#Loading a scene does not bring other players

1 messages · Page 1 of 1 (latest)

stuck bramble
#

So I am just following the load scene docs here

specifically just this section:

  [SerializeField]
  private string m_SceneName;

  public override void OnNetworkSpawn()
  {
      if (IsServer && !string.IsNullOrEmpty(m_SceneName))
      {
          var status = NetworkManager.SceneManager.LoadScene(m_SceneName, LoadSceneMode.Additive);
          if (status != SceneEventProgressStatus.Started)
          {
              Debug.LogWarning($"Failed to load {m_SceneName} " +
                    $"with a {nameof(SceneEventProgressStatus)}: {status}");
          }
      }
  }

And I tried to implement like this:

using UnityEngine;
using Unity.Netcode;

public class NetworkSceneManager : MonoSingleton<NetworkSceneManager>
{
    public void LoadSceneForAllPlayers(string sceneName)
    {
        print($"Loading Scene {sceneName}");

        var status = NetworkManager.Singleton.SceneManager.LoadScene(sceneName, UnityEngine.SceneManagement.LoadSceneMode.Single);

        if (status != SceneEventProgressStatus.Started)
        {
            Debug.LogError($"Failed to load scene {sceneName}: {status}");
            return;
        }
    }
}
    private void StartGame()
    {
        if(!IsHost) return;

        startingGame = true;
        print("Starting");
        
        //Testing with first level
        NetworkSceneManager.Instance.LoadSceneForAllPlayers(GlobalResources.Level1BuildName);
    }

However only the host gets brought into the game when this is run, and it doesnt syncronize the other player with the host and bring them all which is the intended functionality. I have active scene scyncronization enabled on my player prefab, and enable scene management is on on the networkmanager.

#

I also tried

    [Rpc(SendTo.Server)]
    private void StartGameServerRpc()
    {
        startingGame = true;
        print("Starting");
        
        //Testing with first level
        NetworkSceneManager.Instance.LoadSceneForAllPlayers(GlobalResources.Level1BuildName);
    }

since on the docs it says:

As a server:
Any scene you want synchronized with currently connected or late joining clients must be loaded via the NetworkSceneManager

But then it just told me its a SessionOwnerOnlyAction... So i am a little confused if even calling as the server won't load it

#

Any scene loaded via NetworkSceneManager will always default to being synchronized with clients.

#

Something I did find odd is that when the host loads into the loaded scene the other client is there on the hosts screen but not in the right spot or anything so idk what is happening with it, but the client does not get brought in to the game they get stuck in the previous scene

stuck bramble
whole gyro
#

That should work as long as its getting called after the host StartHost()

stuck bramble
#

ok then what the hell is wrong with my project

#

im so lost idk what to even try to fix because it feels so internal

stuck bramble
whole gyro
stuck bramble
#

I am using sessions

#

I just assumed it would set the host as the creator of the session does it not? Trying to find if it does that right now

whole gyro
#

Yea. If you are using Relay then the host is also the session owner

#

If you call Load scene() after you create the session, it should be fine

stuck bramble
#

its odd because the session owner does NOT appear to be the host whenever I print out the IsHost after it gets spawned

stuck bramble
#

print($"Host {IsHost} client {IsClient} server {IsServer}"); prints false true true on the player that creates the session

#

how is that even possible

whole gyro
#

That is odd. Are you using distributed authority by chance?

stuck bramble
#

I am

whole gyro
#

Oh that changes some things.

#

There is no host or server technically when using DA

stuck bramble
#

So how can I load the scene then if it wants to be called by the host

onyx terrace
whole gyro
#

Just have whoever created the session call Load Scene

stuck bramble
#

session owner is true, host is false on my prints

stuck bramble
#

ohh wait

#

hold on i may have an idea

stuck bramble
#

Lol well it still didnt load them both

#
using UnityEngine;
using Unity.Netcode;

public class NetworkSceneManager : NetworkBehaviour
{

