Skip to content

Unable to parent NetworkObject to a NetworkObject only on client #3100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Conundroy opened this issue Oct 15, 2024 · 13 comments
Closed

Unable to parent NetworkObject to a NetworkObject only on client #3100

Conundroy opened this issue Oct 15, 2024 · 13 comments
Assignees
Labels
priority:high This issue has high priority and we are focusing to resolve it stat:imported Status - Issue is tracked internally at Unity type:bug Bug Report

Comments

@Conundroy
Copy link

Conundroy commented Oct 15, 2024

Description

Unable to parent NetworkObject to a NetworkObject only on client.

Reproduce Steps

  1. Host spawns NetworkObject (DestroyedWithScene = true) and parent it via script.

Actual Outcome

Host:

  • Scene
    • Parent NetworkObject
      • Child NetworkObject

Client:

  • Scene
    • Parent NetworkObject
    • Child NetworkObject

Expected Outcome

Host:

  • Scene
    • Parent NetworkObject
      • Child NetworkObject

Client:

  • Scene
    • Parent NetworkObject
      • Child NetworkObject

Environment

  • OS: Windows
  • Unity Version: 6000.0.22f1
  • Netcode Version: 2.0.0

Additional Context

Works if I spawn and parent in editor, probably has something to do with DesroyedWithScene set to true?

Update: Works when I downgrade to v1.11.0

@Conundroy Conundroy added stat:awaiting-triage Status - Awaiting triage from the Netcode team. type:bug Bug Report labels Oct 15, 2024
@Conundroy Conundroy changed the title Unable to parent NetworkObject to a NetworkObject Unable to parent NetworkObject to a NetworkObject only on client Oct 15, 2024
@NoelStephensUnity
Copy link
Collaborator

@Conundroy
If you could post the associated script it would help me provide better guidance on this issue.
Make sure you have spawned both NetworkObject instances before you attempt to parent them. Otherwise, if you are parenting them prior to spawning then that will not synchronize properly.

Order of Operations:

  • Instantiate and spawn parent
  • Instantiate and spawn child
    • Get the NetworkObject of the child.
    • Invoke NetworkObject.TrySetParent

Let me know if this resolves your issue or if not then if you could provide me with a replication project or the script that you are using to instantiate, spawn, and parent the two objects it would be helpful.

@NoelStephensUnity NoelStephensUnity added the stat:awaiting-response Awaiting response from author. This label should be added manually. label Oct 18, 2024
@Fobri
Copy link

Fobri commented Oct 20, 2024

I have the same issue, it started appearing when I upgraded from 1.8 to 2.0.
The scenario I have is very simple, a networkbehaviour instantiates and spawns an instance of a networkobject, and then parents it under itself called in OnNetworkSpawn.
Simplified pseudocode of what I'm doing below.

override void OnNetworkSpawn()
{
   var instance = Instantiate(prefab);
   instance.GetComponent<NetworkObject>().Spawn();
   instance.transform.parent = transform;
}

The object gets correctly parented on server and also late joining clients, but for clients currently in the game the parenting never happens.

@Conundroy
Copy link
Author

@NoelStephensUnity

Here's the script on the parent object/game manager:

