Hello
I am working on PvP for a 2D game.
All things are working on Unity Editor which means that 2 spawned network objects in Host are also spawned in Client.
But it is not working in APK build in Android Device.
I attached some code block and video.
So, the object is spawned in Host and it is reflected in Client when I play it on Unity Editor
But it is not working well in android build in Android Device.
What i mean : the object is only spawned in Host , it is not reflected in client in Android Device.
I will attach 2 videos to show them.(Left is Host, Right is Client in videos)
Further observations from me, a team member of OP:
First of all, it seems that the problem is not just with object instantiation but rather with the network synchronization on Android builds specifically. When running the game in the Unity Editor, network communication works flawlessly: objects are spawned on both the Host and Client sides and can interact with each other without any hiccups.
Observations:
Client-Host Communication: During my debugging, I found out that the ClientNetworkId is received correctly by the Host but is not reflected on the Client side when running on an Android device.
Logcat: I went through the Android Logcat and found no specific errors related to networking or object instantiation, which makes this all the more puzzling.
Debugging: Further debug logs indicated that the CreateCruiser function is being called and executed without any errors on the Android build; however, the spawned object simply does not appear on the Client side.
Network Permissions: I double-checked my AndroidManifest.xml, and all the required permissions for networking are set.
Additional Clues:
I tried bypassing the SpawnWithOwnership(ClientNetworkId) function and instead used a basic Spawn() function for testing. The object was spawned on both the Host and Client when running on an Android device, but obviously, I couldn’t control it properly due to lack of ownership.
This leads me to believe that the issue might be tied to the ownership settings or the SpawnWithOwnership() function specifically when running on Android.
I hope these additional observations help us zero in on the actual issue. If anyone else has encountered this problem and found a solution, your insights would be greatly appreciated.
Hello,
I have the same issue and I think that SpawnWithOwnership doesn’t work at all for clients, since several versions of Unity.
I tried with a windows build and in the editor. The object just doesn’t appear, while a simple Spawn works fine.
The code seems fairly straightforward, instantiating a PvPBuildableWrapper object and setting it up for network synchronization with SpawnWithOwnership(clientID). However, the fact that the issue only appears on Android and not within the Unity Editor suggests that there may be a platform-specific issue or behavior that’s causing the problem.
Here are a few things you might want to consider checking:
Type Generics: Unity sometimes behaves differently with generic types on different platforms. Although not very likely, you might want to try using a non-generic version for testing purposes.
Object Activation: buildableWrapper.gameObject.SetActive(true); is called after SpawnWithOwnership. Sometimes, the order of operations matters. Consider setting it active before spawning with ownership to see if that has any effect.
Network Initialization: Ensure that the NetworkObject component is fully initialized before calling SpawnWithOwnership(clientID). Initialization delays could lead to unexpected behavior.
Logs and Debugging: Add more logging around the SpawnWithOwnership(clientID) call to ensure that clientID is what you expect and that the function is being called when and where you expect it.
Unity Version: Sometimes, these types of issues are Unity version-dependent. Make sure that you and your client are using versions of Unity and NGO that are known to be compatible.
Build Settings: Double-check if there are any build settings that might be affecting the Android build differently from the Editor build.
Here’s a slightly modified version of the function, with added logging for debugging purposes:
private TBuildable CreateBuildingBuildable<TBuildable>(
PvPBuildableWrapper<TBuildable> buildableWrapperPrefab,
IPvPFactoryProvider factoryProvider,
ulong clientID) where TBuildable : class, IPvPBuilding
{
PvPHelper.AssertIsNotNull(buildableWrapperPrefab, factoryProvider);
// Debug log to check values
Debug.Log($"ClientID: {clientID}");
PvPBuildableWrapper<TBuildable> buildableWrapper = Object.Instantiate(buildableWrapperPrefab);
buildableWrapper.gameObject.SetActive(true); // Setting active before spawn
// More debug logging
Debug.Log("About to spawn with ownership...");
buildableWrapper.GetComponent<NetworkObject>().SpawnWithOwnership(clientID);
// Debug log to confirm spawn
Debug.Log("Spawned with ownership");
buildableWrapper.GetComponent<NetworkObject>().DontDestroyWithOwner = false;
buildableWrapper.StaticInitialise(_commonStrings);
buildableWrapper.Buildable.Initialise(factoryProvider);
return buildableWrapper.Buildable;
}
Please try these and let me know if they resolve your issue or provide any additional context as to what the issue may be.
Deferred Message (SpawnTimeout) Period:
With Android and/or any platform that could take a bit longer to load assets, you could be running into an issue with messages being received but not processed for a “yet to be instantiated/spawned” object. The default setting for deferred messages (i.e. messages received for a NetworkObject->NetworkBehaviour yet to be spawned/instantiated) is 1 second…if the associated NetworkObject (or NetworkBehaviour component) does not exist within that period of time then the message gets dropped.
You might try increasing the NetworkManager.NetworkConfig.SpawnTimeout value to like say 10 seconds (or some value you think is reasonable) and see if that helps.
Some other pointers:
When things seem to not work on mobile devices (especially Android), as a “sanity” check you might make a build with the “Project Settings->Player->Other Settings->Optimization->Managed Stripping Level” set to minimal to just make sure some critical method or the like is not being stripped away by accident (if you run into this issue you will want to read about preserving code using annotations)
Disabled NetworkBehaviours will not be considered “associated” with a NetworkObject if they are disabled when the NetworkObject is spawned (you can disable them after the NetworkObject is spawned as the NetworkObject will have already registered it…RPCs will still get invoked and NetworkVariables will still be updated if a NetworkBehaviour is disabled post-spawn).