Problem with facebook SDK, "there are 2 event systems in scene" after initializing facebook FB.Init

Hello, I am having a issue that I don’t know how to deal with, when using the Facebook SDK 14.1.0.

When I call FB.Init() which initialized the SDK package, It moves my EventSystem to “Don’t destroy on load”. When I then load any other scene, there is now two EventSystem objects, one that used to control the canvas events on the scene, and now also the one moved to “Don’t destroy on load” - and unity starts spamming the warning:
There are 2 event systems in the scene. Please ensure there is always exactly one event system in the scene

The same happens when I go back to the main scene, because it is now loaded with the EventSystem that was there originally, plus the one from Don’t destroy on load…

  1. I can’t remove the original one from the main scene, otherwise the user can’t click any buttons to begin with, and I don’t always want to initialize the Facebook SDK, this is an additional optional thing in my game.

  2. I could remove all other event systems from all other scene, but this would be a massive pain, since I can no longer run 1 scene at a time when developing… Not ideal - and this still doesn’t solve the issue that there will again be 2 event systems in the main scene each time that one is loaded.

There has got to be some scripting trick that checks if there is an EventSystem in don’t destroy on load, and if so, then destroy the other event system - when a scene is loaded? Or what would be the right way to handle this?

Thanks!

I don’t think FB.Init should create any event system unless one doesn’t exist in your scene, maybe you have a singleton script on your EventSystem game object that is targeting the entire gameObject and not just the component? Or your original scene didn’t have an event system?

Here’s what FB.Init created for me:
8434019--1117031--upload_2022-9-12_16-47-23.png