    public override void OnNetworkSpawn()
    {
        base.OnNetworkSpawn();

        if (!WidgetSessionManager.Instance.Session.IsHost || !IsOwner) this.enabled = false;
    }
    public void LoadSceneForAllPlayers(string sceneName)
    {
        print($"Loading Scene {sceneName}");

        var status = NetworkManager.Singleton.SceneManager.LoadScene(sceneName, UnityEngine.SceneManagement.LoadSceneMode.Single);

        if (status != SceneEventProgressStatus.Started)
        {
            Debug.Log($"Failed to load scene {GlobalResources.Level1BuildName}: {status}");
            return;
        }
    }
}
#

this is now on the player prefab

#

only loads it for the session owner still, idk what im doing wrong i thought all my settings were set up for this

#

does the client have to load it from the session owners prefab on their end? like that would make no sense though

#

Well i tried that anyways but that didnt do anything either, just triggered the SessionOwnerOnly failure

#

So if only the session owner can load the scene, but when the session owner loads the scene it doesnt bring the other players, what can I even do about this

whole gyro
stuck bramble
#

Well I put the players in a lobby scene first (when they join the session / create it) and then once they are all ready I am trying to put them in the level scene its just a test level but im trying to get them all to at least join it together, loading the level scene is the problem here

#

is that a different scenario than what you just said?

#

like either way I am trying to put all of the players in a different scene

whole gyro
#

You can check for IsSessionOwner before you load the scene as well. Loading the scene as Single should switch scenes

stuck bramble
#

because I swear i have quadruple checked this 15 times and I cannot find anything that is wrong, everything you are saying it is all there

#

IsSessionOwner prints false on the client and true on the host like its supposed to. Session owner loads the scene like its supposed to. but the client does not come with

#

i tried rpc on the server rpc to everyone no rpc at all it just does the same thing every time

whole gyro
#

Right only the session owner can switch scenes. The currently loaded scenes will sync with all connected clients and any that join later. Unless you have scene management disabled

stuck bramble
#

ill look into that i guess

#

I think that is from like the lobby isnt it?

#

for mine the player prefabs are already spawned

#

I just want to move them to a different scene should i be destroying them before or something?

whole gyro
stuck bramble
#

What script should be loading it?

stuck bramble
#

if it should be automatic and its not its gotta be some setting somewhere but i have scene management on and i have active scene synchronization on so what the hell?

#

Like i can see the other client on the host but it isnt actually the other client as on their screen they are still in the lobby scene

#

why does it not actually load it on the clients screen

whole gyro
#

The only other thing that could be wrong would be if the scene is not in the build profile scene list

stuck bramble
#

But like... how would the host load it if it wasnt. and it is

#

im getting unbelievably frustrated with this like i dont even know what to do anymore

#

ive resorted to ai and ofc that is more useless than ever

#

the script is supposed to be on the player right?

whole gyro
stuck bramble
#

is it possible that like the session cancels when it tries to load the scene or something

#

but even that wouldnt make sense because i can see the 2nd players object on the host they just dont load

#

like it clearly is working

#

it just shuts down after the 2nd player isnt in for like 10ish seconds

#

shuts down only host^*

whole gyro
#

If its timing out then that could be a problem. Like if it takes too long for the scene to load, it will time out

stuck bramble
#

The scene does not even begin loading on the 2nd player

#

no logs for it, doesnt even show it loading in the hierarchy

#

it just doesnt get communicated

#

like why

#
    private void StartGame()
    {
        print("Starting");

        //Testing with first level
        NetworkSceneManager sceneManagerPlayer = FindObjectsByType<NetworkSceneManager>(FindObjectsInactive.Include, FindObjectsSortMode.None).FirstOrDefault(x => x.enabled);

        if (sceneManagerPlayer != null)
            sceneManagerPlayer.LoadSceneForAllPlayer(GlobalResources.Level1BuildName);
    }
#

"starting" is the only thing printed on the 2nd player

