Search Unity

Animancer - Less Animator Controller, More Animator Control

Discussion in 'Assets and Asset Store' started by Kybernetik, Oct 8, 2018.

  1. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    Setting the _Animancer.Controller doesn't automatically play it so its State doesn't exist and therefore can't have its parameters set.

    Calling _Animancer.PlayController(); after setting it should solve the problem.
     
  2. Skotrap7

    Skotrap7

    Joined:
    May 24, 2018
    Posts:
    125
    I think I solved my own problem. Continuing to play around with different ways to set the paramters on the animator/animancer components, I tried doing this in my Motion Controller:

    Code (CSharp):
    1.  
    2. // Grab the Default and the Current controller from the animancer component in awake
    3. private void Awake()
    4. {
    5.     _Animancer = GetComponent<HybridAnimancerComponent>();
    6.     _Current = _Default = _Animancer.Controller;
    7. }
    8.  
    Then when changing the controllers for the override controllers, I do:

    Code (CSharp):
    1. _Current = _Override;
    2. _Animancer.Play(_Current);
    And to change back:

    Code (CSharp):
    1. _Current = _Default;
    2. _Animancer.Play(_Current);
    Then to set parameters I do
    Code (CSharp):
    1. _Current.State.SetFloat(SPEED, x);
    Seems to be working just fine. Let me know if you can think of any issues in doing it this way. I'll be continuing to replace my animator controllers with Animancer stuff now. :)
     
  3. Skotrap7

    Skotrap7

    Joined:
    May 24, 2018
    Posts:
    125
    Thanks, Unity's forums didn't show your reply to me (even after refreshing the page a few times), would you mind looking at my latest reply and see what I'm doing and let me know if that is good/bad/ugly?

    Thanks!
     
  4. Todiloo

    Todiloo

    Joined:
    Jan 22, 2016
    Posts:
    53
    Trying to FSM implementation. How should one manage conditional transitions. So for instance if I have

    StandingState
    Crouching
    Crawling

    If I was crawling and I press crouch I first want to play CrawlToCrouchAnimationn
    If I was Standing and I press crouch I first want to play StandToCrouchAnimation

    And same goes for leaving a state. Say I want to make an attack but I sort of need to finishing "stopping" in a movement state.
     
  5. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    @Skotrap7 Your way needs an extra field in your script (_Current) but overall the effect will be practically identical so just go with whichever approach you like the look of.

    @Todiloo You could try something similar to the Priority system in the Interrupt Management example, but with an enum called Posture or Stance (with values like Stand, Crouch, Crawl, etc.). Then in OnEnterState you can get the previous state's posture and use it to decide which animation you want to play.
     
  6. Rossakis

    Rossakis

    Joined:
    Sep 5, 2018
    Posts:
    6
    Hi @Kybernetik ! I ran into a bit of a problem when making some animation scripts for my 2D platformer game.

    So, I have two separate animation scripts attached to my Player gameobject, which are MovementAnimation and CombatAnimation respectively.

    And what I want to understand is, if I type Animancer.Play(clip) in both of the scripts, who will have the priority between the animations of the scripts? That is, without taking into accord 'if' statements and whatnot inside of the scripts.How would the Animancer handle this?

    I'm just trying to understand this as without Unity's graphical state machine, it became a little harder for me to understand how the transition between many different types of Player animations would work.

    PS. One more question. How can I see whether an animation has finished through code? Like, is there a bool method that tells us for example that an animation "Walk" is still playing, or that it is finished ?
     
    Last edited: Apr 20, 2022
  7. Todiloo

    Todiloo

    Joined:
    Jan 22, 2016
    Posts:
    53
    I haven't done 2D animations but I assume it is the same as the 3D variants. Your second Play will "overwrite" the old one depending on what transition/fade you have setup which for 2D I assume is instancen (since animation blending this one doesn¨t make sense). Or at least for the same Layer .

    To see if an animation is finished you can use the reference State you get when you Animancer.Play(clip) . It has bool "IsStopped" .

    Or, to react to a finished animation just use the
    state.Events.OnEnd = (your method here) .
     
  8. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    @Rossakis Calling Play from multiple scripts is just like calling Play multiple times from the same script. They will run one after the other and whichever Play call is last will be the state Animancer ends up in.

    End Events are usually the best way to react to the end of an animation.

    Also, a slight correction to what @Todiloo said: states have an IsPlaying property, but it doesn't tell you if they have reached their end. States continue playing after their end and their time continues increasing even if they are only showing a static pose for a non-looping animation. So if you want to check when it is done that way, you can just check if the state's NormalizedTime >= 1 (or state.Time >= state.Length).
     
  9. GamePowerNetwork

    GamePowerNetwork

    Joined:
    Sep 23, 2012
    Posts:
    257
    Hello I'm having an issue with OnEnd event. I'm using Unity 2021 LTS version.

    I have my animation clip set to not loop. The OnEnd event fires, then it keeps firing non-stop in a loop.
     
  10. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    GamePowerNetwork likes this.
  11. GamePowerNetwork

    GamePowerNetwork

    Joined:
    Sep 23, 2012
    Posts:
    257
    Wow thanks for the quick response. I actually came back to edit my post and say I saw the documentation about "OnEnd" lol.

    At the very least, thanks for being so helpful!
     
  12. Todiloo

    Todiloo

    Joined:
    Jan 22, 2016
    Posts:
    53
    Anyone using Animancer and preferable the State Machine for use in a multiplayer game, any tips on how to synchronize which state is suppose to play, and of cause most importantly which animation (and that animations time/float value)?
     
  13. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    Willbkool_FPCS likes this.
  14. Rusted_Games

    Rusted_Games

    Joined:
    Aug 29, 2010
    Posts:
    135
    Hi @Todiloo, take a loot at the code snippet I put together prototyping a simple integration using PUN 2
    Animancer - Less Animator Controller, More Animator Control
    I'm working in my channel on a video tutorial using Animancer, Entitas but will switch PUN2 for Fusion or FishNet probably
     
    Todiloo likes this.
  15. Todiloo

    Todiloo

    Joined:
    Jan 22, 2016
    Posts:
    53
    Thank you. But should the clients also do the state actions?(Haven't used PUN 2 myself only mirror so not 100% sure about the syntax). I was thinking that the server has a NetworkBrain for each Player. And players sends commands and the NetworkBrain executes states based on those (and game info), and the states update Variables and pushed which animatinos to play to the clients ?
     
  16. Rusted_Games

    Rusted_Games

    Joined:
    Aug 29, 2010
    Posts:
    135
    The clients (proxies) are receiving which animation state to play by sending the state key, they don't receive input directly, game object movement of the proxies, is handled in my case using the Photon Transform Sync
     
  17. Todiloo

    Todiloo

    Joined:
    Jan 22, 2016
    Posts:
    53
    So your states here are purely animations?

    I have been eyeing Behaviour Tree(Node Canvas) to drive the AI and that might work well. Just SendRPC and then then just run the appropriate animation state. Multiplayer is ... hard, really hard.
     
    Rusted_Games likes this.
  18. Rusted_Games

    Rusted_Games

    Joined:
    Aug 29, 2010
    Posts:
    135
    Yes it is ;)
     
    Todiloo likes this.
  19. One_Learning_Man

    One_Learning_Man

    Joined:
    Sep 30, 2021
    Posts:
    81
    Hello Kyber! I got two small questions. In your 3d game kit example, character.cs stores state references like the following:

    Code (CSharp):
    1.         [SerializeField]
    2.         private CharacterState _Idle;
    3.         public CharacterState Idle => _Idle;
    4.  
    5.         [SerializeField]
    6.         private CharacterState _Locomotion;
    7.         public CharacterState Locomotion => _Locomotion;
    8.  
    9.         [SerializeField]
    10.         private AirborneState _Airborne;
    11.         public AirborneState Airborne => _Airborne;
    \

    Is there a functional difference between declaring it as a CharacterState type vs. the more specific AirborneState? I don't believe there is but just wanted to make sure.

    In a previous section, you mentioned advantages and disadvantages to storing stats in a central stat class or keep it isolated to its individual state. It seems like you went with a mix of both:

    upload_2022-4-22_0-7-10.png
    upload_2022-4-22_0-7-43.png

    What's the rationale behind this? Looking at it, is your design that the CharacterStat is just generic stuff while you saved specific stats to the specific states? I'm thinking about storing every stat possible into one class.

    Thanks!
     

    Attached Files:

    Todiloo likes this.
  20. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    KeyboardAndMouseBrain is calling Character.Airborne.TryJump and CancelJump which it couldn't do if that property was a base CharacterState.

    But nothing actually needs to care which specific type is being used for Idle or Locomotion. An enemy would have a Character component as well and their Locomotion state probably won't have quick turn animations and might just have a single animation instead of a Mixer so it could have a SimpleLocomotionState without all that unnecessary stuff and you wouldn't need to make any changes to the Character class. Or you could have a tree enemy that can't move so you just assign its IdleState to both Creature.Idle and Creature.Locomotion.

    I'm thinking I'll change it to make Character.Airborne a CharacterState and give KeyboardAndMouseBrain its own Jump field which happens to be an AirborneState and references the same component.

    The fields in the CharacterStats class are only used by the Character script, not by a particular state. The decision to split them into a separate class was entirely arbitrary, I just felt it was a good idea because there are quite a few other fields already in Character. Now that I look at it again, I'm considering making a CharacterMovement script for the stats and the logic that uses them to keep all that separate from the states and state machine in Character.
     
    Last edited: Apr 22, 2022
    One_Learning_Man likes this.
  21. Adunato

    Adunato

    Joined:
    Nov 3, 2018
    Posts:
    28
    Hello! Just started to integrate Animancer into my project and so far looking very promising! I'm trying to set up a callback on an end event (e.g.
    Code (CSharp):
    1. _animationState.Events.OnEnd = OnAnimationEnd
    ) and realised that the event is called each frame after the animation is ended (as per documentation).

    How does this work on looping animations, does it keep sending events after the first loop has ended? Ideally, I'd like a way to get one event for each animation loop.

    Thanks!
     
  22. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
  23. One_Learning_Man

    One_Learning_Man

    Joined:
    Sep 30, 2021
    Posts:
    81
    Very informative! Design patterns and good architecture is always tricky so I appreciate your documentations and conversations where you explain why you put something somewhere and pros and cons. It's been extremely insightful.

    So after reflecting on this issue, I think I'm going to back off from having all stats sit in one spot but bundle it with the logic like you mentioned. Here is my strategy:

    upload_2022-4-22_20-43-42.png

    I think this is a clean implementation. I wasn't too sure if I had to look into a state or the character to find the stat I needed before! What are your thoughts? Any glaring problems?

    I'm planning to manage my NPC AI through Behaviour Trees. I'm wondering if that's going to be at the AI Input level or the Brain level...

    As a side note, your word choice in calling it "Brain" grew on me. "InputManager" was one that made it easy to understand but it didn't quite encapsulate what it does. "StateManager" was an alternative but now I believe that "Brain" is the right choice. I know you're reworking some parts of your tutorial, one suggestion would be adding in these architecture diagrams, how things fit together. With your help and documentation, I've learned a lot and I think some figures and diagrams would be a great addition especially in the state machine section.

    I normally use (https://app.diagrams.net/) - but I'm sure you have better tools and strategies in mind.
     
    Last edited: Apr 23, 2022
  24. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    That looks mostly reasonable.
    • With so many Jump fields, I'd probably put them in a JumpStats class, even if you access them via Character.MovementStats.Jump...
    • I wouldn't consider trees or pots as part of this system at all. Even if they have states and animations, trying to squeeze them into the Character system is likely not worth the effort.
    • My Platformer Game Kit has a very simple Behaviour Tree implementation for its enemies which you might want to take a look at.
    I have a general To Do task for explaining more about why I've made certain decisions in the examples rather than just how to do things. Adding architecture diagrams will probably help in some places too.
     
  25. Adunato

    Adunato

    Joined:
    Nov 3, 2018
    Posts:
    28
    Thanks! So to summarise this is what I get.

    With End Events, Animancer will send events every frame after the end of the first loop, making it not suitable for my requirement (one event at the end of each loop).

    With regular Animancer Events, I can detect the end of each loop, but I need to do some delta comparison of the
    AnimancerPlayable.Current.FrameID as otherwise, I will get multiple events in successive frames (see below).

    Happy to use the regular events for this use case, but is there a way to avoid FrameID delta comparison? Not a big issue, just trying to keep the code streamlined. Originally I was using 0.99f as normalizedTime input and assumed this caused a rounding issue, but even using AnimancerEvent.AlmostOne I still get events on consecutive frames.

    End Event implementation

    Code (CSharp):
    1. //setting the event
    2. _animationState.Events.OnEnd = OnAnimationEnd;
    3.  
    4. private void OnAnimationEnd()
    5. {
    6. // received every frame after end of first loop
    7. }
    Regular Animance Events implementation

    Code (CSharp):
    1. //setting the event
    2. _animationState.Events.Add(new AnimancerEvent(AnimancerEvent.AlmostOne, OnAnimationEnd));
    3.  
    4. private void OnAnimationEnd()
    5. {
    6. // received after end of each loop
    7. //check that FrameID delta with previous
    8. if (_lastEventFrameID != 0 && AnimancerPlayable.Current.FrameID - _lastEventFrameID < FrameMinDelta) return;
    9. [...] event logic [...]
    10. }
     
  26. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    That shouldn't be necessary. A regular Animancer Event at AlmostOne should trigger only once each time the animation loops past its end.

    Are you sure you aren't adding the event multiple times or playing the animation really fast or something?
     
  27. Adunato

    Adunato

    Joined:
    Nov 3, 2018
    Posts:
    28
    Hello, thanks for the quick response.

    I just started using this, so I may be well off here, so apologies in advance if I'm talking nonsense :), but I do think there's a float rounding issue with AnimancerEvent.AlmostOne and how it's used in AnimancerState.EventDispatcher.

    When GetLoopDelta compares the previous / current times the difference between 2 and AnimancerEvent.AlmostOne ends up being 1, which results in previousTime == previousLoopCount.

    So IMHO either AnimancerEvent.AlmostOne needs to have a double precision or (more easily) it needs to lose one decimal point of precision, i.e. 2 - 0.9999994f = 1.0000006, bringing it to 7 digits rather than 8. Just tested this on my setup and it solves the issue in this instance.

    upload_2022-4-23_8-45-33.png


    upload_2022-4-23_8-43-3.png

    In answer to your question, the animation is pretty standard in terms of speed and duration, and the event is only set once.
     

    Attached Files:

  28. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    Changing that value doesn't solve the problem, just slightly shifts the values where it occurs.

    The actual problem seems to be a bug in GetLoopDelta. The previous time needs to be inclusive so that playing from 0 will trigger an event at 0 which means that the next time needs to be exclusive so that landing exactly on the event time won't trigger the event twice (once for the frame it reaches that time then again when it moves off that time).

    I've made some new unit tests and posted a fix here which satisfies them.

    If those are the actual values you're getting, then your animation is playing fast enough to finish one loop every frame which explains why you'd see the event getting triggered every frame. Otherwise I'm not sure what else could cause it so if you want to send a minimal reproduction project to animancer@kybernetik.com.au I'd be happy to take a look at it.
     
  29. Adunato

    Adunato

    Joined:
    Nov 3, 2018
    Posts:
    28
    That was a quite impressive hot fix :) Just tested and now my scenario works with AnimancerEvent.AlmostOne. The events are spaced by 600 frames, so not the case of a super fast loop animation, not sure what values suggested that in my screenshot, but for the time being it doesn't matter as it works for me and more importantly you're happy with the fix.

    Thanks again for the quick support, not taken for granted.
     
  30. Todiloo

    Todiloo

    Joined:
    Jan 22, 2016
    Posts:
    53
    Very interesting read up. I am at analysis paralysis when it comes to game AI. My take is to create a Finite-state machine that moves between states based on transitions which sort of acts like the glue for the AI.

    Hopefully the only thing that difference between a NPC/monster and the player character is that the player controller controls the transitions, but the states themselves are identical.

    So for example, if the monster is idle, it has a transition (See Player) which transitions the monster to Attack(which includes chase, then use sword).

    For the player controller, the mouse presses the monster. Which takes the player from idle-state to attack(also chase, then sword).

    Does that makes sense?
     
  31. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    FSMs are usable for AI, but most people find that Behaviour Trees are much better for the job. As I mentioned in an earlier post, my Platformer Game Kit has a very simple Behaviour Tree implementation for its enemies.
     
  32. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    Most of the complexity in the Layers example comes from the need to allow the action animation to be played on either layer depending on whether the character is moving.

    If you just want to play a layered animation all you need is something like this:
    Code (CSharp):
    1. public void PlayLayeredAnimation(AnimationClip clip, float fadeDuration)
    2. {
    3.     var state = _Animancer.Layers[ActionLayer].Play(clip, fadeDuration);
    4.     state.Events.OnEnd = () => state.Layer.StartFade(0, fadeDuration);
    5. }
     
  33. KimZigbang

    KimZigbang

    Joined:
    Apr 24, 2020
    Posts:
    9
    Hello~
    I have some problems
    Sometimes AnimationState.Time and Raw Time are infinity.

    So Exception in (weighted Normalized Time.IsFinite() )

    I need Your Help


    Clip Data
    upload_2022-4-28_12-36-47.png
    Mixer
    upload_2022-4-28_12-37-15.png
     

    Attached Files:

  34. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    I can't see anything wrong in those screenshots. If you want to send a minimal reproduction project to animancer@kybernetik.com.au I'd be happy to take a look at it for you.
     
  35. Prith1

    Prith1

    Joined:
    Mar 26, 2020
    Posts:
    6
    How can I use a state driven cinemachine camera with animancer pro? I want to use different virtual cameras based on the state, how can I do this?
     
  36. Todiloo

    Todiloo

    Joined:
    Jan 22, 2016
    Posts:
    53
    Is there a way to get the current state type currently playing?

    I have a LinearTransitionState.UnShsred which blends between idle and running through a parameter. Additionally the Character can play attack/heal etc. Plus some layered animations (a hit animation only effects upper body). I wish to synchronize these through the network.

    For any animation that doesn't have a parameter that is no problem. However the idle->run wants navmesh speed which only the server knows about. Do I have to have a reference to my Linearstransitionstate.unshared directly or can I conveniently get that from the Animancer component?

    Or other tips för sort of merging the animation handling?
     
  37. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    @BorBaw Can you explain your question in more detail? I've never used Cinemachine, but if you know how to set the camera then doing it at the same time you tell Animancer to play an animation should be straightforward so I'm not really sure what you're asking about.

    @Todiloo
    if (animancerComponent.States.Current is LinearMixerState mixer) mixer.Parameter ...
    should do it if you only care about the current state. Or you could use
    animancerComponent.States.TryGet(transition, out var state)
    if you need it when it's not the current state.
     
    Todiloo likes this.
  38. Doomchecker

    Doomchecker

    Joined:
    Apr 5, 2021
    Posts:
    109
    Hi there,
    is there a way I can interrupt a mixer by itself?

    So what I mean is when the mixer is half through an animation, restarting it with fading out from the half completed animation into a restart from the beginning.
     
  39. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    Yes, but not easily.

    If you made the mixer from a transition you can call transition.CreateState to make another copy of its state, but then you have two mixers you need to control the parameter of and it's up to you to manage which one you want to play each time.
     
    Doomchecker likes this.
  40. h_kishi

    h_kishi

    Joined:
    Jun 9, 2015
    Posts:
    5
    Hello.
    I am trying Animancer Lite on Unity 2021.3.1f1 (LTS) to consider purchasing Animancer Pro.
    Using WebGL as the platform and "Examples/01 Basics/01 Quick Play/Quick Play,unity", I executed "Build & Run" and got the attached error on the browser.
    The same error occurred when I used other Examples scenes.

    Is this a problem that can be solved by adopting Animancer Pro?
    Or is there any way to work around this issue?


    The full error message on the JavaScript console is here:
    ---
    exception thrown: RuntimeError: null function or function signature mismatch,RuntimeError: null function or function signature mismatch
    at il2cpp::vm::MetadataCache::ExecuteModuleInitializers() (http://localhost:49532/Build/Build.wasm:wasm-function[1321]:0x9239d)
    at dynCall_v (http://localhost:49532/Build/Build.wasm:wasm-function[52327]:0xe9917e)
    at http://localhost:49532/Build/Build.framework.js:1035:20
    at invoke_v (http://localhost:49532/Build/Build.framework.js:14056:3)
    at main (http://localhost:49532/Build/Build.wasm:wasm-function[47559]:0xc8d61e)
    at http://localhost:49532/Build/Build.framework.js:1035:20
    at callMain (http://localhost:49532/Build/Build.framework.js:15909:13)
    at doRun (http://localhost:49532/Build/Build.framework.js:15952:21)
    at run (http://localhost:49532/Build/Build.framework.js:15964:3)
    at runCaller (http://localhost:49532/Build/Build.framework.js:15892:18)
    at Object.removeRunDependency (http://localhost:49532/Build/Build.framework.js:990:4)
    at http://localhost:49532/Build/Build.framework.js:144:12
    at doCallback (http://localhost:49532/Build/Build.framework.js:4483:11)
    at done (http://localhost:49532/Build/Build.framework.js:4494:5)
    at IDBTransaction.transaction.oncomplete (http://localhost:49532/Build/Build.framework.js:3850:5)
    printErr @ Build.loader.js:70
     

    Attached Files:

  41. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    I just tested it and can confirm that Animancer Pro seems to work fine in Web GL.

    There's probably nothing I can do to fix Animancer Lite to work in Web GL though. I suspect that it's caused by the code obfuscation used on the Lite DLLs, but I have no idea how to even begin to debug or fix it.
     
  42. h_kishi

    h_kishi

    Joined:
    Jun 9, 2015
    Posts:
    5
    Thanks for the confirmation.
    I will purchase Animancer Pro since it seems to work fine in WebGL.
     
  43. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    Hey everyone, just a heads up if you try to use Animancer Pro in Unity 2022.1 you'll get a compiler warning about AnimationPlayableUtilities.Play being deprecated. Here's a workaround for now, but I'll report a Unity bug and hope they fix it on their end.

    Animancer v7.3 is still on track to release next month. It's functionally ready to go but I'm still working on the examples, so if anyone wants to try it out early just let me know (send me your Invoice Number if you want Animancer Pro).

    Most of my work since I last mentioned it has been improving the examples and their documentation, but I also came up with a clean(ish) way of making state machines serializable so they can show the Current State in the Inspector without needing any custom editor code:

    serialized-fsm.gif

    I've also taken the suggestion from @One_Learning_Man and started adding code architecture diagrams like this to all the examples:

    architecture.png

    architecture.png
     
  44. One_Learning_Man

    One_Learning_Man

    Joined:
    Sep 30, 2021
    Posts:
    81
    @Kybernetik Very awesome updates!

    "AnimationPlayableUtilities.Play being deprecated" - If Animancer is based on the playables API, does this mean Animancer will no longer work with future Unity versions or is this just a visual bug?

    "I also came up with a clean(ish) way of making state machines serializable so they can show the Current State in the Inspector without needing any custom editor code" - This is fantastic.

    What are your thoughts on left to right diagrams vs top to bottom layout style? (I'm a fan of a top to bottom + encapsulation container style but it's just preference really lol :oops:).

    FSM.png

    How come you're using the word "transition" to refer to animation clips? That's actually new info for me so I'm curious. I normally think of transition as the sequence between changing animations. A transitions to B for example.
     
    Last edited: May 12, 2022
  45. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    No, worst case scenario they don't un-deprecate it and don't provide alternative so once the deprecated method actually stops working Animancer would lose the ability to use Animate Physics mode but everything else would continue working fine. But I don't think that's too likely.

    I like left to right because that's the direction we read in English and computer monitors are wider in that direction. Also, because the images are larger than necessary, having them wider means they hit the edge of the page and start scaling down earlier so you can keep the whole thing on screen at once without scrolling (your image is in between two of my scroll notches so if I don't drag the scroll bar exactly or zoom out I can't see the whole thing at once).

    The fields are actually Transitions so really they should look like the Simple Character diagram above it (Script has a Transition and the Transition is what actually references the AnimationClip). But by the point you get to the Characters example you should already understand that relationship so I left it out to simplify the diagram a bit since that's not the focus any more (like how I left out the Animancer Component -> Animator reference as well). Though since I put clip names in there, the group should be called Animation Clips rather than Transitions.
     
    One_Learning_Man likes this.
  46. One_Learning_Man

    One_Learning_Man

    Joined:
    Sep 30, 2021
    Posts:
    81
    Awesome, hope to go back and revisit your tutorials.

    One last thing from me. I learned my coding convention from your documentation: https://kybernetik.com.au/cs-unity/docs/coding-standard/naming

    But just recently, I found that Microsoft has it slightly different. https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions

    Private fields: _camelCase
    Public field: PascalCase
    etc. etc.

    It's really not that big of a deal and everyone has their preference anyhow but what are your thoughts? Do you plan on changing your page or keeping it as is?
     
  47. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    The company I work at uses publicField, _privateField, Property/Method/Etc.

    But I like the look of PascalCase better than camelCase so _PrivateField is just another place I can use the one I like.

    One thing I am considering changing is the
    /**********/
    lines used as Member Separators. But so far I've only ever had one person bring it up (they didn't like it) and I like them for as a softer way of grouping things than #regions so I probably won't remove them unless more people bring it up.

    For example, here I have a bunch of individual fields then a const, serialized field, and property all relating to each other so I like being able to group them.

    upload_2022-5-13_11-10-44.png
     
    Willbkool_FPCS likes this.
  48. One_Learning_Man

    One_Learning_Man

    Joined:
    Sep 30, 2021
    Posts:
    81
    What happens if you use a ClipTransition and also have values hardcoded in the script? Which values take precedence?
     
  49. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    If you specify a fade duration in the Play call, that takes precedence over the value in the transition.
     
    One_Learning_Man likes this.
  50. Todiloo

    Todiloo

    Joined:
    Jan 22, 2016
    Posts:
    53
    upload_2022-5-16_7-38-9.png
    I get 2 states for the same animation. What could be the reason for this. The code where I initiate is pretty straight forward:



    Code (CSharp):
    1.  
    2.         public AnimancerState PlayAttackAnimation()
    3.         {
    4.             attackState = animancer.Play(attackAnimation, 0.25f, FadeMode.FromStart);
    5.             attackState.Time = 0;
    6.             return attackState;
    7.         }
    8.  
    After this code The called of said function just sets an OnEnd event:
    Code (CSharp):
    1.     void OnAnimationEnd()
    2.         {
    3.             state.Events.OnEnd = null;
    4.             canAttackAgain = true;
    5.         }
    The reason it seem to be a problem is that the character sometimes gets into a weird position, like 90 degree turned or something. but only for 1 frame.

    I also see this behaviour first time during a transition when I try out a transition in transition preview (not though it seem to go to time 1.0 when the actual end is 1.6, however in the game it goes to 1.6, a full animation but still a 1 frame jitter)

    This is the jitter in the game: (after third hit, its not as noticeable as in game due to framerate of recording)
    Unity_7uQ2jPAHuA.gif

    (I have tested with totally different attack animations, same result)
     

    Attached Files:

    Last edited: May 16, 2022