Thats exactly correct. It worked fine after upgrading to 3.32.6.
In the older version, the description was definitely complete. I saved it separately and used the exact same wording in the latest version after upgrading. Word for word the same description.
Hi @nostalgicbear the deepClone issue will be resolved in the next update.
Additionally another reason for animations not playing is that when they are exported with a different hierarchy (e.g. if your script is not on the same object as the AnimatorController) - then the animationclips reference objects with different names and when you assign the new controller the animatorcontroller is currently not able to resolve the correct bindings (aka figure out which animation-track should target which object). A workaround for this would be to add that exports those additional animations to the same object that has the animatorcontroller
@marcel I’ve just updated to the latest release as it had the fix for the deepClone issue which is good progress (thank you for the swift response with that), but Im not really sure what you mean by the above, and as a result I still cant have my animations changed dynamically.
Right now I have an Animator component on an object that gets animated. Also on the object is a script that can referernce two Animator Controller assets:
AnimatorController 1 (Which has path animation 1 as its only state)
AnimatorController 2 (Which has path animation 2 as its only state)
Based on what you said above - my script is on the same object as the AnimatorController that is having is animatorController.runtimeAnimatorController variable updated, and it already has a reference to the second animator controller I want to swap to, but after I assign the new animator controller, the animation doesnt play. The deepClone error is gone but it doesnt play my animation. I get that you are saying its unable to resolve the correct binding, but Im not sure of the best way to work around that.
I dont know what you mean by this sentence " A workaround for this would be to add that exports those additional animations to the same object that has the animatorcontroller". I had planned to only load assets via the SceneSwitcher to only use animations as and when they are needed. If they are all held in memory, I may as well just add all the animations to a single animator controller, but I wanted to avoid any solution like that.
If Im honest, Id rather be able to use the approach I used for a series of games in standard Unity. In my standard Unity project I have tracks being dynamically created on the timeline, but I cant seem to replicate that with the Timeline functionality Needle engine has exposed. In a standard Unity project, I can create a track on the fly with a selected animation with:
animatorToBindTo = objectThatHasMyAnimator.GetComponent<Animator>(); AnimationTrack newTrack= asset.CreateTrack<AnimationTrack>("SomeNewTrack"); TimelineClip newTimelineClip= newTrack.CreateClip(selectedAnimation); //Can set the clip start, end, duration etc playableDir.SetGenericBinding(newTrack, animatorToBindTo);
I can just create a track based on the animation selected, play it, add/remove markers dynamically, and override it for each race. Is it possible to do something like that in Needle engine? I dont seem to be able to create a track via code, assign an animation, and bind it to the timeline.
Hello Nostalgicbear, to create an animation track via code, assign an animation clip to it, and have it play on a timeline, you can utilize the AnimationTrackHandler component. Below is a step-by-step guide and the corresponding code:
Create the AnimationTrackHandler instance.
Set the target property to the Object3D that should be animated.
Create an AnimationMixer and assign it to the mixer property.
Create AnimationClip instances and add them to the clips array.
Bind the animations using the bind function.
Use the evaluate function to update the animations based on the timeline’s current time.
import { Object3D, AnimationMixer, AnimationClip } from "three";
import { AnimationTrackHandler } from "@needle-tools/engine"; // assuming you are using a TypeScript environment
// Step 1: Create the AnimationTrackHandler instance
const animationTrackHandler = new AnimationTrackHandler();
// Step 2: Set the target Object3D
animationTrackHandler.target = new Object3D(); // replace with your actual target
// Step 3: Create an AnimationMixer and assign it
const mixer = new AnimationMixer(animationTrackHandler.target);
animationTrackHandler.mixer = mixer;
// Step 4: Create AnimationClip(s) and add to the clips array
const myClip = AnimationClip.parseAnimation(/* animation data */, animationTrackHandler.target);
animationTrackHandler.clips = [myClip];
// Step 5: Bind the animations
animationTrackHandler.bind();
// Now the AnimationTrackHandler is ready to use
// Step 6: Update animations over time (e.g., in your update loop)
function onTimelineUpdate(time) {
// time should be the current time of your timeline logic
animationTrackHandler.evaluate(time);
}
Hi @nostalgicbear adding your second script to the same object should work - but I understand that this is not really a solution. I’ll raised an issue internally since currently animationclips resolve the objects they target in the GltfLoader by threejs the time the file is loaded and this doesnt work if the hierarchy doesnt exist (yet)
@marcel Thanks again (always appreciate your responses). Im wondering if I am misunderstanding something so.
In the image attached, everything is one the one object but the animation doesnt play after I swap runtimeAnimatorControllers. I have one script “AnimatorManager” that allows me to assign “animatorController.runtimeAnimatorController = alternateRuntimeAnimatorController”. The script is on the same object as the Animator in question, which is on the object that will be animated (the same object that the animator is bound to before I swap the runtimeAnimatorController). After swapping, there is no deepClone error, but the animation doesnt play. Have I misunderstood something in your explanation? Just for clarity, there is no second script that you mentioned. I know I mentioned using the SceneSwitcher to load assets, but Ive not done that. For now Im just trying to see if this would work as an an initial test before incorporating extra steps using the SceneSwitcher.
I’ll just add that in relation to my last comment that the Bot tried to answer, if there is a way to bind an animation track to a timeline and have it play, then that would be in line with what I did in a standard Unity project, that would be great, but I dont think the bot interpreted my question correctly.
Animation via Timeline would still have the same underlying issue that we need to solve first - otherwise nothing will be different.
I think you understood me right. If the animation still isnt playing can you add ?debuganimatorcontroller to your url and check the console in the browser?
Thanks Marcel. Appreciate it. I have created a test project, and it does seem to be working in that, so Im going to double check Ive not done something stupid. I dont receive these calls in my main project, despite taking the same steps. Ill look further into it.
sooooo the testsetup i made here works - I can put animations in separate prefabs and load them at runtime. The requirement for this to work is that the hierarchy matches. This could be automatically solved with tooling (e.g. generating the correct hierarchy based on the assigned animations) - but as a first step we can test it manually I think