Hey just bought the asset - quick question:
I use matchtarget to align my characters pixelperfect after issuing movement commands (strategy game).
And I saw that the matchtarget is not supported by the Playables API, and therefore not by animancer.
However there was a helper/utils class you created 2 years ago:
is this still the best way to go about it - or is there an updated version?
If so I would use that for my rootbone matching.
I havenât worked on it any more since then. Feel free to give it a go, but unfortunately I donât think the Playables API actually gives us access to enough information to do the proper calculations so it might not be possible to get it working as well as Target Matching within an Animator Controller.
Thanks for the info, I will try!
Follow up question: I am using the Hybrid approach with the HybridAnimancerComponent and I have use case in my game where I change out an overridecontroller with another overridecontroller.
E.g. when the player equips a weapon we change from the unarmed to the sword runtime override controller.
However doing this seems to do nothing the second time i try to exchange the runtimecontroller:
(on start I set _animancer.runtimeAnimatorController to unarmed and when combat starts I set _animancer.runtimeAnimatorController to armed)
TLDR;
How to exchange runtimeAnimatorcontroller dynamically in code (on start and whenever combat starts) with the HybridAnimancerComponent?
P.S. I wanted to ask if there is a way to check if the hybridcomponent is currently playing a animancer animation or just âplaying the controllerâ as both cases will return true when checking _animancer.IsPlaying(). - I read the documentation for hybrid but it didnât seem to contain any info in regards to that - if there is more info somewhere else feel free to link it to me!
Thatâs an unfortunate side effect of the Animancer Events rework in Animancer v8.0, specifically this bit since HybridAnimancerComponent uses a ControllerTransition:
The transition doesnât compare anything about the contents of the state to its own fields, so you would need to do something like this to make it create new states based on the controller:
ControllerTransition transition = _Animancer.Controller;
if (transition.Controller != newController)
{
// Change the old state's key to its controller so we can get it back later.
if (transition.BaseState != null)
transition.BaseState.Key = transition.Controller;
// If there was already a state for the new controller, give it the transition as its key.
if (_Animancer.States.TryGet(newController, out AnimancerState state))
state.Key = transition;
// If there wasn't already a state, the transition needs it to be able to create the state.
transition.Controller = newController;
}
// Now we can play the ControllerTransition and it will use or create the correct state.
_Animancer.PlayController();
Thatâs a lot more effort than I would like to achieve something relatively simple so Iâve made a note in my To Do list to try to find a better way for the next version of Animancer or at least include it as a method.
Try going to StringAsset.GetHashCode and changing it to return base.GetHashCode(); instead of using the Name. I canât think of any specific issues that would cause so it might be fine, but it could just get past that error and still cause the same problem in some other part of their process that ends up trying to access the Name.
The issue is as it says, âGetName is not allowed to be called during serializationâ and for whatever reason it looks like Odin is serializing a reference to the StringAsset in UndoTrackerStateContainer. Thatâs not a problem when StringAssets are used for their intended purposes so I never encountered it while implementing the system, but it seems to be unavoidable if you try to use them in an OnAfterDeserialize method.
Unfortunately, there might not be anything that can be done to properly fix it in the current system. Trying to store the name in a serialized field would be unreliable because thereâs no way to guarantee that the StringAsset gets deserialized first. Trying to return some sort of dummy value also wouldnât work because it would break anything expecting the real value and Unity doesnât even seem to have a way for us to check if itâs currently âduring serializationâ or not.
Iâve been trying to come up with an alternative but none of the options seem to be good ones. It would be a shame to need to go back to raw strings for event names and stuff just to fix issues that donât happen during normal usage.
Iâd also recommend reporting the issue to the Odin developers. They might have a system for excluding specific types from the UndoTrackerStateContainer system which would at least fix the issue for this case.
Hello, Iâve been using a modified version of the LayeredAnimationManager and have been running into some issues occasionally when trying to play animations or chain them together based on end events.
In this image Iâm playing a âcowerâ emote as an action on the action layer. Firstly, I play the transition from Idle to Cower, which will then play Cower after it completes.
The problem Iâm seeing is that Idle doesnât seem to end, nor the transition clip. I was under the assumption that calling Play on a layer would automatically stop any current clip. Itâs looking like thatâs not the case? Should I be manually stopping or crossfading?
Yeah, layer.Play will stop or fade out everything else on that layer so as long as youâre not directly manipulating individual states, it shouldnât be possible to end up with the total Weight of states above 1.
That script doesnât appear to be doing anything with the individual state weights or fading so it should be fine. Do you have any other scripts directly manipulating them?
Hmm, I took another look through the rest of my code and I do not manipulate state weight directly.
I did find a section where I call a fadeout on the Face and Action layers and then call play on the base layer. Since Actionâs target weight should be zero at the time because of my fade, Iâm pretty sure itâs just playing the new clip on base while the other 2 layers are fading.
I was curious though, is there a functional difference in calling Stop on the AnimancerComponent vs. calling Stop directly on a layer? Wondering if that could cause an issue depending on when it happens.
@Kybernetik So we are still on v7.4 and canât upgrade due to an upcoming deadline. Weâre having trouble with the conflicts Animancer has with Animation Rigging. Is there any chance you could share with me the code for the PlayableOutputRefresher? Or perhaps the code for the AnimancerPlayable constructor that allows me to pass the RigBuilderâs PlayableGraph? I tried to reverse engineer it but Iâve had no luck.
Thanks so much! So unfortunately this doesnât seem to solve our problem. The issue Iâm having is that the bone transforms are all wrong when we Evaluate() the graph manually with a RigBuilder enabled. It sounds like the PlayableOutputRefresher only solves Rig weights resetting? Do I also need to do the Paused Graph portion of your doc to address this? I was under the impression these were 2 different ways to solve the same problem.
Theyâre entirely separate problems. The Paused Graph section is for if you need to manually evaluate a paused graph and the refresher is for if your rig values are resetting. If you have both problems then youâll need both solutions.