diff --git a/.yamato/api-updater-test.yml b/.yamato/api-updater-test.yml index 8662e698cc..678fd6d4b0 100644 --- a/.yamato/api-updater-test.yml +++ b/.yamato/api-updater-test.yml @@ -1,41 +1,52 @@ -{% metadata_file .yamato/project.metafile %} ---- - -# DESCRIPTION-------------------------------------------------------------------------- - # This job validates the NGO 2.x -> 3.x upgrade path for editor scripts. - # NGO 3.0 renamed the editor assembly and its namespaces (Unity.Netcode.Editor -> - # Unity.Netcode.GameObjects.Editor), and every relocated public type carries a [MovedFrom] so that - # Unity's API updater rewrites a 2.x project's editor scripts automatically on upgrade. - # apiupdaterproject holds editor code written against the 2.x API; the job imports it with - # -accept-apiupdate and asserts that every 2.x type reference was rewritten and none survived. - # See apiupdaterproject/README.md. - - -# TECHNICAL CONSIDERATIONS--------------------------------------------------------------- - # apiupdaterproject/Packages/manifest.json references the package by relative path - # (file:../../com.unity.netcode.gameobjects), so the job tests the package as it sits in the repo - # and needs no package-pack dependency. - # The script restores the 2.x sources when it finishes, so the checkout is left unmodified and the - # job is safe to re-run on the same agent. - # --clean purges Library first: the assertion is meaningless against a warm Library that already - # holds rewritten sources from a previous run. - -{% for platform in test_platforms.default -%} -{% for editor in validation_editors.default -%} -api_updater_test_{{ platform.name }}_{{ editor }}: - name : API Updater Test - NGO 2.x editor scripts upgrade [{{ platform.name }}, {{ editor }}] - agent: - type: {{ platform.type }} - image: {{ platform.image }} - flavor: {{ platform.flavor }} - commands: - - unity-downloader-cli --fast --wait -u {{ editor }} -c Editor # Installing basic editor for the import - - python apiupdaterproject/run_upgrade_test.py --unity .Editor --clean - artifacts: - logs: - paths: - - "apiupdaterproject/upgrade-test.log" - dependencies: - - .yamato/_run-all.yml#run_quick_checks # initial checks to perform fast validation of common errors -{% endfor -%} -{% endfor -%} +{% metadata_file .yamato/project.metafile %} +--- + +# DESCRIPTION-------------------------------------------------------------------------- + # This job validates the NGO 2.x -> 3.x upgrade path for user scripts. + # NGO 3.0 renamed the editor assembly and its namespaces (Unity.Netcode.Editor -> + # Unity.Netcode.GameObjects.Editor) and moved the runtime timing types (Unity.Netcode.NetworkTime + # and friends -> Unity.Netcode.GameObjects.Timing), and every relocated public type carries a + # [MovedFrom] so that Unity's API updater rewrites a 2.x project's scripts automatically on upgrade. + # apiupdaterproject holds code written against the 2.x API; the job imports it with + # -accept-apiupdate and asserts that every 2.x type reference was rewritten and none survived. + # See apiupdaterproject/README.md. + # + # The second run adds an assembly that occupies Unity.Netcode.NetworkTimeSystem, which is what + # Netcode for Entities does as of 6.7.0 - it sub-namespaced NetworkTime out of the shared root but + # left NetworkTimeSystem in it - and inverts the expectation for that one name: the updater is + # driven by resolution failure, so a name that still resolves cannot be migrated. NetworkTime and + # NetworkTickSystem are absent from the stub and must still migrate, so a pass proves both halves. + # This is the regression test for why the timing types were moved at all. + + +# TECHNICAL CONSIDERATIONS--------------------------------------------------------------- + # apiupdaterproject/Packages/manifest.json references the package by relative path + # (file:../../com.unity.netcode.gameobjects), so the job tests the package as it sits in the repo + # and needs no package-pack dependency. + # The script restores the 2.x sources when it finishes, so the checkout is left unmodified and the + # job is safe to re-run on the same agent. + # --clean purges Library first: the assertion is meaningless against a warm Library that already + # holds rewritten sources from a previous run. That is also why the two runs are sequential + # commands rather than one - each needs its own cold import, and the script removes the stub and + # restores the sources on every exit path, so the second run starts from the same state as the first. + +{% for platform in test_platforms.default -%} +{% for editor in validation_editors.default -%} +api_updater_test_{{ platform.name }}_{{ editor }}: + name : API Updater Test - NGO 2.x editor scripts upgrade [{{ platform.name }}, {{ editor }}] + agent: + type: {{ platform.type }} + image: {{ platform.image }} + flavor: {{ platform.flavor }} + commands: + - unity-downloader-cli --fast --wait -u {{ editor }} -c Editor # Installing basic editor for the import + - python apiupdaterproject/run_upgrade_test.py --unity .Editor --clean + - python apiupdaterproject/run_upgrade_test.py --unity .Editor --clean --collision-stub + artifacts: + logs: + paths: + - "apiupdaterproject/upgrade-test.log" + dependencies: + - .yamato/_run-all.yml#run_quick_checks # initial checks to perform fast validation of common errors +{% endfor -%} +{% endfor -%} diff --git a/apiupdaterproject/AGENTS.md b/apiupdaterproject/AGENTS.md index e1d405fbd4..1828649784 100644 --- a/apiupdaterproject/AGENTS.md +++ b/apiupdaterproject/AGENTS.md @@ -7,15 +7,17 @@ what it is and how to run it; this file covers why it is built this way and what * This is a standalone Unity project at the repo root. It is not part of `testproject` or `minimalproject`, and the package does not reference it. -* It validates one thing end to end: that a project written against the **NGO 2.x** editor API is - migrated automatically by Unity's API updater when the package is upgraded to **3.x**. +* It validates one thing end to end: that a project written against the **NGO 2.x** API is migrated + automatically by Unity's API updater when the package is upgraded to **3.x**. Two relocations are + covered — the editor namespaces, and the runtime timing types. * **The mechanism it tests does not live here.** The `[MovedFrom]` attributes are on the real types in - `com.unity.netcode.gameobjects/Editor/**`. This project only consumes them. -* **Do not "fix" the sources under `Assets/Editor`.** They are deliberately written against the 2.x - API and are the input to the test. A helpful cleanup there silently guts it. -* The expected-type list in `run_upgrade_test.py` is frozen: it enumerates the public editor API of - `develop-2.0.0`, which is released and cannot change. It only needs extending if a public editor - type is relocated again within 3.x. + `com.unity.netcode.gameobjects/Editor/**` and `com.unity.netcode.gameobjects/Runtime/Timing/**`. + This project only consumes them. +* **Do not "fix" the sources under `Assets/Editor` or `Assets/Runtime`.** They are deliberately + written against the 2.x API and are the input to the test. A helpful cleanup there silently guts it. +* The two editor blocks of `EXPECTED_MOVES` in `run_upgrade_test.py` are frozen: they enumerate the + public editor API of `develop-2.0.0`, which is released and cannot change. A block only needs + extending if a public type is relocated again within 3.x — as the timing types were. * CI runs it on demand only — comment `/ci apiupdater` on a PR. See `.yamato/api-updater-test.yml`. * **Opening this project locally mutates it.** Unity rewrites `ProjectVersion.txt` to whatever editor opened it, and the package manager can add builtin modules to `Packages/manifest.json` that only @@ -63,6 +65,37 @@ alias, type alias, base type, `typeof`, and generic type argument. The dead `using Unity.Netcode.Editor;` directives are removed and namespace aliases are rewritten in place rather than expanded at each use. +## The timing move is a namespace-only relocation, and that is a different case + +Every row measured above was a namespace **and** assembly move. The timing types keep their assembly +(`Unity.Netcode.Runtime`), so they carry `[MovedFrom(true, "Unity.Netcode", null, null)]` — a null +`sourceAssembly`, which `MovedFromAttributeData.Set` records as `assemblyHasChanged = false`. + +Two things about that are worth knowing before trusting it: + +* **The null form is the documented one.** The attribute's own comment states that any null string is + read as "has not changed" and its value is taken from the decorated type, and there is a + single-argument `MovedFromAttribute(string sourceNamespace)` constructor that does exactly + `Set(true, ns, null, null)`. Passing the real assembly name instead would set `assemblyHasChanged` + for a change that did not happen. +* **It has not been measured here.** The table above has no namespace-only row. `Assets/Runtime` plus + the timing block in `EXPECTED_MOVES` is what settles it; a `/ci apiupdater` run is the proof. + +Do not reach for `AffectsAPIUpdater` to reason about this. It reads +`!classHasChanged && !assemblyHasChanged`, which would make it false for the editor move — and the +editor move demonstrably works, so whatever that property gates, it is not script rewriting. + +### Open form: a namespace alias whose target survives + +`Assets/Runtime/DeprecatedTimingUsage.cs` contains `using TimeNs = Unity.Netcode;` used as +`TimeNs.NetworkTickSystem`. This is **not** the same case as the editor project's +`using Cfg = Unity.Netcode.Editor.Configuration;`: there the alias target itself stopped resolving and +was rewritten in place, whereas `Unity.Netcode` still exists and still holds `NetworkBehaviour` and +the rest. So the alias target cannot be rewritten and the use site has to be. The assertions do not +depend on this form — `NetworkTickSystem` is also referenced by simple name and fully qualified — so +if the updater leaves that one line alone the run still passes. Read the rewritten source rather than +assuming it was handled. + ## Known gap: assembly definition references The updater rewrites C# source only; it does not touch `.asmdef` files. diff --git a/apiupdaterproject/Assets/CollisionStub~/N4E.CollisionStub.asmdef b/apiupdaterproject/Assets/CollisionStub~/N4E.CollisionStub.asmdef new file mode 100644 index 0000000000..990f624227 --- /dev/null +++ b/apiupdaterproject/Assets/CollisionStub~/N4E.CollisionStub.asmdef @@ -0,0 +1,14 @@ +{ + "name": "N4E.CollisionStub", + "rootNamespace": "Unity.Netcode", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": true +} diff --git a/apiupdaterproject/Assets/CollisionStub~/N4ECollisionStub.cs b/apiupdaterproject/Assets/CollisionStub~/N4ECollisionStub.cs new file mode 100644 index 0000000000..f8f41ac6df --- /dev/null +++ b/apiupdaterproject/Assets/CollisionStub~/N4ECollisionStub.cs @@ -0,0 +1,17 @@ +// Stands in for a second package occupying Unity.Netcode.NetworkTimeSystem, which is what Netcode +// for Entities does as of 6.7.0: its casing correction moved 204 files into Unity.Netcode, and it +// sub-namespaced NetworkTime into Unity.Netcode.NetcodeTime but left NetworkTimeSystem behind. +// +// Only that one name collides. NetworkTime and NetworkTickSystem deliberately are not declared here, +// so a --collision-stub run asserts both halves of the finding in one pass: those two migrate, and +// the one whose old name still resolves cannot. +// +// Inert until run_upgrade_test.py --collision-stub copies this folder into place. Unity does not +// import a directory whose name ends in '~'. +namespace Unity.Netcode +{ + public class NetworkTimeSystem + { + public uint EffectiveInputLatencyTicks; + } +} diff --git a/apiupdaterproject/Assets/Runtime.meta b/apiupdaterproject/Assets/Runtime.meta new file mode 100644 index 0000000000..8babe3aec7 --- /dev/null +++ b/apiupdaterproject/Assets/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6883b96a65c44c9c8738cec1134d7372 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/apiupdaterproject/Assets/Runtime/DeprecatedTimingUsage.cs b/apiupdaterproject/Assets/Runtime/DeprecatedTimingUsage.cs new file mode 100644 index 0000000000..580d147358 --- /dev/null +++ b/apiupdaterproject/Assets/Runtime/DeprecatedTimingUsage.cs @@ -0,0 +1,45 @@ +// Update only if the relocated runtime timing API changes. Deliberately written against the +// pre-move namespace: this file is the test's input, not code to clean up. See ../../README.md. +// +// Each of the three types is named at least once in fully qualified form, so a --collision-stub run +// can tell "was not rewritten" apart from "was never referenced". +#pragma warning disable 169 // Ignore field is never used warnings + +using System; +using System.Collections.Generic; +using Unity.Netcode; +using TimeNs = Unity.Netcode; +using TimeValue = Unity.Netcode.NetworkTime; + +namespace ApiUpdaterProject +{ + // Unity.Netcode -> Unity.Netcode.GameObjects.Timing + internal class DeprecatedTimingUsage + { + // using directive plus simple name + private NetworkTime m_SimpleName; + private NetworkTimeSystem m_TimeSystem; + private NetworkTickSystem m_TickSystem; + + // Fully qualified + private Unity.Netcode.NetworkTime m_TimeFullyQualified; + private Unity.Netcode.NetworkTimeSystem m_TimeSystemFullyQualified; + private Unity.Netcode.NetworkTickSystem m_TickSystemFullyQualified; + + // Through a namespace alias, and through a type alias + private TimeNs.NetworkTickSystem m_ThroughNamespaceAlias; + private TimeValue m_ThroughTypeAlias; + + // As a generic type argument + private List m_AsGenericArgument; + + // typeof + private Type TimeSystemType => typeof(NetworkTimeSystem); + + // Constructor call, and as a return type + private NetworkTime Construct(uint tickRate) => new NetworkTime(tickRate, 0d); + + // As a parameter type + private static double TickOf(NetworkTime time) => time.TickWithPartial; + } +} diff --git a/apiupdaterproject/Assets/Runtime/DeprecatedTimingUsage.cs.meta b/apiupdaterproject/Assets/Runtime/DeprecatedTimingUsage.cs.meta new file mode 100644 index 0000000000..560f2be9b5 --- /dev/null +++ b/apiupdaterproject/Assets/Runtime/DeprecatedTimingUsage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f9442f064ea741998cc38366ada397f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/apiupdaterproject/README.md b/apiupdaterproject/README.md index 6fa786b521..984feb3b27 100644 --- a/apiupdaterproject/README.md +++ b/apiupdaterproject/README.md @@ -13,6 +13,18 @@ NGO 3.0 renamed the editor assembly and its namespaces: | `Unity.Netcode.Editor.CodeGen` | `Unity.Netcode.GameObjects.Editor.CodeGen` | | `Unity.Netcode.PackageChecker.Editor` | `Unity.Netcode.GameObjects.PackageChecker.Editor` | +It also relocated the runtime timing types out of the root namespace, so that correcting the casing +of Netcode for Entities' `Unity.NetCode` namespace does not collide with them: + +| 2.x | 3.x | +| --- | --- | +| `Unity.Netcode.NetworkTime` | `Unity.Netcode.GameObjects.Timing.NetworkTime` | +| `Unity.Netcode.NetworkTimeSystem` | `Unity.Netcode.GameObjects.Timing.NetworkTimeSystem` | +| `Unity.Netcode.NetworkTickSystem` | `Unity.Netcode.GameObjects.Timing.NetworkTickSystem` | + +The **assembly is unchanged** for the timing move — only the namespace — so those three carry a null +`sourceAssembly`, which the attribute reads as "unchanged". + ### NGO v2.x.x Unity.Netcode.Editor changes @@ -25,7 +37,9 @@ file or the DeprecatedApiUsageQualified.cs files are updated to reflect the adde | --- | --- | | `Assets/Editor/DeprecatedApiUsage.cs` | Every public 2.x editor type through `using` + simple name | | `Assets/Editor/DeprecatedApiUsageQualified.cs` | Fully qualified names, namespace alias, type alias, base type, `typeof`, generic | +| `Assets/Runtime/DeprecatedTimingUsage.cs` | The three relocated timing types, in every reference form plus a constructor call | | `Assets/UpgradeProbeBehaviour.cs` | The `MonoBehaviour` used as the `NetcodeEditorBase` type argument | +| `Assets/CollisionStub~/` | An assembly occupying the two colliding timing names. Inert — Unity does not import a folder whose name ends in `~` — until `--collision-stub` copies it in | `UpgradeProbeBehaviour` exists so the test does not name NGO's `NetworkManager`: com.unity.transport 6.6.0 — the builtin on some 6000.6 editors — ships a `Unity.Netcode.NetworkManager` of its own in @@ -38,8 +52,8 @@ resolved transport version. ## Running it locally `run_upgrade_test.py` imports the project in batch mode with `-accept-apiupdate`, then asserts that -every 2.x type reference under `Assets/Editor` was rewritten and that none survived. It restores the -2.x sources when it finishes, so it can be re-run. Windows, macOS and Linux. +every 2.x type reference under `Assets/Editor` and `Assets/Runtime` was rewritten and that none +survived. It restores the 2.x sources when it finishes, so it can be re-run. Windows, macOS and Linux. ```sh python run_upgrade_test.py --unity --clean --keep-updated-sources @@ -50,6 +64,24 @@ python run_upgrade_test.py --unity --clean --keep-updated-sources | `--unity` | Omit it if `UNITY_EDITOR_PATH` is set, or if the hub has the version named in `ProjectSettings/ProjectVersion.txt`. | | `--clean` | Purges `Library` and `Temp` first for a cold import. | | `--keep-updated-sources` | Leaves the rewritten sources in place so `git diff` shows exactly what the updater produced. | +| `--collision-stub` | Adds an assembly occupying `Unity.Netcode.NetworkTime` and `NetworkTimeSystem`, then **inverts** the expectation for those two. See below. | + +### The `--collision-stub` run + +This is the regression test for the reason the timing move exists. With the stub installed, a 2.x +reference to `NetworkTime` still resolves — to the stub — so it never fails to resolve, never reaches +the `MovedFrom` data, and cannot be migrated. `NetworkTickSystem` is deliberately **not** in the stub, +so the same run asserts that one still migrates. A pass therefore proves both halves: + +| Type | Expected under `--collision-stub` | +| --- | --- | +| `Unity.Netcode.NetworkTime` | **not** rewritten | +| `Unity.Netcode.NetworkTimeSystem` | **not** rewritten | +| `Unity.Netcode.NetworkTickSystem` | rewritten | +| every editor type | rewritten | + +If a future change ever makes the two blocked rows pass as "rewritten", the mechanism has changed and +the one-sided-move conclusion needs revisiting. Default hub locations, if you need to pass `--unity` explicitly — note that on macOS the binary is inside the `.app` bundle rather than beside it: @@ -73,6 +105,15 @@ Every relocated public editor type carries The arguments are `autoUpdateAPI, sourceNamespace, sourceAssembly, sourceClassName` — a null class name means the type name itself did not change. +The three relocated timing types carry + +```csharp +[MovedFrom(true, "Unity.Netcode", null, null)] +``` + +with `sourceAssembly` null because `Unity.Netcode.Runtime` keeps its name: any null argument is read +as "this did not change", and its value is taken from the decorated type. + A 2.x reference no longer resolves, so the compiler reports CS0246/CS0234. Unity's `ScriptUpdater` consults the `MovedFrom` data extracted from the referenced assemblies, matches the old namespace/assembly, and rewrites the reference. Nothing extra ships: no skeleton assembly, no diff --git a/apiupdaterproject/run_upgrade_test.py b/apiupdaterproject/run_upgrade_test.py index ab5d33b0f0..9c7f91bc0a 100644 --- a/apiupdaterproject/run_upgrade_test.py +++ b/apiupdaterproject/run_upgrade_test.py @@ -1,12 +1,20 @@ #!/usr/bin/env python3 """ -Verifies that Unity's API updater rewrites NGO 2.x editor API references to their NGO 3.x -Unity.Netcode.GameObjects.Editor equivalents. Runs on Windows, macOS and Linux. +Verifies that Unity's API updater rewrites NGO 2.x API references to their NGO 3.x equivalents: +editor types to Unity.Netcode.GameObjects.Editor, and the runtime timing types to +Unity.Netcode.GameObjects.Timing. Runs on Windows, macOS and Linux. -Imports the project in batch mode with -accept-apiupdate, then asserts that every -Unity.Netcode.Editor reference under Assets/Editor was rewritten and that no stale reference +Imports the project in batch mode with -accept-apiupdate, then asserts that every relocated +reference under Assets/Editor and Assets/Runtime was rewritten and that no stale reference survived. The 2.x sources are restored on exit so the test can be re-run. +With --collision-stub, a stub assembly is added that occupies Unity.Netcode.NetworkTimeSystem, +standing in for Netcode for Entities, which still declares that name in the shared root namespace. +The expectation then inverts for exactly that one: the updater is driven by resolution failure, so a +name another assembly still resolves never reaches the MovedFrom data and cannot be migrated. +NetworkTime and NetworkTickSystem are deliberately absent from the stub and must still migrate, which +is what makes the run prove both halves rather than merely fail. + Note that this script can be run from anywhere; paths are resolved relative to the script itself. """ @@ -20,30 +28,57 @@ import tempfile PROJECT_PATH = os.path.dirname(os.path.abspath(__file__)) -SOURCE_DIR = os.path.join(PROJECT_PATH, 'Assets', 'Editor') +SOURCE_DIRS = [os.path.join(PROJECT_PATH, 'Assets', 'Editor'), + os.path.join(PROJECT_PATH, 'Assets', 'Runtime')] LOG_FILE = os.path.join(PROJECT_PATH, 'upgrade-test.log') -# Every 2.x type the sources reference. The 3.x name is derived, so the pair cannot drift. -# Frozen: this is the public editor API of develop-2.0.0, which is released and will not change. -# Extend it by hand if a public editor type is ever relocated again within 3.x. -EXPECTED_TYPES = [ - 'Unity.Netcode.Editor.HiddenScriptEditor', - 'Unity.Netcode.Editor.UnityTransportEditor', - 'Unity.Netcode.Editor.NetworkAnimatorEditor', - 'Unity.Netcode.Editor.NetworkRigidbodyEditor', - 'Unity.Netcode.Editor.NetworkRigidbody2DEditor', - 'Unity.Netcode.Editor.NetcodeEditorBase', - 'Unity.Netcode.Editor.NetworkBehaviourEditor', - 'Unity.Netcode.Editor.NetworkManagerEditor', - 'Unity.Netcode.Editor.NetworkManagerHelper', - 'Unity.Netcode.Editor.NetworkObjectEditor', - 'Unity.Netcode.Editor.NetworkRigidbodyBaseEditor', - 'Unity.Netcode.Editor.NetworkTransformEditor', - 'Unity.Netcode.Editor.NetworkPrefabsEditor', - 'Unity.Netcode.Editor.Configuration.NetcodeForGameObjectsProjectSettings', - 'Unity.Netcode.Editor.Configuration.NetworkPrefabProcessor', +# A directory whose name ends in '~' is not imported, so the stub is inert until it is copied in. +STUB_SOURCE = os.path.join(PROJECT_PATH, 'Assets', 'CollisionStub~') +STUB_TARGET = os.path.join(PROJECT_PATH, 'Assets', 'CollisionStub') + +# Every 2.x type the sources reference, grouped by the move that relocated it. Stating the namespace +# pair once per move means a type's old and new names cannot drift apart. +# +# The two editor entries are frozen: they are the public editor API of develop-2.0.0, which is +# released and will not change. Extend a list only when a public type is relocated again within 3.x. +EXPECTED_MOVES = [ + ('Unity.Netcode.Editor', 'Unity.Netcode.GameObjects.Editor', [ + 'HiddenScriptEditor', + 'UnityTransportEditor', + 'NetworkAnimatorEditor', + 'NetworkRigidbodyEditor', + 'NetworkRigidbody2DEditor', + 'NetcodeEditorBase', + 'NetworkBehaviourEditor', + 'NetworkManagerEditor', + 'NetworkManagerHelper', + 'NetworkObjectEditor', + 'NetworkRigidbodyBaseEditor', + 'NetworkTransformEditor', + 'NetworkPrefabsEditor', + ]), + ('Unity.Netcode.Editor.Configuration', 'Unity.Netcode.GameObjects.Editor.Configuration', [ + 'NetcodeForGameObjectsProjectSettings', + 'NetworkPrefabProcessor', + ]), + ('Unity.Netcode', 'Unity.Netcode.GameObjects.Timing', [ + 'NetworkTime', + 'NetworkTimeSystem', + 'NetworkTickSystem', + ]), ] +# The names the --collision-stub assembly occupies; under it these must NOT be rewritten. +# Keep in sync with Assets/CollisionStub~/N4ECollisionStub.cs. +STUB_OCCUPIED = ['Unity.Netcode.NetworkTimeSystem'] + + +def expected_pairs(): + """Yields (old fully qualified name, new fully qualified name) for every relocated type.""" + for old_namespace, new_namespace, names in EXPECTED_MOVES: + for name in names: + yield f"{old_namespace}.{name}", f"{new_namespace}.{name}" + def find_editor_binary(path): """ @@ -138,7 +173,7 @@ def purge_tree(path): def copy_flat(from_dir, to_dir): - """Copies the files of a flat directory. Assets/Editor has no subdirectories.""" + """Copies the files of a flat directory. The source directories have no subdirectories.""" os.makedirs(to_dir, exist_ok=True) for entry in os.listdir(from_dir): source = os.path.join(from_dir, entry) @@ -146,16 +181,45 @@ def copy_flat(from_dir, to_dir): shutil.copy2(source, os.path.join(to_dir, entry)) +def backup_sources(backup_root): + """Copies every source directory into its own subdirectory of the backup root.""" + for source_dir in SOURCE_DIRS: + copy_flat(source_dir, os.path.join(backup_root, os.path.basename(source_dir))) + + +def restore_sources(backup_root): + """Restores every source directory from the backup root.""" + for source_dir in SOURCE_DIRS: + copy_flat(os.path.join(backup_root, os.path.basename(source_dir)), source_dir) + + def read_sources(): - """Returns the concatenated text of every .cs file under Assets/Editor.""" + """Returns the concatenated text of every .cs file in the source directories.""" parts = [] - for entry in sorted(os.listdir(SOURCE_DIR)): - if entry.endswith('.cs'): - with open(os.path.join(SOURCE_DIR, entry), encoding='utf-8-sig') as handle: - parts.append(handle.read()) + for source_dir in SOURCE_DIRS: + for entry in sorted(os.listdir(source_dir)): + if entry.endswith('.cs'): + with open(os.path.join(source_dir, entry), encoding='utf-8-sig') as handle: + parts.append(handle.read()) return '\n'.join(parts) +def install_stub(): + """Copies the collision stub into Assets so the editor imports it.""" + if not os.path.isdir(STUB_SOURCE): + sys.exit(f"Collision stub not found at {STUB_SOURCE}") + shutil.copytree(STUB_SOURCE, STUB_TARGET, dirs_exist_ok=True) + print(f"Installed the collision stub at {STUB_TARGET}") + + +def remove_stub(): + """Removes the collision stub and the .meta the editor generated beside it.""" + shutil.rmtree(STUB_TARGET, ignore_errors=True) + generated_meta = STUB_TARGET + '.meta' + if os.path.isfile(generated_meta): + os.remove(generated_meta) + + def run_editor(unity): """Imports the project in batch mode with the API updater enabled.""" if os.path.exists(LOG_FILE): @@ -175,31 +239,42 @@ def run_editor(unity): print(f"Editor exit code: {result.returncode}") -def assert_rewritten(): - """Prints a per-type result table and returns the number of types that were not rewritten.""" +def assert_rewritten(collision_stub): + """ + Prints a per-type result table and returns the number of types whose outcome was not the expected + one. Under the collision stub the expectation inverts for the names the stub occupies. + """ all_text = read_sources() - failures = 0 - print(f"\n{'TYPE':<72} {'UPDATED':>8} {'STALE':>6} RESULT") - for old in EXPECTED_TYPES: - new = old.replace('Unity.Netcode.', 'Unity.Netcode.GameObjects.', 1) + # Both counts need a trailing-token boundary: a following word character or dot means the match + # is really part of a longer name. Without it 'Unity.Netcode.NetworkTime' also counts every + # 'Unity.Netcode.NetworkTimeSystem'. + boundary = r'(?![\w.])' - updated = len(re.findall(re.escape(new), all_text)) - # The old name survives only as a distinct token: a trailing word character or dot means this - # is really part of the longer new name. - stale = len(re.findall(re.escape(old) + r'(?![\w.])', all_text)) + failures = 0 + print(f"\n{'TYPE':<72} {'UPDATED':>8} {'STALE':>6} {'EXPECT':>8} RESULT") + for old, new in expected_pairs(): + updated = len(re.findall(re.escape(new) + boundary, all_text)) + stale = len(re.findall(re.escape(old) + boundary, all_text)) + + blocked = collision_stub and old in STUB_OCCUPIED + if blocked: + # The old name still resolves to the stub, so the reference must have been left alone. + passed = updated == 0 and stale > 0 + else: + passed = updated > 0 and stale == 0 - passed = updated > 0 and stale == 0 if not passed: failures += 1 - print(f"{old:<72} {updated:>8} {stale:>6} {'PASS' if passed else 'FAIL'}") + expect = 'blocked' if blocked else 'moved' + print(f"{old:<72} {updated:>8} {stale:>6} {expect:>8} {'PASS' if passed else 'FAIL'}") return failures def main(): parser = argparse.ArgumentParser( - description="Verifies that Unity's API updater migrates NGO 2.x editor API references to 3.x.") + description="Verifies that Unity's API updater migrates NGO 2.x API references to 3.x.") parser.add_argument('--unity', default='', help='Editor binary. Defaults to UNITY_EDITOR_PATH, then to the hub install ' 'matching ProjectSettings/ProjectVersion.txt.') @@ -207,14 +282,19 @@ def main(): help='Delete Library and Temp first, for a cold import.') parser.add_argument('--keep-updated-sources', action='store_true', help='Leave the rewritten sources in place instead of restoring the originals.') + parser.add_argument('--collision-stub', action='store_true', + help='Add an assembly occupying Unity.Netcode.NetworkTime and ' + 'NetworkTimeSystem, and assert those two are NOT migrated while ' + 'NetworkTickSystem still is.') args = parser.parse_args() unity = resolve_unity(args.unity) print(f"Editor: {unity}") print(f"Project: {PROJECT_PATH}") + total = sum(1 for _ in expected_pairs()) backup_dir = tempfile.mkdtemp(prefix='ngo-apiupdater-') - copy_flat(SOURCE_DIR, backup_dir) + backup_sources(backup_dir) try: if args.clean: @@ -224,24 +304,30 @@ def main(): print(f"Removing {stale} ...") purge_tree(target) + if args.collision_stub: + install_stub() + run_editor(unity) - failures = assert_rewritten() + failures = assert_rewritten(args.collision_stub) print('') if failures == 0: - print(f"PASS: all {len(EXPECTED_TYPES)} deprecated editor types were rewritten.") + print(f"PASS: all {total} relocated types behaved as expected.") else: - print(f"FAIL: {failures} of {len(EXPECTED_TYPES)} types were not rewritten. See {LOG_FILE}") + print(f"FAIL: {failures} of {total} types did not. See {LOG_FILE}") if args.keep_updated_sources: - print(f"Rewritten sources left in place under Assets/Editor (backup: {backup_dir}).") + dirs = ', '.join(os.path.basename(d) for d in SOURCE_DIRS) + print(f"Rewritten sources left in place under Assets/{{{dirs}}} (backup: {backup_dir}).") return 0 if failures == 0 else 1 finally: # Restore on every exit path, including Ctrl-C, so an interrupted run never leaves the - # rewritten sources behind as the next run's input. + # rewritten sources or the stub behind as the next run's input. + if args.collision_stub: + remove_stub() if not args.keep_updated_sources: - copy_flat(backup_dir, SOURCE_DIR) + restore_sources(backup_dir) shutil.rmtree(backup_dir, ignore_errors=True) diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index a2cdf2051d..519cead3c2 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -19,6 +19,10 @@ Additional documentation and release notes are available at [Multiplayer Documen - `Unity.Netcode.Editor.CodeGen` → `Unity.Netcode.GameObjects.Editor.CodeGen` - `Unity.Netcode.Editor.PackageChecker` → `Unity.Netcode.GameObjects.Editor.PackageChecker` - `Unity.Netcode.Editor.Tests` → `Unity.Netcode.GameObjects.Editor.Tests` +- The timing types moved out of the `Unity.Netcode` namespace into `Unity.Netcode.GameObjects.Timing`. The assembly is unchanged, and existing scripts are migrated automatically when the package is upgraded. + - `Unity.Netcode.NetworkTime` → `Unity.Netcode.GameObjects.Timing.NetworkTime` + - `Unity.Netcode.NetworkTimeSystem` → `Unity.Netcode.GameObjects.Timing.NetworkTimeSystem` + - `Unity.Netcode.NetworkTickSystem` → `Unity.Netcode.GameObjects.Timing.NetworkTickSystem` ### Deprecated diff --git a/com.unity.netcode.gameobjects/Documentation~/advanced-topics/networktime-ticks.md b/com.unity.netcode.gameobjects/Documentation~/advanced-topics/networktime-ticks.md index 500b3d4b7c..87d25f3b66 100644 --- a/com.unity.netcode.gameobjects/Documentation~/advanced-topics/networktime-ticks.md +++ b/com.unity.netcode.gameobjects/Documentation~/advanced-topics/networktime-ticks.md @@ -183,6 +183,6 @@ For games with short play sessions casting the time to float is safe or `TimeAsF > [!NOTE] > The properties of the `NetworkTimeSystem` should be left untouched on the server/host. Changing the values on the client is sufficient to change the behavior of the time system. -The way network time gets calculated can be configured in the `NetworkTimeSystem` if needed. Refer to the [API docs](xref:Unity.Netcode.NetworkTimeSystem) for information about the properties which can be modified. All properties can be safely adjusted at runtime. For instance, buffer values can be increased for a player with a bad connection. +The way network time gets calculated can be configured in the `NetworkTimeSystem` if needed. Refer to the [API docs](xref:Unity.Netcode.GameObjects.Timing.NetworkTimeSystem) for information about the properties which can be modified. All properties can be safely adjusted at runtime. For instance, buffer values can be increased for a player with a bad connection. diff --git a/com.unity.netcode.gameobjects/Runtime/Components/AnticipatedNetworkTransform.cs b/com.unity.netcode.gameobjects/Runtime/Components/AnticipatedNetworkTransform.cs index 00bd431cbb..26d1e939e2 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/AnticipatedNetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/AnticipatedNetworkTransform.cs @@ -1,4 +1,5 @@ using Unity.Mathematics; +using Unity.Netcode.GameObjects.Timing; using Unity.Netcode.Runtime; using UnityEngine; diff --git a/com.unity.netcode.gameobjects/Runtime/Components/Interpolator/BufferedLinearInterpolator.cs b/com.unity.netcode.gameobjects/Runtime/Components/Interpolator/BufferedLinearInterpolator.cs index d38090550e..4b6de0454e 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/Interpolator/BufferedLinearInterpolator.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/Interpolator/BufferedLinearInterpolator.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Runtime.CompilerServices; +using Unity.Netcode.GameObjects.Timing; using UnityEngine; namespace Unity.Netcode diff --git a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs index a61ddc2468..338d1f991f 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs @@ -3,6 +3,7 @@ using System.Runtime.CompilerServices; using System.Text; using Unity.Mathematics; +using Unity.Netcode.GameObjects.Timing; using Unity.Netcode.Runtime; using UnityEngine; diff --git a/com.unity.netcode.gameobjects/Runtime/Core/ComponentFactory.cs b/com.unity.netcode.gameobjects/Runtime/Core/ComponentFactory.cs index 6733429ee2..304ae05efb 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/ComponentFactory.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/ComponentFactory.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Unity.Netcode.GameObjects.Timing; namespace Unity.Netcode { diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs index 748175ff1f..b0ea20d786 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs @@ -7,6 +7,7 @@ using Unity.NetCode; #endif using Unity.Netcode.Components; +using Unity.Netcode.GameObjects.Timing; using Unity.Netcode.Logging; using Unity.Netcode.Runtime; // TODO-UNIFIED: When: @@ -23,6 +24,11 @@ using PackageInfo = UnityEditor.PackageManager.PackageInfo; #endif using UnityEngine.SceneManagement; +// Netcode for Entities also declares Unity.Netcode.NetworkTimeSystem. The enclosing namespace is +// searched before any using directive, so inside Unity.Netcode the bare name binds to theirs and the +// import above is never consulted. An alias is the only spelling that reaches ours from here, since +// IDE0001 rules out qualifying the name and an alias sharing it is silently ignored. +using GameObjectsNetworkTimeSystem = Unity.Netcode.GameObjects.Timing.NetworkTimeSystem; @@ -997,7 +1003,7 @@ public NetworkPrefabHandler PrefabHandler /// Accessor property for the of the NetworkManager. /// Prefer the use of the LocalTime and ServerTime properties /// - public NetworkTimeSystem NetworkTimeSystem { get; private set; } + public GameObjectsNetworkTimeSystem NetworkTimeSystem { get; private set; } /// /// Accessor property for the of the NetworkManager. @@ -1290,7 +1296,7 @@ internal void Initialize(bool server) ConnectionManager.Initialize(this); // The remaining systems can then be initialized - NetworkTimeSystem = server ? NetworkTimeSystem.ServerTimeSystem() : new NetworkTimeSystem(1.0 / NetworkConfig.TickRate); + NetworkTimeSystem = server ? GameObjectsNetworkTimeSystem.ServerTimeSystem() : new GameObjectsNetworkTimeSystem(1.0 / NetworkConfig.TickRate); NetworkTickSystem = NetworkTimeSystem.Initialize(this); AnticipationSystem = new AnticipationSystem(this); diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs index 2a7eee8be7..62c3391b46 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Unity.Collections; +using Unity.Netcode.GameObjects.Timing; namespace Unity.Netcode { diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/TimeSyncMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/TimeSyncMessage.cs index e3ab1dfe32..bb820ece16 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/TimeSyncMessage.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/TimeSyncMessage.cs @@ -1,3 +1,5 @@ +using Unity.Netcode.GameObjects.Timing; + namespace Unity.Netcode { internal struct TimeSyncMessage : INetworkMessage, INetworkSerializeByMemcpy diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs index 36e0199a5a..a09314e8cb 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/AnticipatedNetworkVariable.cs @@ -1,5 +1,6 @@ using System; using Unity.Mathematics; +using Unity.Netcode.GameObjects.Timing; using UnityEngine; namespace Unity.Netcode diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs index 731ba2bc36..5bcd5cead3 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using Unity.Collections; +using Unity.Netcode.GameObjects.Timing; namespace Unity.Netcode { diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs index 25abeb20e9..dd52c55782 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.CompilerServices; +using Unity.Netcode.GameObjects.Timing; using UnityEngine; namespace Unity.Netcode diff --git a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs index ad465c4d9c..28803104f4 100644 --- a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Runtime.CompilerServices; using System.Text; +using Unity.Netcode.GameObjects.Timing; using Unity.Netcode.Logging; using UnityEngine; using Object = UnityEngine.Object; diff --git a/com.unity.netcode.gameobjects/Runtime/Timing/AnticipationSystem.cs b/com.unity.netcode.gameobjects/Runtime/Timing/AnticipationSystem.cs index abf0dbd60a..0e86fd24fc 100644 --- a/com.unity.netcode.gameobjects/Runtime/Timing/AnticipationSystem.cs +++ b/com.unity.netcode.gameobjects/Runtime/Timing/AnticipationSystem.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Unity.Netcode +namespace Unity.Netcode.GameObjects.Timing { internal interface IAnticipationEventReceiver { diff --git a/com.unity.netcode.gameobjects/Runtime/Timing/IRealTimeProvider.cs b/com.unity.netcode.gameobjects/Runtime/Timing/IRealTimeProvider.cs index cd20e38a0b..0f6fe9b7cf 100644 --- a/com.unity.netcode.gameobjects/Runtime/Timing/IRealTimeProvider.cs +++ b/com.unity.netcode.gameobjects/Runtime/Timing/IRealTimeProvider.cs @@ -1,4 +1,4 @@ -namespace Unity.Netcode +namespace Unity.Netcode.GameObjects.Timing { internal interface IRealTimeProvider { diff --git a/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTickSystem.cs b/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTickSystem.cs index 821f727ed3..606342332c 100644 --- a/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTickSystem.cs +++ b/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTickSystem.cs @@ -1,13 +1,15 @@ using System; using Unity.Profiling; +using UnityEngine.Scripting.APIUpdating; -namespace Unity.Netcode +namespace Unity.Netcode.GameObjects.Timing { /// /// Provides discretized time. /// This is useful for games that require ticks happening at regular interval on the server and clients. /// [Serializable] + [MovedFrom(true, "Unity.Netcode", null, null)] public class NetworkTickSystem { #if DEBUG diff --git a/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTime.cs b/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTime.cs index e452bbb187..dc245acb1b 100644 --- a/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTime.cs +++ b/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTime.cs @@ -1,8 +1,9 @@ using System; using UnityEngine; using UnityEngine.Assertions; +using UnityEngine.Scripting.APIUpdating; -namespace Unity.Netcode +namespace Unity.Netcode.GameObjects.Timing { /// /// A struct to represent a point of time in a networked game. @@ -10,6 +11,7 @@ namespace Unity.Netcode /// This struct is meant to replace the Unity API for multiplayer gameplay. /// [Serializable] + [MovedFrom(true, "Unity.Netcode", null, null)] public struct NetworkTime { private double m_TimeSec; diff --git a/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTimeSystem.cs b/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTimeSystem.cs index a967052a16..9432ccda98 100644 --- a/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTimeSystem.cs +++ b/com.unity.netcode.gameobjects/Runtime/Timing/NetworkTimeSystem.cs @@ -1,8 +1,9 @@ using System; using Unity.Profiling; using UnityEngine; +using UnityEngine.Scripting.APIUpdating; -namespace Unity.Netcode +namespace Unity.Netcode.GameObjects.Timing { /// /// is a standalone system which can be used to run a network time simulation. @@ -11,6 +12,7 @@ namespace Unity.Netcode /// effort at predicting what the server tick will be when a given network action is processed on the server. /// [Serializable] + [MovedFrom(true, "Unity.Netcode", null, null)] public class NetworkTimeSystem { /// diff --git a/com.unity.netcode.gameobjects/Runtime/Timing/RealTimeProvider.cs b/com.unity.netcode.gameobjects/Runtime/Timing/RealTimeProvider.cs index 51a2044f7b..94623b9ba0 100644 --- a/com.unity.netcode.gameobjects/Runtime/Timing/RealTimeProvider.cs +++ b/com.unity.netcode.gameobjects/Runtime/Timing/RealTimeProvider.cs @@ -1,6 +1,6 @@ using UnityEngine; -namespace Unity.Netcode +namespace Unity.Netcode.GameObjects.Timing { internal class RealTimeProvider : IRealTimeProvider { diff --git a/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs b/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs index b951353bdb..a4609373ef 100644 --- a/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs +++ b/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs @@ -11,6 +11,7 @@ using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using Unity.Jobs; +using Unity.Netcode.GameObjects.Timing; using Unity.Netcode.Runtime; using Unity.Networking.Transport; using Unity.Networking.Transport.Error; diff --git a/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs b/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs index 6cb855e2db..c9fda0cd31 100644 --- a/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs +++ b/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs @@ -7,6 +7,7 @@ using Unity.Collections.LowLevel.Unsafe; using Unity.Entities; using Unity.NetCode; +using Unity.Netcode.GameObjects.Timing; using Unity.Netcode.Transports.UTP; using UnityEngine; diff --git a/com.unity.netcode.gameobjects/Tests/Editor/InterpolatorTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/InterpolatorTests.cs index 8b3016ea73..c018cd0ff1 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/InterpolatorTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/InterpolatorTests.cs @@ -1,4 +1,5 @@ using NUnit.Framework; +using Unity.Netcode.GameObjects.Timing; namespace Unity.Netcode.GameObjects.EditorTests { diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Timing/ClientNetworkTimeSystemTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/Timing/ClientNetworkTimeSystemTests.cs index 7b435523ea..f810c45c28 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/Timing/ClientNetworkTimeSystemTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/Timing/ClientNetworkTimeSystemTests.cs @@ -1,5 +1,6 @@ using System; using NUnit.Framework; +using Unity.Netcode.GameObjects.Timing; using UnityEngine; namespace Unity.Netcode.GameObjects.EditorTests diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Timing/NetworkTimeTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/Timing/NetworkTimeTests.cs index 93403ef555..84e1d59911 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/Timing/NetworkTimeTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/Timing/NetworkTimeTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using Unity.Netcode.GameObjects.Timing; using UnityEngine; using Random = System.Random; diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Timing/ServerNetworkTimeSystemTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/Timing/ServerNetworkTimeSystemTests.cs index 4c6560aea5..ed381358eb 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/Timing/ServerNetworkTimeSystemTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/Timing/ServerNetworkTimeSystemTests.cs @@ -1,4 +1,5 @@ using NUnit.Framework; +using Unity.Netcode.GameObjects.Timing; using UnityEngine; namespace Unity.Netcode.GameObjects.EditorTests diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Timing/TimingTestHelper.cs b/com.unity.netcode.gameobjects/Tests/Editor/Timing/TimingTestHelper.cs index ffa62cc265..38306054e6 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/Timing/TimingTestHelper.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/Timing/TimingTestHelper.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Unity.Netcode.GameObjects.Timing; using UnityEngine; using Random = System.Random; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/MockTimeProvider.cs b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/MockTimeProvider.cs index 070cb41dae..4bda57834e 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/MockTimeProvider.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/MockTimeProvider.cs @@ -1,3 +1,5 @@ +using Unity.Netcode.GameObjects.Timing; + namespace Unity.Netcode.TestHelpers.Runtime { /// diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs index f7a1ba1001..6dbf9fe2e1 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs @@ -9,6 +9,7 @@ #if UNIFIED_NETCODE using Unity.NetCode; #endif +using Unity.Netcode.GameObjects.Timing; using Unity.Netcode.RuntimeTests; using Unity.Netcode.Transports.UTP; using UnityEngine; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Timing/NetworkTimeSystemTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Timing/NetworkTimeSystemTests.cs index 8dca0b69d6..ec16f951b6 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Timing/NetworkTimeSystemTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Timing/NetworkTimeSystemTests.cs @@ -1,5 +1,6 @@ using System.Collections; using NUnit.Framework; +using Unity.Netcode.GameObjects.Timing; using Unity.Netcode.TestHelpers.Runtime; using UnityEngine; using UnityEngine.Assertions.Comparers; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Timing/TimeIntegrationTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Timing/TimeIntegrationTest.cs index d5e404a16e..b250e72196 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Timing/TimeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Timing/TimeIntegrationTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using NUnit.Framework; +using Unity.Netcode.GameObjects.Timing; using Unity.Netcode.TestHelpers.Runtime; using UnityEngine; using UnityEngine.TestTools;