public override void OnNetworkSpawn()
{
    if (IsHost) GenerateItems();
    base.OnNetworkSpawn();
{

void GenerateItems()
{
    Mesh mesh = Map.Instance.GetComponentInChildren<MeshFilter>().sharedMesh;
    Bounds bounds = mesh.bounds;

    // Spawn coins
    for (int i = 0; i < numCoins; i++)
    {
        TrySpawnObject(coin, mesh);
    }
}

void TrySpawnObject(GameObject objectPrefab, Mesh mesh)
{
    int randomTriangle = Random.Range(0, mesh.triangles.Length / 3) * 3;  // Choose a random triangle

    Vector3 v0 = mesh.vertices[mesh.triangles[randomTriangle]];
    Vector3 v1 = mesh.vertices[mesh.triangles[randomTriangle + 1]];
    Vector3 v2 = mesh.vertices[mesh.triangles[randomTriangle + 2]];

    // Compute the center of the triangle (polygon face)
    Vector3 center = (v0 + v1 + v2) / 3f;

    // Get the normal of the triangle
    Vector3 normal = Vector3.Cross(v1 - v0, v2 - v0).normalized;

    // Apply random offset in the x and z directions within the range (-3, 3)
    Vector3 randomOffset = new Vector3(
        Random.Range(-3, 3),
        0f, // No offset in the Y direction
        Random.Range(-3, 3)
    );

    Vector3 spawnPosition = center + randomOffset;


    // Directly instantiate at the calculated position
    GameObject newItem = Instantiate(objectPrefab, spawnPosition, Quaternion.identity);
    newItem.GetComponent<NetworkObject>().Spawn(true);
    newItem.GetComponent<NetworkObject>().TrySetParent(transform);
}

This works as intended in v1.11.0.

@NoelStephensUnity
Copy link
Collaborator

NoelStephensUnity commented Oct 24, 2024

Hmmm...generally speaking...instantiating and spawning in the middle of spawning is not recommended as it can lead to issues down the road.

Just out of curiosity, have you tried changing the OnNetworkSpawn to OnNetworkPostSpawn?
This would assure all components had finished running through their spawn process prior to spawning more things and parenting them under the NetworkObject that just finished spawning. There are some updates in v2.0.0 that leverage from NetworkPreSpawn and NetworkPostSpawn ordering which could have impacted spawing in the middle of spawning.

@Fobri
Copy link

Fobri commented Oct 25, 2024

This is the first time I'm hearing that its not recommended to spawn things inside OnNetworkSpawn. How are you supposed to spawn things on server when it initializes then?
My entire server logic gets kicked off in a OnNetworkSpawn that loads a map from disk, and populates it by instantiating and spawning objects. So far I haven't had any issue with that. Perhaps because it's an in-scene placed object?

I did also try OnNetworkPostSpawn for this specific issue, and it didn't change anything.

@NoelStephensUnity NoelStephensUnity added the stat:Investigating Issue is currently being investigated label Oct 28, 2024
@NoelStephensUnity
Copy link
Collaborator

@Fobri
I will take a look to see if there is a bug here, but the issue isn't that you can't spawn things during OnNetworkSpawn or OnNetworkPostSpawn but that if during spawning something you spawn another NetworkObject that will be parented under the NetworkObject currently being spawned.
However, I will investigate this issue further to see if I can replicate it on my end too and if there was a recent update that is the cause of this issue.
👍

@NoelStephensUnity NoelStephensUnity removed the stat:awaiting-response Awaiting response from author. This label should be added manually. label Dec 16, 2024
@michalChrobot michalChrobot added stat:awaiting-response Awaiting response from author. This label should be added manually. and removed stat:awaiting-response Awaiting response from author. This label should be added manually. stat:Investigating Issue is currently being investigated labels Jan 17, 2025
@michalChrobot michalChrobot added stat:Investigating Issue is currently being investigated and removed stat:awaiting-triage Status - Awaiting triage from the Netcode team. labels Jan 21, 2025
@NoelStephensUnity
Copy link
Collaborator

I have the same issue, it started appearing when I upgraded from 1.8 to 2.0. The scenario I have is very simple, a networkbehaviour instantiates and spawns an instance of a networkobject, and then parents it under itself called in OnNetworkSpawn. Simplified pseudocode of what I'm doing below.

override void OnNetworkSpawn()
{
   var instance = Instantiate(prefab);
   instance.GetComponent<NetworkObject>().Spawn();
   instance.transform.parent = transform;
}

The object gets correctly parented on server and also late joining clients, but for clients currently in the game the parenting never happens.

Have you tried setting the transform on a NetworkBehaviour (OtherNetworkBehaviour below) of the instantiated prefab and parenting it within the OnNetworkPostSpawn of the NetworkBehaviour on the newly instantiated prefab?

override void OnNetworkSpawn()
{
   var instance = Instantiate(prefab);
   instance.GetComponent<OtherNetworkBehaviour>.SetTargetParent(transform);
   instance.GetComponent<NetworkObject>().Spawn();
}

And then on OtherNetworkBehaviour:

    private Transform m_TargetParent;

    public void SetTargetParent(Transform targetParent)
    { 
        m_TargetParent = targetParent; 
    }

    protected override void OnNetworkPostSpawn()
    {
        if (IsServer) 
        {
            NetworkObject.TrySetParent(m_TargetParent);
        }
        base.OnNetworkPostSpawn();
    }

This will assure that when you are parenting the newly spawned object instance is fully spawned prior to parenting it.

@marcusx2
Copy link

I have the same issue. If you spawn something and then on the client make a serverrpc call to set the parent, the parent will change on the server and client for all available clients and late joiners. However, if the server does the parent change on its own (without a serverrpc) the parent only changes on the server and not on any already available clients (late joiners will have the correct parent though).

@michalChrobot michalChrobot added the stat:reply-needed Awaiting reply from Unity account label Apr 1, 2025
@EmandM
Copy link
Collaborator

EmandM commented Apr 8, 2025

@marcusx2 Do you have the script of how your server is doing the parent change? If the client is not fully connected and synchronized when the parent is changed then the parent change message can be lost.

@github-actions github-actions bot added stat:awaiting-response Awaiting response from author. This label should be added manually. and removed stat:reply-needed Awaiting reply from Unity account labels Apr 8, 2025
@marcusx2
Copy link

marcusx2 commented Apr 9, 2025

Do you have the script of how your server is doing the parent change? If the client is not fully connected and synchronized when the parent is changed then the parent change message can be lost.

@EmandM It's nothing special. It's a NetworkBehaviour script attached to a network object. I check if it's the server or if it's the client OnNetworkSpawn. If it's the server I spawn and call TrySetParent, that is all. The parenting doesn't work for clients that are already connected, only late joiners. Maybe if I use NetworkPostSpawn? Haven't tried it. But anyways, it's a bug. It doesn't make sense to think that the message can be lost, when late joiners are correctly reparented.

@github-actions github-actions bot added stat:reply-needed Awaiting reply from Unity account and removed stat:awaiting-response Awaiting response from author. This label should be added manually. labels Apr 9, 2025
@NoelStephensUnity NoelStephensUnity added priority:high This issue has high priority and we are focusing to resolve it stat:import Status - Issue is going to be saved internally and removed stat:Investigating Issue is currently being investigated labels Apr 11, 2025
@NoelStephensUnity
Copy link
Collaborator

NoelStephensUnity commented Apr 11, 2025

@marcusx2 @Conundroy
I have targeted the problematic area for this issue within the ParentSyncMessage where it is not properly deferring the message when the parent is not spawned yet and have a pending fix that I will be posting a PR for shortly. Since this issue is relatively high, I am going to see if we can have a v2.3.1 patch for this issue (will find out Monday and you should see a PR created for this issue by sometime on Monday).

@github-actions github-actions bot added stat:awaiting-response Awaiting response from author. This label should be added manually. and removed stat:reply-needed Awaiting reply from Unity account labels Apr 11, 2025
@michalChrobot michalChrobot added stat:imported Status - Issue is tracked internally at Unity and removed stat:import Status - Issue is going to be saved internally labels Apr 14, 2025
NoelStephensUnity added a commit that referenced this issue Apr 14, 2025
This PR resolves the issue where instantiating and spawning a
`NetworkObject` (A) during another `NetworkObject`'s spawn process (B)
and then parenting the newly spawned `NetworkObject` (A) under the
`NetworkObject` (B) would end up causing the parenting message to not
properly defer the parenting message until the parent (B) was fully
spawned on other already connected and synchronized clients (it would
properly parent if another client late joined shortly after).

[MTTB-1209](https://jira.unity3d.com/browse/MTTB-1209)

fix: #3100

## Changelog

- Fixed: Issue where during a `NetworkObject` spawn if you instantiated,
spawned, and parented another network prefab under the currently
spawning `NetworkObject` the parenting message would not properly defer
until the parent `NetworkObject` was spawned.

## Testing and Documentation

- Includes new integration ParentingDuringSpawnTests test.
- No documentation changes or additions were necessary.

<!-- Uncomment and mark items off with a * if this PR deprecates any
API:
### Deprecated API
- [ ] An `[Obsolete]` attribute was added along with a `(RemovedAfter
yyyy-mm-dd)` entry.
- [ ] An [api updater] was added.
- [ ] Deprecation of the API is explained in the CHANGELOG.
- [ ] The users can understand why this API was removed and what they
should use instead.
-->

## Backport

This requires a backport to v1.x as the `ParentSyncMessage` does not
defer the message if the parent `NetworkObject` is not spawned yet.
@NoelStephensUnity
Copy link
Collaborator

Closing as #3401 resolved this issue.
This issue will be resolved in the hot-fix patch v2.3.1 update which should be available very soon.

@github-actions github-actions bot removed the stat:awaiting-response Awaiting response from author. This label should be added manually. label Apr 14, 2025
@NoelStephensUnity
Copy link
Collaborator

v2.3.1 is now available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority:high This issue has high priority and we are focusing to resolve it stat:imported Status - Issue is tracked internally at Unity type:bug Bug Report
Projects
None yet
Development

No branches or pull requests

6 participants