Skip to content

Commit 7d1c3eb

Browse files
Merge branch 'develop' into pvp-fixes-develop-v2
2 parents 281f06d + c040066 commit 7d1c3eb

File tree

12 files changed

+175
-68
lines changed

12 files changed

+175
-68
lines changed

.github/ISSUE_TEMPLATE/support.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
name: Support
33
about: Have a question or need help with anything?
44
title: ''
5-
labels: stat:awaiting-triage, stat:reply-needed, type:support
5+
labels: stat:awaiting triage, type:support
66
assignees: ''
77

88
---
99

10-
Post your questions or problems here.
10+
For support related questions we HIGHLY recommend to post a message either on the [Unity Discussions](https://discussions.unity.com/tag/netcode-for-gameobjects) or on our [Discord Community](https://discord.gg/TqNeJTtC) where you can get help from the community and the developers.
11+
Those forums will get you the fastest response and are the best place to ask for help.
1112

12-
For general questions, networking advice or discussions about the Netcode for GameObjects, you can also reach us on our [Discord Community](https://discord.gg/FM8SE9E) or create a post in the [Unity Multiplayer Forum](https://forum.unity.com/forums/multiplayer.26/).
13+
If you still feel like you want to open a support issue as an GitHub Issue, please make sure to include as much information as possible (also including any relevant code/project) to help us understand your problem.

.github/pull_request_template.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22

33
<!-- Add short version of the JIRA ticket to the PR title (e.g. "feat: new shiny feature [MTT-123]") -->
44

5-
<!-- Add RFC link here if applicable. -->
6-
75
## Changelog
86

97
- Added: The package whose Changelog should be added to should be in the header. Delete the changelog section entirely if it's not needed.
10-
- Fixed: If you update multiple packages, create a new section with a new header for the other package.
8+
- Fixed: If you update multiple packages, create a new section with a new header for the other package.
119
- Removed/Deprecated/Changed: Each bullet should be prefixed with Added, Fixed, Removed, Deprecated, or Changed to indicate where the entry should go.
1210

1311
## Testing and Documentation
@@ -26,3 +24,13 @@
2624
- [ ] Deprecation of the API is explained in the CHANGELOG.
2725
- [ ] The users can understand why this API was removed and what they should use instead.
2826
-->
27+
28+
## Backport
29+
30+
<!-- If this is a backport:
31+
- Add the following to the PR title: "\[Backport\] ..." .
32+
- Link to the original PR.
33+
If this needs a backport - state this here
34+
If a backport is not needed please provide the reason why.
35+
If the "Backports" section is not present it will lead to a CI test failure.
36+
-->

.github/workflows/assignee-management.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ env:
2121
jobs:
2222
handle_assignment:
2323
name: Handle Issue Assignment Changes
24-
if: ${{ !github.event.issue.pull_request }} && ${{ github.event.issue.state == 'open' }}
24+
if: ${{ !github.event.issue.pull_request && github.event.issue.state == 'open' }}
2525
runs-on: ubuntu-latest
2626
permissions:
2727
issues: write
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# This workflow is designed to verify that the pull request description contains a "## Backport" section, which is important as a reminder to account for backports for anyone that works with NGO repository.
2+
# We have 2 development branches (develop and develop-2.0.0) and we need to ensure that relevant changes are landing in only one or both of them
3+
# If the "##Backport" section is missing, the workflow will fail and block the PR from merging, prompting the developer to add this section.
4+
5+
# The workflow is configured to run when PR is created as well as when it is edited which also counts simple description edits.
6+
7+
name: "NGO - Backport Verification"
8+
9+
on:
10+
pull_request:
11+
types: [opened, edited]
12+
branches:
13+
- develop
14+
- develop-2.0.0
15+
16+
jobs:
17+
backport-verification:
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v3
22+
23+
- name: Check PR description
24+
uses: actions/github-script@v6
25+
with:
26+
script: |
27+
const pr = context.payload.pull_request;
28+
const body = pr.body || '';
29+
30+
if (!body.includes('## Backport')) {
31+
core.setFailed('PR description must include a "## Backport" section. Please add this section and provide information about this PR backport to develop or develop-2.0.0 branch respectively or explain why backport is not needed.');
32+
}

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@ Additional documentation and release notes are available at [Multiplayer Documen
1616

1717
### Fixed
1818

19+
- Fixed issue where in-scene placed `NetworkObjects` could fail to synchronize its transform properly (especially without a `NetworkTransform`) if their parenting changes from the default when the scene is loaded and if the same scene remains loaded between network sessions while the parenting is completely different from the original hierarchy. (#3388)
20+
- Fixed an issue in `UnityTransport` where the transport would accept sends on invalid connections, leading to a useless memory allocation and confusing error message. (#3383)
1921
- Fixed issue where `NetworkAnimator` would log an error if there was no destination transition information. (#3384)
2022
- Fixed initial `NetworkTransform` spawn, ensure it uses world space. (#3361)
2123
- Fixed issue where `AnticipatedNetworkVariable` previous value returned by `AnticipatedNetworkVariable.OnAuthoritativeValueChanged` is updated correctly on the non-authoritative side. (#3322)
2224

2325
### Changed
2426

27+
- Changed the scene loading event serialization order for in-scene placed `NetworkObject`s to be based on their parent-child hierarchy. (#3388)
2528

2629
## [1.12.2] - 2025-01-17
2730

com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -185,15 +185,18 @@ private bool IsEditingPrefab()
185185
/// </remarks>
186186
private void CheckForInScenePlaced()
187187
{
188-
if (PrefabUtility.IsPartOfAnyPrefab(this) && !IsEditingPrefab() && gameObject.scene.IsValid() && gameObject.scene.isLoaded && gameObject.scene.buildIndex >= 0)
188+
if (gameObject.scene.IsValid() && gameObject.scene.isLoaded && gameObject.scene.buildIndex >= 0)
189189
{
190-
var prefab = PrefabUtility.GetCorrespondingObjectFromSource(gameObject);
191-
var assetPath = AssetDatabase.GetAssetPath(prefab);
192-
var sourceAsset = AssetDatabase.LoadAssetAtPath<NetworkObject>(assetPath);
193-
if (sourceAsset != null && sourceAsset.GlobalObjectIdHash != 0 && InScenePlacedSourceGlobalObjectIdHash != sourceAsset.GlobalObjectIdHash)
190+
if (PrefabUtility.IsPartOfAnyPrefab(this))
194191
{
195-
InScenePlacedSourceGlobalObjectIdHash = sourceAsset.GlobalObjectIdHash;
196-
EditorUtility.SetDirty(this);
192+
var prefab = PrefabUtility.GetCorrespondingObjectFromSource(gameObject);
193+
var assetPath = AssetDatabase.GetAssetPath(prefab);
194+
var sourceAsset = AssetDatabase.LoadAssetAtPath<NetworkObject>(assetPath);
195+
if (sourceAsset != null && sourceAsset.GlobalObjectIdHash != 0 && InScenePlacedSourceGlobalObjectIdHash != sourceAsset.GlobalObjectIdHash)
196+
{
197+
InScenePlacedSourceGlobalObjectIdHash = sourceAsset.GlobalObjectIdHash;
198+
EditorUtility.SetDirty(this);
199+
}
197200
}
198201
IsSceneObject = true;
199202
}
@@ -1243,7 +1246,7 @@ private void OnTransformParentChanged()
12431246
// we call CheckOrphanChildren() method and quickly iterate over OrphanChildren set and see if we can reparent/adopt one.
12441247
internal static HashSet<NetworkObject> OrphanChildren = new HashSet<NetworkObject>();
12451248

1246-
internal bool ApplyNetworkParenting(bool removeParent = false, bool ignoreNotSpawned = false, bool orphanedChildPass = false)
1249+
internal bool ApplyNetworkParenting(bool removeParent = false, bool ignoreNotSpawned = false, bool orphanedChildPass = false, bool enableNotification = true)
12471250
{
12481251
if (!AutoObjectParentSync)
12491252
{
@@ -1316,7 +1319,10 @@ internal bool ApplyNetworkParenting(bool removeParent = false, bool ignoreNotSpa
13161319
// to WorldPositionStays which can cause scaling issues if the parent's
13171320
// scale is not the default (Vetctor3.one) value.
13181321
transform.SetParent(null, m_CachedWorldPositionStays);
1319-
InvokeBehaviourOnNetworkObjectParentChanged(null);
1322+
if (enableNotification)
1323+
{
1324+
InvokeBehaviourOnNetworkObjectParentChanged(null);
1325+
}
13201326
return true;
13211327
}
13221328

@@ -1342,7 +1348,10 @@ internal bool ApplyNetworkParenting(bool removeParent = false, bool ignoreNotSpa
13421348

13431349
m_CachedParent = parentObject.transform;
13441350
transform.SetParent(parentObject.transform, m_CachedWorldPositionStays);
1345-
InvokeBehaviourOnNetworkObjectParentChanged(parentObject);
1351+
if (enableNotification)
1352+
{
1353+
InvokeBehaviourOnNetworkObjectParentChanged(parentObject);
1354+
}
13461355
return true;
13471356
}
13481357

@@ -1826,6 +1835,8 @@ internal SceneObject GetMessageSceneObject(ulong targetClientId)
18261835
{
18271836
var obj = new SceneObject
18281837
{
1838+
HasParent = transform.parent != null,
1839+
WorldPositionStays = m_CachedWorldPositionStays,
18291840
NetworkObjectId = NetworkObjectId,
18301841
OwnerClientId = OwnerClientId,
18311842
IsPlayerObject = IsPlayerObject,
@@ -1836,31 +1847,16 @@ internal SceneObject GetMessageSceneObject(ulong targetClientId)
18361847
TargetClientId = targetClientId
18371848
};
18381849

1839-
NetworkObject parentNetworkObject = null;
1840-
1841-
if (!AlwaysReplicateAsRoot && transform.parent != null)
1850+
// Handle Parenting
1851+
if (!AlwaysReplicateAsRoot && obj.HasParent)
18421852
{
1843-
parentNetworkObject = transform.parent.GetComponent<NetworkObject>();
1844-
// In-scene placed NetworkObjects parented under GameObjects with no NetworkObject
1845-
// should set the has parent flag and preserve the world position stays value
1846-
if (parentNetworkObject == null && obj.IsSceneObject)
1847-
{
1848-
obj.HasParent = true;
1849-
obj.WorldPositionStays = m_CachedWorldPositionStays;
1850-
}
1851-
}
1853+
var parentNetworkObject = transform.parent.GetComponent<NetworkObject>();
18521854

1853-
if (parentNetworkObject != null)
1854-
{
1855-
obj.HasParent = true;
1856-
obj.ParentObjectId = parentNetworkObject.NetworkObjectId;
1857-
obj.WorldPositionStays = m_CachedWorldPositionStays;
1858-
var latestParent = GetNetworkParenting();
1859-
var isLatestParentSet = latestParent != null && latestParent.HasValue;
1860-
obj.IsLatestParentSet = isLatestParentSet;
1861-
if (isLatestParentSet)
1855+
if (parentNetworkObject)
18621856
{
1863-
obj.LatestParent = latestParent.Value;
1857+
obj.ParentObjectId = parentNetworkObject.NetworkObjectId;
1858+
obj.LatestParent = GetNetworkParenting();
1859+
obj.IsLatestParentSet = obj.LatestParent != null && obj.LatestParent.HasValue;
18641860
}
18651861
}
18661862

@@ -1873,12 +1869,6 @@ internal SceneObject GetMessageSceneObject(ulong targetClientId)
18731869
var syncRotationPositionLocalSpaceRelative = obj.HasParent && !m_CachedWorldPositionStays;
18741870
var syncScaleLocalSpaceRelative = obj.HasParent && !m_CachedWorldPositionStays;
18751871

1876-
// Always synchronize in-scene placed object's scale using local space
1877-
if (obj.IsSceneObject)
1878-
{
1879-
syncScaleLocalSpaceRelative = obj.HasParent;
1880-
}
1881-
18821872
// If auto object synchronization is turned off
18831873
if (!AutoObjectParentSync)
18841874
{
@@ -1956,6 +1946,15 @@ internal static NetworkObject AddSceneObject(in SceneObject sceneObject, FastBuf
19561946
var bufferSerializer = new BufferSerializer<BufferSerializerReader>(new BufferSerializerReader(reader));
19571947
networkObject.SynchronizeNetworkBehaviours(ref bufferSerializer, networkManager.LocalClientId);
19581948

1949+
// If we are an in-scene placed NetworkObject and we originally had a parent but when synchronized we are
1950+
// being told we do not have a parent, then we want to clear the latest parent so it is not automatically
1951+
// "re-parented" to the original parent. This can happen if not unloading the scene and the parenting of
1952+
// the in-scene placed Networkobject changes several times over different sessions.
1953+
if (sceneObject.IsSceneObject && !sceneObject.HasParent && networkObject.m_LatestParent.HasValue)
1954+
{
1955+
networkObject.m_LatestParent = null;
1956+
}
1957+
19591958
// Spawn the NetworkObject
19601959
networkManager.SpawnManager.SpawnNetworkObjectLocally(networkObject, sceneObject, sceneObject.DestroyWithScene);
19611960

com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventData.cs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,14 @@ internal void AddSpawnedNetworkObjects()
322322
m_NetworkObjectsSync.Add(sobj);
323323
}
324324
}
325+
SortObjectsToSync();
326+
}
325327

328+
/// <summary>
329+
/// Used to order the object serialization for both synchronization and scene loading
330+
/// </summary>
331+
private void SortObjectsToSync()
332+
{
326333
// Sort by INetworkPrefabInstanceHandler implementation before the
327334
// NetworkObjects spawned by the implementation
328335
m_NetworkObjectsSync.Sort(SortNetworkObjects);
@@ -568,20 +575,31 @@ internal void SerializeScenePlacedObjects(FastBufferWriter writer)
568575
// Write our count place holder (must not be packed!)
569576
writer.WriteValueSafe((ushort)0);
570577

578+
// Clear our objects to sync and build a list of the in-scene placed NetworkObjects instantiated and spawned locally
579+
m_NetworkObjectsSync.Clear();
571580
foreach (var keyValuePairByGlobalObjectIdHash in m_NetworkManager.SceneManager.ScenePlacedObjects)
572581
{
573582
foreach (var keyValuePairBySceneHandle in keyValuePairByGlobalObjectIdHash.Value)
574583
{
575584
if (keyValuePairBySceneHandle.Value.Observers.Contains(TargetClientId))
576585
{
577-
// Serialize the NetworkObject
578-
var sceneObject = keyValuePairBySceneHandle.Value.GetMessageSceneObject(TargetClientId);
579-
sceneObject.Serialize(writer);
580-
numberOfObjects++;
586+
m_NetworkObjectsSync.Add(keyValuePairBySceneHandle.Value);
581587
}
582588
}
583589
}
584590

591+
// Sort the objects to sync based on parenting hierarchy
592+
SortObjectsToSync();
593+
594+
// Serialize the sorted objects to sync.
595+
foreach (var objectToSycn in m_NetworkObjectsSync)
596+
{
597+
// Serialize the NetworkObject
598+
var sceneObject = objectToSycn.GetMessageSceneObject(TargetClientId);
599+
sceneObject.Serialize(writer);
600+
numberOfObjects++;
601+
}
602+
585603
// Write the number of despawned in-scene placed NetworkObjects
586604
writer.WriteValueSafe(m_DespawnedInSceneObjectsSync.Count);
587605
// Write the scene handle and GlobalObjectIdHash value

0 commit comments

Comments
 (0)