If the Start Time isn’t set and the animation was already playing, it will continue from its previous time. Other than that, there isn’t really anything that would change an animation’s time.
I’m building a VR application that records the position of the spheres as you move them and then you can replay the animation. Replaying move the position and rotation of the sphere according to the recorded history. The problem that I have is that I cannot assign a sphere to other bones like the fingers. I’ve tried pragmatically rotating the finger bones, but it seems that ApplyAnimatorIK is locking every bone while the animation is playing and setting the bone rotation does nothing. I can disable ApplyAnimatorIK but then the sphere do not control the movement anymore.
From your answer you suggest another system like Final IK. Can I use that in combo with Animancer to achieve this?
That’s not due to IK, it’s just how all of Unity’s animation systems work. If you want to control the bones of an animated character in a script, you need to set them every LateUpdate which runs after the animation system updates and applies its values to the bones.
Final IK can be used with Animancer (it doesn’t care what animation system you use) and would likely help do what you want, but I’ve never really used it so I can’t be sure.
Also, I just wanted to say that I’m really liking this thing! I made a little Soulslike game in a game jam last weekend, and I took the opportunity to learn to use your state machine system. I had to stare at the docs for a little while until it clicked, but it worked really nicely.
(splitting input into a separate Brain class was also a very good idea)
I’m working on a second, much-less-rushed game now, and it feels a lot easier to write coherent logic! Directly controlling animations from the individual states makes things a lot more predictable.
Looks like the preview thing is a Unity bug. When unpausing a PlayableGraph in Edit Mode, its first update gives it the maximum possible delta time value (0.3333333) which causes a massive jump. I’ve reported it to them.
For your layering issue, you could either have the State A End Event do nothing if Layer 2 is playing something or you could have State B simply set animancer.Layers[0].CurrentState.Events = null; (or just clear its End Event if it might have other important events).
A more complex solution would depend on your specific use case. For example, it might make sense to simply have a separate StateMachine for each layer.
Is there any particular part of the FSM documentation that you found hard to follow? I’d like to make it easier to understand, but it’s hard for me to get into that mindset when I’m so intimately familiar with the whole system.
I’m not sure if any part was abnormally hard to follow – it’s just a fair number of concepts all at once!
Part of it might be unfamiliarity with some of the patterns you use a lot, like serialized private fields and extension-method GetComponent* stuff.
But that’s just a small hiccup.
I’m very glad you chose to do detailed written docs instead of making a bunch of video tutorials. They’re very comprehensive.
re: clearing the events, I see that one solution is to do this:
public override bool OnExitState() {
base.OnExitState();
Entity.Animancer.States[anim].Events = null;
}
This would ensure that no events run once the state exits. I guess this could be overkill for some cases (especially if the animation takes a long time to fade out), but it seems like a good default.
In this case, the state is for a dodge roll, and the “overriding” state is for something like a death animation. So, it makes sense for absolutely nothing to happen once the death state triggers.
That should be up to the DeathState to have its CanExitState return false. You want the death animation to interrupt the previous animation so it doesn’t really make sense to play it on another layer where it would let the previous animation keep playing. Not being able to interrupt death is a logical mechanic so it should be in the logical state machine rather than the animation system. Your approach would work of course, it just doesn’t seem like the right place for that responsibility.
The dodge state exits using ForceSetDefaultState, though, since otherwise it wouldn’t be possible to go from a higher-priority state (like the dodge state) to a lower-priority state (like the idle state).
I suppose I could have each state indicate if it’s “over” and then ignore priority if the state being exited has that flag set to true.
That’s the problem with using force, it’s easy for simple cases but you don’t get enough control for a more complex setup. The Interruptions Example explains a few ways you can set up a proper priority system.
Hi Kybernetik,maybe a bug about rootmotion
i create a prefab via this static factory,it is very simple,and you can ignore GameObjectUtil,it just create prefab and GetOrCreate a Monobehavior
then i set a custom position for the new gameobject
finally i use animancerComponent.Play
but the strange thing is that every time i create model it will show in random position,sometimes it will show at (0,0,0) and some time it will show at the specific position.
I set ApplyRootMotion=true in animator
and if i disable ApplyRootMotion,everything will be correct
and this is the idle clip settings,it will always cause random position whatever setting,only without enable the rootmotion in animator then the position will be right.
Is there a way I can use the same event name more than once? I might have several points in an animation that need to do the same thing, and it’s a little tedious to name them “X 1”, “X 2”, “X 3”, and so forth.
It looks like that, if you have duplicate event names, only the first one gets counted.
I’d like all of the same-named events to trigger the same function.
I guess this might be a place where Animation Events make more sense – in this case, I’m triggering camera shake at certain points in an animation. It’s very generic behavior, so I can just slap a component on the animator’s object that deals with it.
@ununion When you say “random position” do you mean it changes every time or it’s just the same unexpected position every time?
Animations will control the local position of the Animator so if it’s your character’s root object then it will be moved relative to its parent. I generally recommend having the model/Animator as a child of the character’s root and other components and redirecting the root motion (if you want to use root motion).
@chemicalcrux If you’re using Animancer v7.4, there are SetCallbacks/RemoveCallbacks/etc. methods which will affect all events with the specified name.
I mean it will change every time between these two position,one is (0,0,0) in world axis and another is the position set in static factory
the result is fully random,I cannot know which pos will give next time.
the animator and animancer component and character controller is in the root object of my human.