Search Unity

Animator.StringToHash with TCPClient

Discussion in 'Scripting' started by Ziron999, Jul 17, 2020.

  1. Ziron999

    Ziron999

    Joined:
    Jan 22, 2014
    Posts:
    282
    If i send a hash through the network will it be the same for the client?
    Is this a set hash system or is it "generated randomly" upon running the game?
    Sending animation states in an optimized way is the hardest thing i'm stuck on. I have nearly everything else ready to go but animations are hard to get down in a minimized performance based way. I have no interest in changing my method so don't suggest things like "predictive animation" please. The way I am doing this just sends 1 byte. I just need to know things like this.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    I suppose you could dig for it in the documentation to see, but it might be hard to find.

    Alternatively you could probably construct a test in under half an hour with two of your machines reporting the hashes and then compare them. None of us here (or few of us here) have our games set up to test such a thing, whereas you clearly do.

    If they're the hashes are same you're golden, if you assume they'll stay that way in future versions of Unity.

    If they're different then maybe you have to implement a remap handshake at the start of a connection so that they can be trans-mapped in some way between clients.
     
  3. Ziron999

    Ziron999

    Joined:
    Jan 22, 2014
    Posts:
    282
    yes, right now i convert the hash into a byte based on the state of the client and send out 1 byte. I guess this is going to be the only real way to do it...
    i mean it works but it puts more processing load on the clients but can't say no to just sending 1 byte for the server on animations so meh, pros/cons lol.
     
  4. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,006
    Animator.StringToHash is just a hashing function. It will always return the same hash for a given string. So yes, it should be the same even on different machines. However keep in mind that it is just a hashing function and can have collisions. So in rare cases the function can return the same hash for different input strings. For more informations see this post and my answer at the bottom.

    Note that Shader.PropertyToID works different. It does not necessarily return the same value on different machines. Even on different executions the IDs might not be the same. They are just unique inside one game session.

    However to reduce the required data to be send across a network connection it makes more sense to just use an index into an array of animations. This array should be the same on all machines so the same index will access the same animation everywhere. You probably won't have more than 255 animations on one object so a single byte would most likely be enough.
     
    HaiderBassim04 likes this.
  5. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    That's not necessarily true.

    For example within the .net framework itself the object.GetHashCode can vary from machine to machine and version to version. Or as MSDN phrases it "from domain to domain".

    This is why in the documentation for it Microsoft says:
    https://docs.microsoft.com/en-us/dotnet/api/system.object.gethashcode?view=netcore-3.1

    Now this isn't to say Animator.StringToHash can't be trusted from domain to domain.

    It's just to say that being a hashing function doesn't necessarily guarantee that it can be trusted from domain to domain. Quite the contrary, without knowledge of the hashing algorithm, it's best to err on the side of caution.

    For example, lets say the hashing algorithm xor'd together every char of a string to generate a hash, but one system was bigendian and another littleendian, and when translating the values between systems you didn't account for that. That could be an issue.

    Case in point... Shader.PropertyToID is technically a hash... all a hash is is a function that maps arbitrary size data to a fixed size... usually a numeric value or something of that sort. The index within a collection can technically be a hash since the algorithm takes any known value in the collection and maps it to a fixed sized result (in this case an int, and technically it is a unique hash too). Though usually hashes are more broad than that, often performing bitwise operations across the underlying data. Or in the case of UnityEngine.Object's, it's the id created for it when it was created, it's "Instance ID", which technically means it's unique until you've cycled through all IDs and had to reuse at which point you probably exhausted the instance count of the game or destroyed objects up to that point meaning the previous object with the same id is gone.

    And the fact PropertyToID can vary from machine to machine is proof in itself that hash functions can't necessarily be trusted from domain to domain unless otherwise documented to do as such.

    This is why in the posts you linked we all had already discussed much of this.

    It's also why I personally argued that the lack of documentation on the part of Unity is bad. Because without documentation... than the appropriate interpretation is "do not trust". If I don't know the algorithm being used, and that it's only a hash, I should assume that it's not necessarily unique and that's it's not necessarily persistent between domains.

    Of course in that same thread I did assume that because I interpreted Unity's insistence that it is good to use the hash over the string to carry over to that they ensured uniqueness. This could have been done in many ways while remaining a hash... as I pointed out before where the InstanceID of UnityEngine.Objects are technically unique (for the first gajillion instances). But that was a mistake on my part in trusting Unity (a thing I no longer do)... and as the thread shows we all learned that no, it behaves like a hash that is non-unique. And thus spawned my argument that the documentation is bad (which you don't have to agree with, but is a fair argument none the less).

    Which also leads me to, since they don't say if it persists between domains, well... I won't be surprised when it doesn't persist between domains.
     
    Last edited: Jul 17, 2020