Fix Unity 6000.5 compile errors, deprecation warnings, and NLog initialization - #1984
Open
mikhail-dcl wants to merge 4 commits into
Open
Conversation
Unity 6000.5 resolves NLog's assembly location to the host executable
path, so NLog's scan for optional NLog.*.dll extension assemblies calls
Directory.GetFiles on a file and throws while building
ConfigurationItemFactory.Default:
IOException: The parameter is incorrect :
'C:\...\Editor\Unity.exe'
at NLog.Config.ConfigurationItemFactory.GetNLogExtensionFiles
at NLog.Config.ConfigurationItemFactory.BuildDefaultFactory
at NLog.Layouts.Layout.op_Implicit
at NLog.Targets.TargetWithLayout..ctor
Creating any layout or target resolves that factory implicitly, so the
exception escapes the static constructors that reach the log managers and
permanently poisons those types. It surfaces from AltRunner in the player
and from AltBuilder in the editor, the latter during an editor delay call
in AltTesterImportErrorChecker, which makes the SDK unusable on 6000.5.
All three log factories are affected -- DriverLogManager, ServerLogManager
and EditorLogManager -- so the guard lives once on DriverLogManager, the
lowest assembly the other two already reference, and each buildLogFactory
calls it first. Seeding happens before the UNITY_EDITOR || ALTTESTER split
so the ConsoleTarget and FileTarget paths are covered too.
The SDK ships no NLog extension assemblies, so registering NLog's built-in
items directly loses nothing. Guarded by UNITY_6000_5_OR_NEWER and a first
-call flag, so it is a no-op on other Unity versions, outside Unity, and on
every call after the first.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1983.
This PR covers two independent Unity 6000.5 problems. The first is the compile errors from the
GetInstanceIDdeprecation, described immediately below. The second is a runtimeTypeLoadExceptionthat leaves the SDK unusable even once it compiles; it is described in the final section, NLog initialization on Unity 6000.5.Problem
Unity 6000.4 deprecated
Object.GetInstanceID()in favour ofObject.GetEntityId(). Unity 6000.5 raised that deprecation to an error, so the SDK's 19GetInstanceID()call sites across 6 files emit CS0619 andAltTester.AltTesterUnitySDK.dlldoes not build.Renaming the call is not sufficient:
EntityId's implicit conversion tointis also deprecated as an error, soint id = obj.GetEntityId();does not compile.#pragma warning disable CS0619does not suppress an obsolete-as-error, so there is no consumer-side workaround.EntityId.GetRawData()is deprecated in favour ofEntityId.ToULong(EntityId), which is the supported accessor.Changes
Compile errors. New
Runtime/Commands/Utils/AltObjectId.cs; all 19 call sites route through it:The narrowing keeps the id 32-bit, matching
AltObject.id,transformIdandtransformParentId. Widening it is a wire-format change across the C#, Java, Python and Robot bindings, and is out of scope.Deprecation warnings. Clears the 5 CS0618 warnings Unity 6000.5 adds, using the
NamedBuildTargetpattern already present inAltBuilder.cs:AltRunner.cs—FindObjectsOfType<UIDocument>()→FindObjectsByType<UIDocument>(), plus an explicit sort (see Ordering).AltGetAllCamerasCommand.cs— adds aUNITY_6000_4_OR_NEWERtier using the no-argumentFindObjectsByType<Camera>(); theFindObjectsSortModeoverload is now deprecated too.AltTesterEditorWindow.cs—GetScriptingDefineSymbolsForGroup(BuildTargetGroup)→GetScriptingDefineSymbols(NamedBuildTarget).CreateAltPrefab.cs— theGetScriptingDefineSymbolsForGroupresult was assigned to a local never read anywhere in the file; the dead assignment is removed.Version gate
EntityId.ToULongand the no-argumentFindObjectsByType<T>()overload both first appear in 6000.4. Compiled against each editor's own reference assemblies with-warnaserror:unchecked((int)EntityId.ToULong(o.GetEntityId()))FindObjectsByType<T>()EntityIdhas noToULongGating at
UNITY_6000_5_OR_NEWERwould leave a CS0618 warning on 6000.4. Versions below 6000.4 keep the existing code paths, so the"unity": "2021.3"floor inpackage.jsonis unaffected.Validation
Unity 6000.5.9f1, batch mode, this repository:
AltTester.AltTesterUnitySDK.dllandAltTester.AltTesterUnitySDK.Editor.dllrecompile with 0 errors and 0 warnings. Before: 19 errors, 5 warnings.Also compiled in a separate ~21k-asset project on 6000.5.9f1 with the package linked via
file:— no AltTester diagnostics.Returned ids compared against
GetInstanceIDreached by reflection:Both id signs are covered, exercising the
uncheckednarrowing.Ordering
Of the two call sites moving to
FindObjectsByType, one is order-sensitive.AltGetAllCamerasCommandonly enumerates its result (twofrom ... selectprojections, no indexing) and has passedFindObjectsSortMode.Nonesince Unity 6 support was added. Order was already unspecified; nothing observable changes.AltRunner.GetScreenPositionused an ungatedFindObjectsOfType<UIDocument>()on all Unity versions and readsuIDocuments[0]twice.FindObjectsOfTypeorders by instance id;FindObjectsByTypedoes not. The previous ordering is restored explicitly:Measured on 6000.5.9f1:
FindObjectsOfType<T>()orders ascending by instance id, so[0]is the minimum.FindObjectsByType<T>()is unordered: five objects created in sequence returned-1508, -1532, -1520, -1526, -1514, against-1532, -1526, -1520, -1514, -1508fromFindObjectsOfType.FindObjectsOfTypeand[0]is the same object reference.System.Array.Sortwith a non-capturing lambda adds no allocation and needs no newusing. Instance ids are unique, so sort stability is immaterial.Pre-existing and untouched: the same method indexes
[0]without a length check and throws when a scene contains noUIDocument.NLog initialization on Unity 6000.5
Problem
Unity 6000.5 resolves NLog's assembly location to the host executable path. NLog's scan for optional
NLog.*.dllextension assemblies then callsDirectory.GetFileson a file rather than a directory and throws while buildingConfigurationItemFactory.Default:Constructing any layout or target resolves that factory implicitly, so the exception escapes whichever static constructor first reaches a log manager and permanently poisons that type. Both entry points are fatal:
AltBuilder..cctor->EditorLogManager.Instance, reached fromAltTesterImportErrorChecker.DeleteAltTesterPrefabIfExistson anEditorApplicationdelay call. This fires on editor load, so the SDK is broken before anything is run.AltRunner..cctor->ServerLogManager.Instance.Because the failure happens inside a type initializer, the resulting
TypeInitializationExceptionis not recoverable for the lifetime of the domain.Scope
All three log factories construct NLog targets and are equally affected, in three separate assemblies:
DriverLogManagerAltTester.AltTesterUnitySDK.DriverServerLogManagerAltTester.AltTesterUnitySDKEditorLogManagerAltTester.AltTesterUnitySDK.EditorChanges
One guard, on
DriverLogManager— the lowest of the three assemblies, which the other two already reference — so there is a single implementation rather than three copies:Each
buildLogFactory()calls it as its first statement. Three properties matter:#ifis inside the method, so call sites carry no conditional compilation and the method is a no-op on other Unity versions and outside Unity entirely, whereUNITY_6000_5_OR_NEWERis never defined.Lazy<LogFactory>instances can each call it; only the first assigns, so no factory discards registrations made by an earlier one.#if UNITY_EDITOR || ALTTESTERsplit in each factory, so theConsoleTargetandFileTargetpaths used by non-instrumented builds are covered as well. A static constructor onUnityTargetwould have been a smaller change but would miss those, since that type only compiles under the editor/ALTTESTER branch.Nothing is lost by skipping the scan: the SDK bundles only
NLog.dll(Runtime/3rdParty/nlog.4.7.9) and ships noNLog.*.dllextension assemblies for it to find.Validation
Unity 6000.5.9f1. All three assemblies —
AltTester.AltTesterUnitySDK.Driver.dll,AltTester.AltTesterUnitySDK.dllandAltTester.AltTesterUnitySDK.Editor.dll— recompile with 0 errors, and the log is free ofIOException,GetNLogExtensionFilesandTypeInitializationException.Confirmed in a ~21k-asset project on 6000.5.9f1 with the package linked from this branch: before the change, launching the editor reported the
AltBuilderTypeInitializationExceptionabove on every load; after it, the editor loads clean.The editor path is verified directly. The player path (
AltRunner->ServerLogManager) shares the same guard and the same factory, but was not exercised in a player build.