#
    public void LoadSceneForAllPlayer(string sceneName)
    {
        print($"Loading Scene {sceneName}");

        print(IsSessionOwner + "   " + NetworkManager.LocalClientId);
        print($"SCENE MANAGEMENT {NetworkManager.Singleton.NetworkConfig.EnableSceneManagement}");

        var status = NetworkManager.Singleton.SceneManager.LoadScene(sceneName, UnityEngine.SceneManagement.LoadSceneMode.Single);

        if (status != SceneEventProgressStatus.Started)
        {
            Debug.Log($"Failed to load scene {GlobalResources.Level1BuildName}: {status}");
            return;
        }
    }
#

all my changes and ive got no where

#

I see the host leave on the 2nd players screen too when they load the scene

whole gyro
#

How is your session getting started?

stuck bramble
#

im using the widget

#
print(WidgetSessionManager.Instance.Session.PlayerCount+ " PLAYERS");
print(NetworkManager.Singleton.ConnectedClients.Count + " CLIENTS");

just added these too they both say 2 when the host begins the load

#
using System.Collections;
using TMPro;
using UnityEngine;

namespace Unity.Multiplayer.Widgets
{
    internal class CreateSession : EnterSessionBase
    {
        TMP_InputField m_InputField;
        
        protected override void OnEnable()
        {
            m_InputField = GetComponentInChildren<TMP_InputField>();
            base.OnEnable();
        }

        public override void OnServicesInitialized()
        {
            StartCoroutine(LoadSession());
/*            m_InputField.onEndEdit.AddListener(value =>
            {
                if (Input.GetKeyDown(KeyCode.Return) && !string.IsNullOrEmpty(value))
                {
                }
            });*/
            m_InputField.onValueChanged.AddListener(value =>
            {
                m_EnterSessionButton.interactable = !string.IsNullOrEmpty(value) && Session == null;
            });
        }

        private IEnumerator LoadSession()
        {
            yield return new WaitForSeconds(2f);
            EnterSession();
        }

        protected override EnterSessionData GetSessionData()
        {
            return new EnterSessionData
            {
                SessionAction = SessionAction.Create,
                SessionName = m_InputField.text,
                WidgetConfiguration = WidgetConfiguration,
            };
        }
    }
}
#

heres the create session code

#

all i changed was make it wait 2 seconds and then make the session

#

otherwise unitys code

whole gyro
#

does the same thing happen when you have the widget configuration set to Relay instaed of DA?

stuck bramble
#

Um well when i changed it to that the Session became null

#
using UnityEngine;
using Unity.Multiplayer.Widgets;
using Unity.Services.Multiplayer;
using System.Collections.Generic;
public class WidgetSessionManager : WidgetBehaviour, ISessionProvider
{
    public ISession Session { get; set; }

    public static WidgetSessionManager Instance { get; private set; }

    private void Awake()
    {
        if(Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(this);
        }
        else
        {
            Destroy(this);
        }
    }

    public string GetLocalPlayerName()
    {
        print(Session);

        Session.CurrentPlayer.Properties.TryGetValue(SessionConstants.playerNamePropertyKey, out var name);
        return name.Value;
    }

}

I have this and when I switched to Relay mode the Session is just null now on that print, I call this OnNetworkSpawn of the player

#

this is what you meant right?

whole gyro
#

I wouldn't modify any of the widget code. Its just going to get overwritten since its package code

whole gyro
stuck bramble
#

Well theres no way to customize it besides changing it and its impossible to get it working from scratch

#

plus its not like i updated the package

whole gyro
stuck bramble
#

Yes but I wanted to access the Session outside the widget to get information out of it

#

everything is internal

whole gyro
stuck bramble
#

But I would have to re implement all of the buttons and the voice chat for an interface its way easier to just use the widget

#

spent like 2 days trying to make my own system and i was flooded with trouble so

#

this is easier at least to test for now

#

but now with this scene loading jank I might have to reinvent the wheel again

#

if thats even the issue anyway

stuck bramble
#

Okay so @whole gyro I took your advice and started from scratch, made the session myself, and SOMEHOW it still wont load player 2 in. Same exact everything except now has nothing to do with the widget bs.