You can check the code to see - maybe your version is different
But here’s the fb init code

          switch (Constants.CurrentPlatform)
          {
            case FacebookUnityPlatform.Android:
              FB.OnDLLLoadedDelegate = (FB.OnDLLLoaded) (() => ((AndroidFacebook) FB.facebook).Init(appId, onHideUnity, onInitComplete));
              ComponentFactory.GetComponent<AndroidFacebookLoader>(ComponentFactory.IfNotExist.AddNew);
              ComponentFactory.GetComponent<CodelessCrawler>(ComponentFactory.IfNotExist.AddNew);
              ComponentFactory.GetComponent<CodelessUIInteractEvent>(ComponentFactory.IfNotExist.AddNew);
              break;
            case FacebookUnityPlatform.IOS:
              FB.OnDLLLoadedDelegate = (FB.OnDLLLoaded) (() => ((IOSFacebook) FB.facebook).Init(appId, frictionlessRequests, FacebookSettings.IosURLSuffix, onHideUnity, onInitComplete));
              ComponentFactory.GetComponent<IOSFacebookLoader>(ComponentFactory.IfNotExist.AddNew);
              ComponentFactory.GetComponent<CodelessCrawler>(ComponentFactory.IfNotExist.AddNew);
              ComponentFactory.GetComponent<CodelessUIInteractEvent>(ComponentFactory.IfNotExist.AddNew);
              break;

Which will check your scene during Awake() for CodelessUIInteractEvent:

if ((UnityEngine.Object) UnityEngine.Object.FindObjectOfType<EventSystem>() == (UnityEngine.Object) null)
      {
        GameObject gameObject = new GameObject("EventSystem");
        gameObject.AddComponent<EventSystem>();
        gameObject.AddComponent<StandaloneInputModule>();
        UnityEngine.Object.DontDestroyOnLoad((UnityEngine.Object) gameObject);
      }

Hi, thanks for sharing your code example ! :slight_smile:

Mine is indeed quite different, I am only calling FB.Init() - or, I have cut away everything else because I was trying to locate what call makes the EventSystem “not destroy on load”, and I have concluded that it is the FB.Init(). There might be much variation depending on what SDK version is used, but the documentation doesn’t mention anything about this as far as I can tell.

I have checked my EventSystem object, there is no scripts or anything custom attached to it. It’s the one that came automatically when I created a canvas.

This is what my hierarchy looks like prior to starting the player:

I have create a bare minimum script, that only contains a function that will initialize Facebook and nothing else, and attached that function to a button OnClick event:


When I play the scene, the EventSystem object stays where it is (pic 1), right until the moment I click the button that calls the CallInit() function. Then the EventSystem object is moved out of the main scene hierarchy, and appears instead under the “don’t destroy on load” section (outside the scene scope?)

So, I don’t think that the Facebook SDK is creating a new EventSystem, it’s more like it is making the one that exist global, which I don’t know why - or how to deal with, since I have even systems on other scenes as well.

So ether, there should be a way to tell FB to not make it “don’t destroy on load”, but I can’t find any information on that.
Or, there should be a way for me to do it manually (with scripting moving it back into the scene hierarchy?) - I’m not sure how I target the EventSystem GameObject, and what to call to get it “back in scene” - and I’m not sure if the is advised?
Or, some like…: OnSceneLoad check for duplicate EventSystem and delete one - this sounds to me like the least favourable approach - creating unwanted object and deleting them.
Or, something completely different that I can’t think of.

The code snippets I shared was from the FB SDK - just followed into FB.Init() to see what it was doing.

You should be able to navigate to the FB SDK code and see what it’s doing to when you press the button.

I don’t believe the FB SDK has changed much in regards to the unity code. CodelessUIInteractEvent.cs is where. In the Awake() method of CodelessUIInteractEvent (which is created by FB.Init()) it will look for a game object of type EventSystem - if it can’t find one then it will create one and set it to DontDestroyOnLoad. Try to verify if your version of the SDK does the same

Anyways I think another thing you could try is just creating an empty scene with a simple component that just calls FB.Init() in Awake(). Or try their sample scene, then you can isolate why your scene results in 2 EventSystem

1 Like

Good tip thanks! - Could you point me to the path/directory where you found facebook SDK code? (the file you are referring to) - when I search “CodelessUIInteractEvent.cs” in the assets, I don’t find anything.

Alright, I did as suggested. Created a brand new scene, only added a canvas and a button, then made the button trigger FB.Init() - and I must say I was kind of suspicious that it would not reproduce, and that it would indeed be because I am having some dark magic in my main scene that I have forgot about, but no. It reproduced exactly as in the main scene.

To demonstrate I decided to do a screen recording. Sometimes visuals add valuable input to the brain storming, and I have become very determined to understand what’s going on - and solve it.
Here is the video clip:

I forgot to capture the console, but I believe the output could be valuable… After the button is clicked, and FB.Init() is called, the following logs were printed in the console:

1 Warning:
This example uses Unity Engine OLD input system. If you are using new Input System and you want to use this example, please set your input configuration to BOTH.
UnityEngine.Debug:LogWarning (object)
Facebook.Unity.CodelessUIInteractEvent:Awake ()
UnityEngine.GameObject:AddComponent<Facebook.Unity.CodelessUIInteractEvent> ()
Facebook.Unity.ComponentFactory:GetComponent<Facebook.Unity.CodelessUIInteractEvent> (Facebook.Unity.ComponentFactory/IfNotExist)
Facebook.Unity.FB:Init (string,string,bool,bool,bool,bool,bool,string,string,Facebook.Unity.HideUnityDelegate,Facebook.Unity.InitDelegate)
Facebook.Unity.FB:Init (Facebook.Unity.InitDelegate,Facebook.Unity.HideUnityDelegate,string)
FacebookTest:CallInit () (at Assets/Scripts/FacebookTest.cs:8)
UnityEngine.EventSystems.EventSystem:Update () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:501)

2 Warning:
You are using the facebook SDK in the Unity Editor. Behavior may not be the same as when used on iOS, Android, or Web.
UnityEngine.Debug:LogWarning (object)
Facebook.Unity.FacebookLogger/DebugLogger:Warn (string)
Facebook.Unity.FacebookLogger:Warn (string)
Facebook.Unity.Editor.EditorFacebook:Init (Facebook.Unity.InitDelegate)
Facebook.Unity.FB/<>c__DisplayClass36_0:b__1 ()
Facebook.Unity.FB/CompiledFacebookLoader:Start ()

3 Info:
Using Facebook Unity SDK v14.1.0 with FBUnityEditorSDK/14.1.0
UnityEngine.Debug:Log (object)
Facebook.Unity.FacebookLogger/DebugLogger:Info (string)
Facebook.Unity.FacebookLogger:Info (string)
Facebook.Unity.FB:LogVersion ()
Facebook.Unity.FB/CompiledFacebookLoader:Start ()

