Search Unity

Facebook Instant

Discussion in 'Project Tiny' started by phil-harvey, Dec 5, 2018.

  1. phil-harvey

    phil-harvey

    Joined:
    Aug 27, 2014
    Posts:
    60
    What would the procedure be to export for Facebook Instant. Would a module with FB code need to be created?
     
  2. MBest_Unity

    MBest_Unity

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    21
    There is nothing stopping you from making this work today. However, there are things we can to do make the process easier down the line. You can checkout this handy Messenger links on what you need from their end to help you get started down that path.
     
  3. dimitroff

    dimitroff

    Joined:
    Apr 3, 2013
    Posts:
    103
    Yeah, I am really curious how to handle this too? Especially, when Tiny switch to C# code.
     
    castana1962 likes this.
  4. phil-harvey

    phil-harvey

    Joined:
    Aug 27, 2014
    Posts:
    60
    I know the Instant SDK, I was wondering how I go about calling the external js lib from with in code, so that you can test in the debugger etc, as well as when the move to C# is made, how do you call into an external js file which is included.

    Take something else like Moment.js or another library.
     
  5. etienne_unity

    etienne_unity

    Unity Technologies

    Joined:
    Aug 31, 2017
    Posts:
    54
    castana1962 likes this.
  6. dwiperidream

    dwiperidream

    Joined:
    Nov 12, 2015
    Posts:
    7
    I'll add in here as I was able to figure out how to get FB Instant working along with getting JS or TypeScript libraries loaded as well with @etienne_unity 's help in the other thread.

    For FB Instant, you have to make sure you add in their CDN hosted fbinstant SDK, and for FB Instant you can't use a debug or development build as it will look for a "tsc-emit.js" in the script imports on the index page and the FB Instant hosting is sandboxed. So, build a release version, and then add
    Code (JavaScript):
    1. <script src="https://connect.facebook.net/en_US/fbinstant.6.2.js"></script>
    Into the html page, I put it in right before the closing body tag. The other way, would be to add in a post processing script made in CSharp - I have this in the root of the Assets folder, one folder up from the Tiny project. Here's what I wrote up to automatically do that (plus include the fbapp-config.json with the package):


    Code (CSharp):
    1. using System.IO;
    2.  
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6. using Unity.Tiny;
    7. using UnityEditor;
    8.  
    9. public class FBInstantPostProcessing
    10. {
    11.     [TinyPostprocessBuildAttribute(1)]
    12.     static void PostProcessFBInstant(TinyBuildOptions opts, TinyBuildResults results)
    13.     {
    14.         DirectoryInfo finalBuildFolder = results.BinaryFolder;
    15.         bool buildResult = results.Success;
    16.  
    17.         if (buildResult)
    18.         {
    19.             // Only enable FB instant if it's a release version
    20.             if(opts.Configuration == TinyBuildConfiguration.Release){
    21.                 CopyFBAppJson(finalBuildFolder);
    22.                 AddFBLibsToHTML(finalBuildFolder);
    23.             }
    24.  
    25.         }
    26.     }
    27.  
    28.     static void CopyFBAppJson(DirectoryInfo destination)
    29.     {
    30.         FileUtil.CopyFileOrDirectory("Assets/fbapp-config.json", destination + "/fbapp-config.json");
    31.     }
    32.  
    33.     static void AddFBLibsToHTML(DirectoryInfo destination)
    34.     {
    35.         string indexHtmlPath = destination + "/index.html";
    36.         // Ok, open the HTML and read it, then sub in our fbinstant stuff.
    37.         string toInsert = "<script src=\"https://connect.facebook.net/en_US/fbinstant.6.2.js\"></script>";
    38.         var endTag = "</body>";
    39.         var newTag = toInsert + endTag;
    40.         var fileText = File.ReadAllText(indexHtmlPath);
    41.         fileText = fileText.Replace(endTag, newTag);
    42.         // write the file back out
    43.         using (FileStream fs = new FileStream(indexHtmlPath, FileMode.Open, FileAccess.Write))
    44.         using (StreamWriter sw = new StreamWriter(fs))
    45.         {
    46.             sw.Write(fileText);
    47.         }
    48.     }
    49. }

    With regards to including other libs, following the instructions in the other thread worked perfect, except you can also include custom Typescript in your "include" section, as well as including extra d.ts files in a files section. I used that to include a FBInstant.d.ts file so I'd have typings to use for it too. So my tsconfig.override.json looks like this:


    Code (JavaScript):
    1. {
    2.     "compilerOptions": {
    3.         "allowJs": true
    4.     },
    5.     "include": [
    6.         "External/SomeJsLib/**/*.js",
    7.         "External/SomeJsLib/**/*.ts",
    8.     ],
    9.     "files": [
    10.         "External/dst/FBInstant.d.ts"
    11.     ]
    12.  
    13. }
     
    castana1962 and BitMatrix like this.
  7. etienne_unity

    etienne_unity

    Unity Technologies

    Joined:
    Aug 31, 2017
    Posts:
    54
  8. tiagokeller

    tiagokeller

    Joined:
    Dec 11, 2018
    Posts:
    3
    @etienne_unity Editing the index.html for CDN hosted libraries every build time do not seem practical. Any plans on having an HTML template or especial property configuration to point out for external hosted libs? I took a quick look at TinyHTML5Builder.cs, but I could find a proper way to have a workaround for it. This will be important for loading external libs for metrics, facebook, google, etc...
     
  9. TheRoccoB

    TheRoccoB

    Joined:
    Jun 29, 2017
    Posts:
    54
    tiagokeller likes this.
  10. dwiperidream

    dwiperidream

    Joined:
    Nov 12, 2015
    Posts:
    7
    @tiagokeller - Not sure if this is what you're asking about, but if you modify the post build script I had posted earlier you can insert whatever you want into the index.html file. That should run after every release build without any extra user interaction as long as it's the root of the Assets folder and the main method has that attribute attached. You could modify it to build a fully custom index.html if you wanted or post copy any extra files into the release folder. For our reasons, it was FB's instant SDK plus analytics libs we'd put in there. You could also generate a custom index.html for a dev build vs a release build (so, enabling verbose analytics for dev during testing, for example).
     
    tiagokeller likes this.
  11. tiagokeller

    tiagokeller

    Joined:
    Dec 11, 2018
    Posts:
    3
  12. simone9725

    simone9725

    Joined:
    Jul 19, 2014
    Posts:
    234
    I have a question I'm building a game in C#.When I load the game for instant game the facebook splash screen overlays the game. I know that there is something that must be change in unity loader.How can I say that loading is ok and the game can start?Thanks
     
  13. Stijn_cts

    Stijn_cts

    Joined:
    Nov 14, 2016
    Posts:
    4
    Hi, I'm really enjoying project Tiny so far and see a lot of new opportunities! However, I'm not very familiar with typescript development and I can't seem to figure out how I can use included external .js libraries from my typescripts withing my project.

    For example, I included an external javascript file which has a function 'doSomething()', how would I call that function from my Tiny project?

    Thanks in advance!
     
  14. Stijn_cts

    Stijn_cts

    Joined:
    Nov 14, 2016
    Posts:
    4
    So I've figured it out by now. For anyone else who has this issue; apparently all you have to do, after adding the needed .js files to the external folder and adding them to the tsconfig.override.json file, let Unity recompile, close and reopen the code editor so it refreshes and then you can use any function you put inside the external folder as if it was part of the project..
    Easy as that.

    Happy hollidays!
     
    IJhunter likes this.
  15. tomny

    tomny

    Joined:
    Sep 12, 2015
    Posts:
    16
    I'm getting an error for the new 14.1 update using this.

    Code (CSharp):
    1. Assets\FBInstantPostProcessing.cs(12,61): error CS0246: The type or namespace name 'TinyBuildResults' could not be found (are you missing a using directive or an assembly reference?)
    2.  
     
  16. frankprogrammer

    frankprogrammer

    Joined:
    Apr 27, 2009
    Posts:
    17
    Here is @dwiperidream's code updated for 0.14.1

    Code (CSharp):
    1. using System.IO;
    2.  
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6. using Unity.Tiny;
    7. using UnityEditor;
    8.  
    9. public class FBInstantPostProcessing
    10. {
    11.     [TinyPostprocessBuildAttribute(1)]
    12.     static void PostProcessFBInstant(TinyBuildOptions opts, TinyBuildResult result)
    13.     {
    14.         string finalBuildFolder = result.BuildFolder;
    15.         bool buildResult = result.Success;
    16.  
    17.         if (buildResult)
    18.         {
    19.             // Only enable FB instant if it's a release version
    20.             if (opts.Configuration == TinyBuildConfiguration.Release)
    21.             {
    22.                 CopyFBAppJson(finalBuildFolder);
    23.                 AddFBLibsToHTML(finalBuildFolder);
    24.             }
    25.  
    26.         }
    27.     }
    28.  
    29.     static void CopyFBAppJson(string destination)
    30.     {
    31.         FileUtil.CopyFileOrDirectory("Assets/fbapp-config.json", destination + "/fbapp-config.json");
    32.     }
    33.  
    34.     static void AddFBLibsToHTML(string destination)
    35.     {
    36.         string indexHtmlPath = destination + "/index.html";
    37.         // Ok, open the HTML and read it, then sub in our fbinstant stuff.
    38.         string toInsert = "<script src=\"https://connect.facebook.net/en_US/fbinstant.6.2.js\"></script>";
    39.         var endTag = "</body>";
    40.         var newTag = toInsert + endTag;
    41.         var fileText = File.ReadAllText(indexHtmlPath);
    42.         fileText = fileText.Replace(endTag, newTag);
    43.         // write the file back out
    44.         using (FileStream fs = new FileStream(indexHtmlPath, FileMode.Open, FileAccess.Write))
    45.         using (StreamWriter sw = new StreamWriter(fs))
    46.         {
    47.             sw.Write(fileText);
    48.         }
    49.     }
    50. }
    51.  
     
    tomny likes this.
  17. Revolter

    Revolter

    Joined:
    Mar 15, 2014
    Posts:
    98
    Can you share an example of how you use FBInstant in your code?
     
  18. dwiperidream

    dwiperidream

    Joined:
    Nov 12, 2015
    Posts:
    7
    I've actually stopped with the Tiny project for now as it's not quite as stable as we need it to be for production in our studio, plus I'm kind of waiting on the C# support instead since that seems to be the direction the Tiny project will be heading. With regards to how we use FB Instant in this particular case, along with @frankprogrammer 's update to my code snippet, we include the FBInstant.d.ts file to avoid TypeScript errors, but as long as the FB Instant SDK is imported, you can just call it directly. For our internal testing, we did up a wrapper service to initialize it all. I've included the service below and how we'd call it from a behaviour:

    // FBInstantService.ts
    Code (CSharp):
    1.  
    2. namespace game {
    3.  
    4.     export class FBInstantService {
    5.  
    6.         protected static Instance: FBInstantService = null;
    7.         protected hasInstant: boolean = false;
    8.  
    9.         public static getInstance(): FBInstantService {
    10.             if (FBInstantService.Instance === null) {
    11.                 FBInstantService.Instance = new FBInstantService();
    12.             }
    13.             return FBInstantService.Instance;
    14.         }
    15.  
    16.         public async initialize() {
    17.             try {          
    18.                 FBInstant; // this will error out if it's not available
    19.                 this.hasInstant = true;
    20.                 // let's do our async and goto main menu.
    21.                 await FBInstant.initializeAsync();
    22.                 FBInstant.setLoadingProgress(100);
    23.                 console.log("Starting game async...");
    24.                 return await FBInstant.startGameAsync();
    25.             } catch (e) {
    26.                 // We don't have this, so let's  just goto the main menu state
    27.                 this.hasInstant = false;
    28.                 return;
    29.             }
    30.         }
    31.  
    32.         public get isAvailable(): boolean {
    33.             return this.hasInstant;
    34.         }
    35.     }
    36.  
    37.  
    38.     export enum ContextFilter {
    39.         NEW_CONTEXT_ONLY = "NEW_CONTEXT_ONLY",
    40.         INCLUDE_EXISTING_CHALLENGES = "INCLUDE_EXISTING_CHALLENGES",
    41.         NEW_PLAYERS_ONLY = "NEW_PLAYERS_ONLY",
    42.     }
    43. }
    44.  
    // ProcessFBLoadBehaviour.ts
    Code (CSharp):
    1.  
    2. namespace game {
    3.  
    4.     export class ProcessFBLoadBehaviourFilter extends ut.EntityFilter {
    5.         fbload: game.InitializeFBInstantComponent;
    6.     }
    7.  
    8.     export class ProcessFBLoadBehaviour extends ut.ComponentBehaviour {
    9.  
    10.         data: ProcessFBLoadBehaviourFilter;
    11.  
    12.         // ComponentBehaviour lifecycle events
    13.         // uncomment any method you need
    14.  
    15.         // this method is called for each entity matching the ProcessFBLoadBehaviourFilter signature, once when enabled
    16.         OnEntityEnable(): void {
    17.             console.log("Initting fb loading.");
    18.             // ok, gonna do up our fb instant stuff...
    19.             FBInstantService.getInstance().initialize().then(()=>{
    20.                 console.log("Loading into main menu");
    21.                 LoadGameStateService.setGameState(this.world, GameStateEnum.MAINMENU);        
    22.             });
    23.          
    24.         }
    25.  
    26.     }
    27. }
    28.  
    This was running on an older version of the Tiny project so I'm not sure if it'd still work, but that was the general flow. You really would not need the service to wrap it in and could simply call the FBInstant library directly, as long as the SDK was imported on the main HTML page. Hope this helps!
     
  19. Revolter

    Revolter

    Joined:
    Mar 15, 2014
    Posts:
    98
    Thanks for the awesome examples!

    I think I'm still missing something, the code doesn't compile for me.

    Do I need to import the FBInstant module?

    Here's my override, I have the fbinstant.6.2.js inside the External/FBInstant folder and the FBInstant.d.ts that I found online in the External/dst/ folder
    Code (JavaScript):
    1. {
    2.     "compilerOptions": {
    3.         "allowJs": true
    4.     },
    5.     "include": [
    6.         "External/FBInstant/**/*.js",
    7.         "External/FBInstant/**/*.ts",
    8.     ],
    9.     "files": [
    10.         "External/dst/FBInstant.d.ts"
    11.     ]
    12. }

    Edit: Never mind, it finally worked using this d.ts file: https://github.com/egret-labs/egret-core/blob/master/build/egret-facebook/fbinstant.d.ts
    Hurray! I think I can manage by myself from here on

    Edit2: You don't need to add the fbinstant.6.2.js file in the External folder -> the release won't build then
     
    Last edited: Feb 19, 2019
    dwiperidream likes this.
  20. kohl-schrelbe

    kohl-schrelbe

    Joined:
    Apr 12, 2019
    Posts:
    1
    Hello guys
    just i'd like to say i want facebook instant games builder
    thank you for understanding
     
  21. sniffle63

    sniffle63

    Joined:
    Aug 31, 2013
    Posts:
    155
    Hello!
    So first add
    Code (JavaScript):
    1. <script src="https://connect.facebook.net/en_US/fbinstant.6.2.js"></script>
    using the PostProcessing script in this topic above

    and then add this as a tsconfig.override

    Code (CSharp):
    1.  
    2.  
    3. {
    4. "compilerOptions": {
    5. "allowJs": true
    6. },
    7. "files": [
    8. "External/dst/FBInstant.d.ts"
    9. ]
    10. }
    11.  
    then i add in the FBInstantService.ts file mentioned a few comments above and then used the

    Code (JavaScript):
    1. FBInstantService.getInstance().initialize().then(()=>{
    2.                 console.log("Loading into main menu");
    3.                 LoadGameStateService.setGameState(this.world, GameStateEnum.MAINMENU);
    4.             });
    to initialize your game into a play state
    Code (CSharp):
    1. FBInstantService
    if you try to use something like
    Code (CSharp):
    1. FBInstant.player.getID();
    it returns an error like this if your game isnt hosted on facebook




    Also add a fbapp-config.json file in your assets folder
    Code (CSharp):
    1.  
    2. {
    3.     "instant_games": {
    4.         "orientation": "PORTRAIT",
    5.         "override_web_orientation": "LANDSCAPE",
    6.         "navigation_menu_version": "NAV_FLOATING",
    7.         "match_player_config": {
    8.             "min_context_size": 2,
    9.             "max_context_size": 20
    10.         }
    11.     }
    12. }
    13. }



    I do have one more question for @dwiperidream tho, what did you add the ContextFilter for in FBInstantService.ts?




    *Edit*Changed from a question to an explanation
     
    Last edited: Apr 27, 2019
  22. sniffle63

    sniffle63

    Joined:
    Aug 31, 2013
    Posts:
    155
    Wanted to post this here sense it what the topic is about
     
  23. dwiperidream

    dwiperidream

    Joined:
    Nov 12, 2015
    Posts:
    7
    From what I can recall, it's defining an enum for the types of contexts you could start with Facebook Instant via their shareAsync or createAsync. I probably should've clipped that out for clarity, it's not needed for this.
     
    sniffle63 likes this.
  24. sniffle63

    sniffle63

    Joined:
    Aug 31, 2013
    Posts:
    155
    Yep figured that out while reading threw the SDK. Thanks alot!