How can I smoothly transition between two separate animations in SceneKit? - animation

I am working with a 3d model that has one CAAnimationGroup per animation, with each group containing SCNMorpher weight animations with 2 CABasicAnimations per frame (to transition from weights of 1.0 to 0.0 and 0.0 to 1.0 for each frame and the next using interpolation).
My animations are running smoothly, but the transition from one group to the next is rough and rigid, like from walking to running.
I'm pretty new to 3D model animation, and need some guidance on a SceneKit approach to building smooth transitions from ANY of the animations to the next.
I'd like to be able to stop the current running animation immediately no matter how far it is along and immediately transition to the next. I'd like to transition to an offset in the target animation that ensures the target animation maintains it's original length so that the animation audio sync is not affected.
I apologize in advance for lack of sufficient information as I am not certain what information is required to answer the question. If you ask, I will provide whatever information is required.
How can I smoothly transition from one animation to another, without waiting for the current running animation to finish and without changing the running duration of the target?

Does -removeAnimationForKey:fadeOutDuration: help?
From the documentation:
For example, the geometry loaded from a scene file for a game character may have associated animations for player actions such as walking and jumping. When the player lands from a jump, you remove the jump animation so the character continues walking. If you use the removeAnimationForKey: method to remove the jump animation, SceneKit abruptly switches from the current frame of the jump animation to the current frame of the walk animation. If you use the removeAnimationForKey:fadeOutDuration: method instead, SceneKit plays both animations at once during that duration and interpolates vertex positions from one animation to the other, creating a smooth transition.

Instance method removeAnimation(forKey:fadeOutDuration:) is deprecated since macOS_10.13/iOS_11.
func removeAnimation(forKey key: String,
fadeOutDuration duration: CGFloat)
Use new instance method removeAnimation(forKey:blendOutDuration:) instead.
func removeAnimation(forKey key: String,
blendOutDuration duration: CGFloat)

Related

Position of player changes when the attack animation starts - unity

So I did an attack animation in the program Aseprite and everything was fine with the animation, but when I put in inside the animator in unity the character changes position.
Here's the images, first one is a gif with the animation running as I want, and then the before and after of the animation in Unity.
I know it's small but I hope you can see
This is because it's setting the center point at the location, and the gif is wider than the standard player image, you will need to offset to compensate.
So I just sliced the sprites again but with the pivot to the left instead of center, and then adjusted the Collider. It seems to work. Not sure if it's the perfect way though.

How to keep sprites position after Unity animation?

I just recently began using Unity3D and this is my first game, so if I'm not doing things like I'm supposed to, please tell me.
There is a 2D character that I want to move one step forward using the Animation mechanism. This movement can be splitted in two parts :
Move forward the back leg, don't move the upper body ;
Use this leg to push and make the step, moving the upper body.
My problème is that I can't find a way to make this step permanent. As soon as it start looping on the "Idle" animation, then, it come back to the original position (before the step).
I don't know how to let my character stay in the position it was just between the "Step Forward" animation and the "Idle" animation.
I tried to add "Rigidbody 2D", "Box Collider 2D" and "Physics2D Material" on both feet and on the floor, but it somewhat breaks the IK script ("Simple CCD", from the youtube video "Unite 2014 - 2D Best Practices In Unity"). And I'm sure there is a much simpler way.
EDIT: My question was not clear enough. The idle animation is the default animation, where the character is doing nothing in particular. It's just moving a little while it's staying in position. When it runs "Step Forward", all the sprites are moved (only when the back leg is pushing). If all animations are stopped right now, then the character is indeed in a new position, closer to it's opponent. I can check that by removing the transition from "Step Forward" to "Idle". But from here, I want it to loop on the Idle animation. When the transition from "Step forward" to "Idle" is done, the character is NOT running Idle from it's new position, but from it's old position, before the step, as if it was pulled from backward. I want to run Idle from the new position.
Here is a longer gif when we can see more of the Idle animation :
And my Hierarchy panel looks like :
Main Camera
Karateka (the top GameObject container, with the Animator component)
Torso (the sprites)
Head
Right arm
Right leg
Right lower leg
Right foot
...
IK (the Inverse Kinematics targets)
Left fist target
Left foot target
...
Any suggestion is welcome.
If I get it right, you have the StepForward animation running and it gets cut in the middle back to idle. There, the StepForward animation triggers again but from the start and you wish to restart from where you left off:
You can record the normalized value of your StepForward animation and use it next time:
float normValue = this.animator.GetCurrentAnimatorStateInfo(0).normalizedTime;
then you can use that value:
this.animator.Play("StepForward", 0, normValue);
Other possibility, you are not after that but simply you want to pause the animation without getting to Idle.
Use a parameter. You can add a float parameter (call it direction) in the Animator window (top left). Then select a state in the animator, it will open the animation setting in the inspector. Under speed, open the drop down where your new parameter should show up. And tick it.
Now, your direction float will affect the speed of your animation as such:
this.animator.SetFloat("direction", value);
if you give 0, you pause. Give back 1 to move forward. You can also lerp the value so it is not abrupt. Your way.

