#Different StableTypeHash in Editor vs Build

1 messages · Page 1 of 1 (latest)

prisma zenith
#

Loaded up a build on work project after updating from 1.3.5 to 1.3.10
ArgumentException: Cannot find TypeIndex for type hash 2099003614977633896. Check in the debug file ExportedTypes.log of your project Logs folder (<projectName>/Logs) the corresponding Component type name for the type hash 2099003614977633896. And ensure your runtime depends on all assemblies defining the Component types your data uses.

0x1d2128aab500ae68 - 2099003614977633896 - Animations.Client.Data.AnimancerAnimationState

    [Serializable]
    public class AnimancerAnimationState : IComponentData
    {
        [CreateProperty] [NonSerialized] public AnimancerState value;
    }```

Not familar with the component in the project so no idea about those attributes, but looking at uses this seems to be added as a component in baking but without ever setting data until runtime.

`baker.AddComponentObject(e, new AnimancerAnimationState());`

Debugging the hash at runtime we get, 
`AnimancerAnimationState runtime hash 9194182210451528232`

@regal sierra (sorry ![mopLove](https://cdn.discordapp.com/emojis/1016644743385595905.webp?size=128 "mopLove") )
regal sierra
#

can you paste animancerstate also?

#

also what stripping level? (not that that should matter, but yknow)

prisma zenith
#

stripping is minimal

#

do fields matter for managed components that are referenced?
just looking at animancer source it inherits from animancerNode which seems to have a condition field

        /// <summary>[Editor-Only, Internal] Indicates whether the Inspector details for this node are expanded.</summary>
        internal bool _IsInspectorExpanded;
#endif```
regal sierra
#

i believe they do, but i'm not sure why any recent change would have caused that to matter a different amount from before

#

so i guess this could be actually a regression from 1.3.8 to 1.3.9, rather than from 1.3.9->1.3.10

#

and that is more thinkable that the typemanager getting its hashes from an entirely different place (i.e. from codegen) would cause an issue here

prisma zenith
#

we're updating from 1.3.5 so i can't confirm if it worked in any version after that

regal sierra
#

how about animancernode?

#

and while we're at it animancerevent.sequence

prisma zenith
#

i can confirm it's the

#if UNITY_EDITOR
        /// <summary>[Editor-Only, Internal] Indicates whether the Inspector details for this node are expanded.</summary>
        internal bool _IsInspectorExpanded;
#endif```
#

i removed the conditionals here and it worked fine, generate same hash at runtime for AnimancerAnimationState

#

just realized i probably shouldn't be posting large chunks of the source here as i think it's a paid asset ^_^
i can dump you it on slack if you still want but yeah looks like that's the issue

regal sierra
#

ok i can test that out thanks

#

actually, i'm kind of surprised that ever worked, really.

#

now that i think about it, the scene is serialized with the editor's version of the type, and it writes down the editor's type hash for the type into the scene file

#

but maybe we're looking more deeply into managed types now, i guess.

#

obviously it should never work for unmanaged types.

#

anyway, must go parent, but thanks for the report and sorry for the regression!

prisma zenith
#

looking at git history, it was added 2024/04/23

#

so not a recent addition

#

easy enough workaround, an extra bool in the build ain't going to break the bank
and it does appear like the build is now error free so hopefully nothing more to report (though i haven't built server yet...)

prisma zenith
#

unfortunately on further testing this is now generating different hashes in release/development now

#

development is matching editor but release is getting a different

#

there were some cases in animancer of UNITY_ASSERTIONS on fields which i thought was the problem

#

as i assume they exist in development not release

#

but after removing and triple checking there are no more remaining

#

the only thing i can see left that could different is managed stuff native to unityengine

#

like playables

#

though i haven't confirmed it actually crawls into subtypes

#

otherwise i'm at a loss now though

#

will probably just rewrite this to no longer bake this component and just suck up the structural change at runtime

#

actually unless, it's also using static properties? i just assumed they were ignored but i guess i can try the 1 remaining static property that is stripped

#

i just recall statics weren't used for stable hash

regal sierra
#

it is probably true that it's inspecting managed types too deeply right now

#

i'm sure i'll get to it before the next release; right now i'm on occuros's compile error with the array thing, but this is up next immediately after that

#

you could also check for any #if DEVELOPMENT_BUILD iirc, which would be in common between dev player and editor and not nondev player

prisma zenith
#

I couldn't see anything

#

Decided to just stop caring and go with the simple approach to fix it

#

Just replace it with object

#
        private object value;

        [CreateProperty]
        public AnimancerState Value
        {
            get => value as AnimancerState;
            set => this.value = value;
        }

Kind of deal

regal sierra
#

well, still worth fixing. by the way, was that #if UNITY_EDITOR field on a monobehaviour or scriptableobject, or on a type that was neither?

prisma zenith
#

It's just a normal class

regal sierra
#

it seems like probably what we used to do was that we would look inside normal managed types, but not inside ones that inherited from unityengine.object

#

i suppose i'll go back to the old version and try to figure out when it could work to #if like that

prisma zenith
#

does it crawl class fields as well
as in

class ICompoenntData
    MyClass Field;

class MyClass
    SomeOtherClass SomeField;

class SomeOTherClass
#if 
    Condition Field;
#endif```
#

because i think that's currently where i stand with why its still broken

regal sierra
#

it does, as long as they aren't circular references, and as long as they don't inherit from unityengine.object

prisma zenith
#

animancer has 128 #if

#

and i've removed all the top level ones and the ones i could find, but there are a lot i needed to go through so ended up being easier to just not deal with it and having to main fork

#

Most are UNITY_ASSERTIONS which is why i think its working in dev not release now

#

btw, i don't mind if classes aren't allowed conditionals

#

it was just a regression for us is all

regal sierra
#

i think maybe it looked inside top-level classes, but then actually stopped like so when it saw a class field, like you said: if (fieldType.IsClass) fieldTypeHash = HashTypeName(fieldType); else if(!cache.TryGetValue(fieldType, out fieldTypeHash)) { fieldTypeHash = HashType(fieldType, cache); }

#

i saw this at the top and assumed that was the only time we early-outed if (type.IsArray || type.IsPointer || type.IsPrimitive || type.IsEnum || (TypeManager.UnityEngineObjectType?.IsAssignableFrom(type) == true)) { cache.Add(type, hash); return hash; } but there was a second out

#

the old behavior is kind of weird. but i'd also rather not unintentionally regress like this

#

but it would mean that before, you could not #if UNITY_EDITOR your field on a top level component type, even if it was managed, but you could do it on a type that a component had as a field

#

which is a crazy rule, as far as i can tell?

prisma zenith
#

it does sound a bit odd, but did it matter hmm

regal sierra
#

i guess one question is, how did serialization work if this was actually a problem; the hash is for serialization anyway, after all

prisma zenith
#

well we weren't actually serializing data on it so no idea if it would have been broken
It was added as null during baking and setup at runtime