I am going to give ALL of the relevant code because I dont know where else to turn, if you could help me out.

SessionManager its on the NetworkManager
GameStarting This one is the countdown and then starts the game when it ends.
NetworkSceneManager sits on the player prefab, and is found in GameStarting to call the load. I made it an RPC to see whats happening on the 2nd client, but of course it doesnt load it because its a session only function.

So there. I load the session myself, both players are in and it STILL will not load them both in. Looks like the widget wasnt even the issue its gotta be some DA malarky... I am still on DA btw, as you can see in the SessionManager file.

Any scene loaded via NetworkSceneManager will always default to being synchronized with clients.

I am using no scene validation.
I am reading about client synchronization and it is saying that ONLY when a client connects to the server it happens. Does that mean that it will not synchronize a scene swap... that would make NO SENSE because then the host is basically just leaving and the client cant even join because they cant load the scene since they arent the session owner.

Any insight? Thanks

#

Only other useful info I found is that once the session owner loads the scene the 2nd player becomes the session owner... Not sure why it doesnt bring him in but instead just promotes them to owner

The session owner puts both player objects in dontdestroyOnLoad and then loads the new scene, but on the clients side nothing happens, scene doesnt even begin loading

whole gyro
#

Have you tried loading up the Asteroids sample I linked the other day. Does the same thing happen in that project?

stuck bramble
#

im currently looking at this file from the scripts of that project for any help at all

stuck bramble
#
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;

/// <summary>
/// This can be added to the same GameObject the NetworkManager component is assigned to in order to prevent
/// multiple NetworkManager instances from being instantiated if the same scene is loaded.
/// </summary>
public class AutoLoadScene : MonoBehaviour
{
    [HideInInspector]
    [SerializeField]
    private string m_SceneToLoad;

#if UNITY_EDITOR
    public SceneAsset SceneToLoad;
    private void OnValidate()
    {
        if (SceneToLoad)
        {
            m_SceneToLoad = SceneToLoad.name;
        }
    }
#endif

    // Start is called before the first frame update
    private void Start()
    {
        SceneManager.LoadSceneAsync(m_SceneToLoad, LoadSceneMode.Single);
    }
}
#

this file is also in there, why are they loading it with the normal SceneManager here?

#

I searched for instances of SceneManager.LoadScene and theres only 1 call with the network manage in that scene loading ui script. Is it meant to only work the first time? Or am I supposed to use UnityEngine.SceneManagement.SceneManager to load the scene for all the clients, and only the session owner uses NetworkManager.SceneManager? Guess I will try that now

stuck bramble
#

I figured out that NetworkSceneManager.OnSynchronize is not even being called so for some reason it does not synchronize the clients why though I don't know yet...

#

umm..... well not sure why i didnt try this sooner, but I just tried going back to the main menu scene from the lobby and THAT worked, but loading the level DOESNT work... this is getting really weird

#

at least I now know its level specific

#

all I did was change the scene name that it is loading and everything works... so what is wrong with my scene that is making it not synchronize clients?

#

it is in build settings 1000%

#

gotta be something in-scene then it HAS to be

#

OK PROGRESS

#

I disabled ALL of the networkobjects in my level scene and it FINALLY Synchronized.

#

what can be wrong with my network objects that causes this?

whole gyro
stuck bramble
whole gyro
#

If the scene is very large, that could be causing issues. Though you would be getting timeout errors if that were the case

stuck bramble
#

the scene takes like 10ish seconds to load

#

but i get no time out messages

#

the one time it did work it started loading the 2nd player after the first was done, but now it doesnt do that, also doesnt time out either :/

#

it has to be the loading time

#

i just duped the level and deleted a bunch of the walls and stuff and then it worked

#

man that is SO ANNOYING

#

how do i even fix this i guess I have to make the level smaller? like idk

whole gyro
stuck bramble
#

I never thought about that that is an interesting concept

stuck bramble
#

and then how would I test the levels then