Unity2D - Player relative animation positioning

I'm making a 2D platformer and I've come across a really annoying problem where if I move my player character GameObject to another location on the scene, my player becomes stuck and the game spazzes out, jumping from the players original location and the position I moved it to.
My player character is made up of many parts, each a separate GameObject. I know the problem is definitely in my animation, because if I disable the animator component, the problem goes away, just I don't have my animations anymore. I believe the problem may be in the player character's Idle Animation and it's position property. There is no script attached where his starting location is hard coded.
How can I make the child Gameobjects move relative to the parent Player GameObject? I cannot move the player in the scene from its original location without the game glitching up.
Here are some screenshots
[Player and it's parts in Hierarchy]http://i67.tinypic.com/bdlc1j.png
[Idle Animation]http://i64.tinypic.com/2gtp99x.png
[Player's original Location, he works if starting here] http://i66.tinypic.com/261jb6c.png
[Player is Moved, game bugs out] http://i67.tinypic.com/292a2c3.png
Try to disable "Apply Root Motion" flag in the Animator component.
The problem should be related to the fact that the animation changes the position values
My guess is that you have animated the different parts by moving then around in the editor and recording that. This meas that the animation is keeping track of the original position at which you did the animation. Try deleting those parts from the animation.
I couldn't fix the spazzy-jittering problem that occurs when I move the player character to another position on the scene, but I did find a way around it. The problem definitely lied within the Animator component and the gameObject's Rigidbody2d.
Instead of moving the player to another position, I instead made a 'Spawn Point' which the player starts from when first playing the scene, and that was able to be moved freely around. Pretty much:
void start(){
transform.position = spawnPoint.transform.position;
}

Blending animations in DirectX - is this technically possible?

I have an animated mesh in the .x format I've loaded with D3DXLoadMeshHierarchyFromX and have an animation controller for it. The mesh has two animations, one for walking and one for throwing where the walk animation.
Is it at all possible to blend the two animations in such a way that both animations can run together with the walk taking priority for frames below the hip while throwing animation takes priority for frames above it? If it is will the effect look convincing therefore worth pursuing? Do game developers typically blend animations in such a way to get all the different animations they wish or do they simply create multiple versions of the same animation, i.e. walking while throwing, standing while throwing, walking without throwing?
You can set High and low priority animation tracks with ID3DXAnimationController::SetTrackPriority. You can then blend between them using ID3DXAnimationController::SetPriorityBlend.

Using Core Animation, is there a way to group animations for several CALayers?

I have a situation where I have many CALayers which animate in a "turn based" fashion. I animate the position on each of those CALayers, but they have the exact same duration. Once all of those CALayers are finished animating, a new "turn" is initiated and they animate changing positions again.
The whole idea is that with a linear interpolation between positions, and at a constant speed, a turn based transition between state to state looks like a real time animation. This, however, is hard to achieve with many different CALayers.
CAAnimationGroup is used to group together animations on a single CALayer. But I was wondering, is there a simple solution to group animations, which are supposed to have the same durations, on several CALayers together?
Edited to include a reply to Kevin Ballard's question
My problem lies in this. I'm creating animations for each of my CALayers, then putting
those in an NSArray. Once I get the callback that the individual animation has ended, I remove it form the NSArray. Once it's empty, I again create animations for them all.
With more than a few layers, there's a noticeable delay between where all of the animations finished and the new ones start.
I imagine that if I could group all of these animations into a single one, a lot more layers could be animated without a delay between animations. Thereby not ruining the illusions of a contiguous animation.
If you attach animations to multiple CALayers within a single method, they will all commence at (effectively) the same time. I use this approach in a puzzle game with dropping balls, at the end of the animations I attach the next stage of the animation to any ball that needs further animation.
I'm animating upto 60 CALayers at a time and not experiencing any delays between stages of the animation, but I don't cache the animations in an array of any sort, I'm not sure of thge overhead you have there.
My animations are relatively simple, and created and attached to each CALayer on the fly. My sprites are 60px square and use a couple dozen possible images to represent their content.
In some cases there are multiply animations that I can create with different starting times(using beginTime), I bundle them up with a CAAnimationGroup - but you may not be able to precalculate subsequent animations.
If you wrap your animations in a CATransaction, CG will make sure that they all run during the same iteration of the main loop.
[CATransaction begin];
// all your animations
[CATransaction commit];
If you add 3 animations to 3 different layers all at the same time, and they have the same duration, I would expect them all to animate together. What behavior are you seeing?
cp21yos: can you elaborate on your method? I am trying to do something similar, which involves animating several layers at a time, more than once. You said: "at the end of the animations I attach the next stage of the animation ". Can you explain that? When I try to put logic to perform additional animations in an animationDidStop event, only the last animation is occuring, instead of the whole sequence of animations.

Resources