You can view the source by ‘ctrl’ + click the method name in your IDE.

So if you ctrl + click the Init() part of FB.Init() it should bring you to it.

If that doesn’t work, you can also view the source on their github. I see you are on v14 so I took a look at their changes and looks like they updated it here to make the EventSystem always DoNotDestroy

Looks like they made a change to fix conflicts with the new/old input system.

There is an open issue still though for the EventSystem:Facebook SDK incompatible with new Input System · Issue #442 · facebook/facebook-sdk-for-unity · GitHub
Don’t have enough time to investigate whether it’s still broken or not

You are only using the old input system right? If so I would just use an older version of the FB SDK

13.2. shouldn’t have the updated code for EventSystem

1 Like

I’m having the same issue due to updating my Facebook SDK to v14.1.0 (was previously on v11.0). I wrote a script that will auto search when a new scene is loaded and destroy any EventSystem’s that aren’t under DontDestroyOnLoad. Hopefully this helps you too if you hadn’t found a fix yet.

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;

public class SingleEventSystem : MonoBehaviour {
        private static SingleEventSystem instance;
      
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        private static void Init() {
            instance = new GameObject().AddComponent<SingleEventSystem>();
            instance.hideFlags = HideFlags.HideAndDontSave;
            DontDestroyOnLoad(instance.gameObject);
        }

        private void OnEnable() {
            SceneManager.sceneLoaded += HandleSceneLoaded;
        }

        private void OnDisable() {
            SceneManager.sceneLoaded -= HandleSceneLoaded;
        }

        private static void HandleSceneLoaded(Scene arg0, LoadSceneMode arg1) {
            var eventSystems = FindObjectsOfType<EventSystem>();
            if (eventSystems.Length == 1)
                return;

            foreach (var eventSystem in eventSystems) {
                if (!IsDontDestroyOnLoadActivated(eventSystem))
                    Destroy(eventSystem.gameObject);
            }
        }

        private static bool IsDontDestroyOnLoadActivated(Component eventSystem) {
            return eventSystem.gameObject.scene.name == "DontDestroyOnLoad";
        }
    }
1 Like

Also, I’m using Unity 2021.3. But if you are on an older version of Unity, my IsDontDestroyOnLoadActivated() method might not work. So here are some other options to check if the eventSystem has DontDestroyOnLoad if mine doesn’t work. A way to check if an object has DontDestroyOnLoad activated - Questions & Answers - Unity Discussions

1 Like

Thank you so much! This is very helpful - highly appreciated

1 Like

Another approach is to add the following inside the OnInitComplete delegate:

FB.Init(delegate
{
    var eventSystems = FindObjectsOfType<EventSystem>();
    foreach (var eventSystem in eventSystems)
    {
        var tmp = new GameObject();
        eventSystem.gameObject.transform.parent = tmp.transform;
     }
} , delegate(bool shown) { });
2 Likes

FWIW, I submitted this as a bug to Facebook, as I couldn’t find it submitted there yet and it is still not fixed. When they tried to fix the new vs old input system, they broke this. Always a good idea to submit using their official Bug reporting system when possible. See the bug report here: Log into Facebook

2 Likes

Seems like they have fixed it in the following commit:

https://github.com/facebook/facebook-sdk-for-unity/commit/580b13eff838b08820ba45fd64129bf02c1d30b8

1 Like

The bug report now says they will have the fix in the next release, so we will have to see when that is and if it is actually fixed correctly and nothing else is broken. If you haven’t notice, I’m not holding my breath, but at least there is a decent chance they get this fixed this time around.

Just to close the loop on this issue. Facebook has released the updated and apparently fixed SDK as version 15.1.0 - Releases · facebook/facebook-sdk-for-unity · GitHub

1 Like

Try closing Unity and opening again like the good old days.
After Adding Facebook SDK, I got this warning, I checked the code, everything was ok. After 15-20 minutes I needed to close the unity and reopen. And the warning is gone.
Somehow FindObjectOfType(); couldn’t find the old EventSystem object.