Search Unity

Very poor NetworkAnimator performance

Discussion in 'Multiplayer' started by Xuzon, Jan 19, 2017.

  1. Xuzon

    Xuzon

    Joined:
    Mar 21, 2014
    Posts:
    83
    Hello!!
    My Team and I are in the optimization stage of our game and I've just realized a very very poor performance in the NetworkAnimator.

    It seems like every 5 ~ 6 frames it is allocating a lot of memory and using a lot of CPU from 1.3 to more than 2ms!!
    In this test we only have one NetworkAnimator so I don't know how the hell is so bad at performance, We already have to implement our solution for the NetworkTransform because unity's built in doesn't interpolate nor predict any movement.

    I don't know if this is happening to anyone but if anyone has fixed this or any info would be helpful.

    I'm attaching three images, first on a spike, second next frame of spike, third next spike




     
  2. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    I've noticed some things (like AudioSource) are massive CPU hogs in the editor, but not with the runtime executable. The profile gives you false information sometime.

    What I'd suggest is for both the editor, and the compiled executable, create as many objects as you can until the CPU starts to slow down. Then compare numbers.

    For (for example) it took like 100 AudioSources to slow down the framerate in the editor, but with the executable it could handle thousands. This will tell you if the ms processing time for the NetworkAnimator is "real" or fake (something to do with the editor).

    Either way I'd bug report. But if it's fake you can ignore it because it won't affect your program (only cause problems for you in editor...)
     
  3. Xuzon

    Xuzon

    Joined:
    Mar 21, 2014
    Posts:
    83
    That was a build profiling XD wich in build is pretty accurate I've been optimizing this week with that profiler and I optimize from 90 fps to 220 fps in the very low graphic settings, but that network animator spikes are there, I will fill a bug report then

    EDIT:
    I've just submitted the bug report, lets see what unity thinks
     
    Last edited: Jan 21, 2017
    Zullar likes this.
  4. voncarp

    voncarp

    Joined:
    Jan 3, 2012
    Posts:
    187
    I've used a number of network libraries that don't have network animators. Wouldn't it be simpler to just write your own functionality when you need the animations to work? For instance, just send a jump boolean when you need to jump. Or locally on all clients: If !grounded then animator.SetBool("jump", true).

    Maybe a custom solution could help alleviate those spikes.
     
  5. MaDDoX

    MaDDoX

    Joined:
    Nov 10, 2009
    Posts:
    764
    I don't work for them or anything, but have you considered Photon Bolt? It deals with both prediction and animator network syncing beautifully from what I've tested.
     
  6. Xuzon

    Xuzon

    Joined:
    Mar 21, 2014
    Posts:
    83
    Yeap, is the next thing we are planning XD but is not our first prioritie now, but if it don't get fixed in a few weeks I'll implement my own solution like I did for the network transform XD

    I know Bolt, It haves some things that we like but I like doing things by code, not setting up with a GUI a keyboard input does X etc.. and we already have all the project in UNET and translate to Bolt is a real real pain
     
  7. moco2k

    moco2k

    Joined:
    Apr 29, 2015
    Posts:
    294
    Agreed. A custom solution also has another benefit: you have full control over the implementation and thus can implement proper measures to keep consumed network bandwidth/traffic as low as possible so that you only sync information when really needed.
     
  8. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    Agreed. What I did to make a custom network animator was relatively simple because my animations are more or less a state machine with no fancy blending or anything. I essentially have a SyncVar that is the animation state (one for each animation layer), and then any float type parameters are also synced. This might work for you if your animations are simple.

    Have you looked on BitBucket to see their NetworkAnimator code? Any idea what could be consuming all the CPU?
     
  9. Xuzon

    Xuzon

    Joined:
    Mar 21, 2014
    Posts:
    83
    I use the unity3d animator (state machine, layers, and parameters) so I've thought that the Network Animator would fit and it does its job, but that cpu spikes are hell, so I'm thinking in a system where I can send only the parameters I change and the current state.

    I'm looking into it right now, I didn't remember that they got their code in bit bucket XD
     
  10. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    If you do decide to code it yourself just sync the integer state full hash for each layer (it's important it's the full hash including layerName, not just the stateName's hash if you have multiple layers)

    Code (csharp):
    1.  
    2. int stateHashFull = Animator.StringToHash(layerName + "." + stateName)
    3.  
    So what I do is
    0: Create a enum/key for each state during startup. This contains the state hash (and could contain other info like crossfade time, etc.)
    1: Scan the animator to figure out how many animator layers there are
    2: Create a SyncVar for each layer. This could be the int fullStateHash, or possibly an index to your state enum/key.
    3: Also create SyncVars for each animator parameter (like floats)
    4: When a state is changed (hook is received) I crossfade 0.1s to the new state.

    This works for me. It's kind of cool if a character gets frozen in the middle of the sword swing then it will also freeze it on the client mid-swing. Then when they thaw out the sword swing will resume. Late connecting players will get the correct state, but the animation will play from the beginning. It also gets around this bug
    https://forum.unity3d.com/threads/networkanimator-multiple-animator-controller-layers-broken.402539/

    If you have animator state blending or crossfades that vary then you'll have to make it more complicated than this. It just depends what you are trying to do.
     
    Last edited: Jan 23, 2017
    Xuzon likes this.
  11. Xuzon

    Xuzon

    Joined:
    Mar 21, 2014
    Posts:
    83
    Thanks for the info!! I've been reading the code in bitbucket I don't know why the hell is allocating so much memory, maybe is it because creating a new AnimMessage every fixed update because the allocation is in the FixedUpdate (I tested with client and host and there are spikes in both)
     
  12. Xuzon

    Xuzon

    Joined:
    Mar 21, 2014
    Posts:
    83
    Well, I finally made my own NetworkAnimator, in this solution I don't Play the current state, I'm only syncyng parameters and testing, it seems that works

    With the Unity's default network animator with a list of 22 parameters I hava spikes of 99.4 KB memory allocation in my cpu means 1.2 ms, with my solution the higher spike was 9 kb with 0.25 ms, I have a list of 22 animation parameters.

    I know I can optimize it more but for the first solution is a good optimization XD

    I'm still using the unity network animator for the triggers but is adding only one command and one RPC more to my solution, but I use triggers in 6 scripts or so, so I must refactor first

    https://github.com/Xuzon/PortFolio/blob/master/C#/Unity/MyNetworkAnimator.cs

    I have a custom network movement with prediction and interpolation if anyone wants XD

    https://github.com/Xuzon/PortFolio/blob/master/C#/Unity/NetworkMovement.cs
     
    Last edited: Jan 24, 2017
  13. Likenius

    Likenius

    Joined:
    Nov 22, 2016
    Posts:
    1
    8NeonBitGuy You are a demigod both your solutions solved all my network problems. :)
     
    Xuzon likes this.
  14. Xuzon

    Xuzon

    Joined:
    Mar 21, 2014
    Posts:
    83
    You're welcome XD I still have to improve it more or tweak better the parameters I think

    It's a shame that unity's default works so bad, in performance the animator and doesn't work at all the transform, I don't know why is there a interpolation factor and it never interpolates nor predicts :/
     
  15. yotingo

    yotingo

    Joined:
    Jul 10, 2013
    Posts:
    44
    Hi 8NeonBitGuy - Thanks for posting those scripts they look great!
    I'm trying to use them but believe I must be missing a few steps.

    With the Network Animator I put the script onto my Server Only enemy and none of the animations are synced.

    The Network Movement gave me the same problem I've ran into with other's custom network movement scripts. I set the Target variable to be the transform of the object I'm trying to sync. Once pressing play, the object is instantly snapped to World Space (0, 0, 0).

    If you could take the time to explain what I am missing, that would be amazing!
     
  16. Xuzon

    Xuzon

    Joined:
    Mar 21, 2014
    Posts:
    83
    Sorry, I've been AFK of this forums some weeks XD

    Yes, the behaviour you are telling me is the desired, this is a component of local player authority, if you want to switch to server authority just replace "isLocalPlayer" for "isServer" in the code and you're done
     
  17. yotingo

    yotingo

    Joined:
    Jul 10, 2013
    Posts:
    44
    Thanks for taking the time to respond!

    That worked as expected.
     
  18. Xuzon

    Xuzon

    Joined:
    Mar 21, 2014
    Posts:
    83
    you're welcome, I've discovered in the networtk movement that the prediction never works XD, because the lerping is after the prediction so first apply the LERP and then apply the prediction.

    I don't know what I was thinking when I programmed that XD