Callback on animation end in Unity - animation

Using Unity 4.6 and 2D stuff with animations.
I am animating a GameObject and have a few transitions to go back and forth between states performing animations. The animations are generally non-repeating. How can I attach a callback to a script function to be called when an animation ends?

I found something call Animation Event. I can easily call a function with this at specified time in the animation interval. It would probably work in many cases...
The problem is that this time round I have one animation that is used twice, once to go from state A to state B, and then the same animation going from B back to A using time set to -1. The animation "end" callback would be called at the end of a positive animation, but called at the beginning of a negative animation. Feels like it gets too complicated to make any sense out of that and a cleaner solution would be appropriate.

Related

Eject Blocking Object if Overlapping: UE4

My 2d platformer has a "time travel" mechanic.
You place down a hologram at a location (actor with no collision and some pretty effects).
While you hold down the "Rewind" button, your character's collision and gravity are turned off, and he slowly moves towards the hologram.
When you release the rewind button, it turns his collision back on.
My tilemap is set to "block" the pawn (so he can walk on it, etc).
If you release the button while he's overlapping the terrain, and it turns his collision back on, he gets stuck.
I'm wondering what to do. Unity automatically "ejected" an object that was overlapping something it shouldn't be.
Since the terrain is set up to block the pawn, I can't fire an overlap event. "On Component Hit" will fire just from him standing or rubbing against the terrain, so that won't do either.
How should I detect that the player is popping up inside the terrain? I can decide what to do later (eject them, kill them, prevent them from appearing, etc). But for right now I just need to differentiate from them touching the tilemap and being inside it.
Any ideas?
So what I wound up doing was duplicating the capsule collider on my player. The new capsule (called 'Terrain Overlap') ignores all collisions, except it overlaps the tilemap.
The component has a begin and end overlap method that sets a boolean on the character.
When the player lets go of the Rewind button, if they're inside the ground (boolean check), I can fire the death method.

How to change rigs spine rotation in unity3d, using camera rotation?

I have a rigged 3d model of a person with animations that i made. It is a player model in a first person shooter. I want this model to "bow", when looking down or do the opposite, when looking up. To achieve this, i decided, instead of making an animation for each degree the player might decide looking at, to rotate models spine, depending on the angle of the camera. In scene view, i can easily change rotation value and get the results i want, however, when game is running, those parameters seem to be "locked" and no matter what script i tried, i cant seem to change the rotation value. I figured, perhaps, when animation is playing, i cant change things it effects, so made a body mask to excluded torso from animations and spines rotation was still locked away from me. Is there a way to rotate models spine, when its doing its normal, lets say, idle, animation? is there actually another easy way to achieve this?
You have to update in LateUpdate(). Unity's animator does it's changes to the transform in Update(). By doing it in LateUpdate() it will be handled after the animation has made it's changes.

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

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)

Why do we update() before we draw()?

This never made sense to me. I looked at GLFW's and Three.js' examples and Cinder's implementation which actually has this comment in there:
mark all windows as ready to draw; this really only matters the first
time, to ensure the first update() fires before draw()
All three libraries seem to be doing that and I don't understand why. There really is no point in updating the i.e. position of something that's never been drawn on screen or is there?
Here's what my loop looks like:
Draw the (first) frame
Swap buffers
Update events
Animate (with the input from the events), update logic, ...
Start from the top
This order makes a lot more sense to me but maybe I'm missing something.
I think that it makes perfect sense to update objects first and then draw them.
Imagine you animate a ball going from one side of the screen to the other and back just like a pendulum. Imagine you also want it to actually reflect real time in your computer. If you draw your scene before updating the ball's position, then where your ball will be positioned in the first frame? Unless you set it's initial position manually, it would be at zero point of your scene, which might be completely out of it's intended trajectory. If you decide to initialize it's position before start of animation, it might happen that there is a time gap causing it to be in the wrong position too.
But if you always update it's position before drawing, it will be on the right place right from the first rendered frame.
But to be honest - nobody will probably notice the first frame, so it is more sense of logic doing it that way rather than any practical reason. I just feel it makes more sense to prepare your scene before drawing it, not vice versa.

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