Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animation and logic

Tags:

animation

I have a question not necessarily specific to any platform or API but more specific to interactions in code between animations.

A game is a good example. Let's say the player dies, and there's a death animation that must finish before the object is removed. This is typical for many cases where some animation has to finish before continuing with what ever action that would normally follow. How would you go about doing this?

My question is about the control and logic of animation. How would you design a system which is capable of driving the animation but at the same time implement custom behavior?

The problem that typically arise, is that the game logic and animation data become codependent. That is, the animation has to callback into code or somehow contain meta data for duration of animation sequences. What's typically even more so a problem, is when an animation, which has to trigger some other code, say after 1.13s spawn a custom sprite, this tend to result in deep nesting of code and animation. A bomb with a timer would be en example of both logic and animation where both things interact, but I want to keep them as separate as possible.

But what would you do to keep animation and code two separate things?

Recently I've been trying out mgrammar, and I'm thinking, a DSL might be the way to go. That would allow the animation or animator, to express certain things in a presumably safe manner which would then go into the content pipeline...

like image 574
John Leidegren Avatar asked Mar 25 '09 08:03

John Leidegren


People also ask

Did Netflix Buy Animal Logic?

Netflix Acquires World Leading Independent Animation Studio Animal Logic. Netflix and Animal Logic are excited to announce today that Netflix plans to acquire the Australian animation studio.

How much did Netflix pay for Animal Logic?

The Animal Logic purchase builds on Netflix's previously announced multi-year deal, with DNEG, which is reported to be worth at least $350 million (over the period up until 2025).

What is Animal Logic known for?

Established in 1991, Animal Logic has produced visual effects and animation for feature films such as the Academy Award-winning Happy Feet, Legend of the Guardians: The Owls of Ga'Hoole, Walking with Dinosaurs 3D, The Lego Movie and Peter Rabbit.

What software does Animal Logic use?

Animal Logic has been actively using and contributing to Rez since 2014 as an integrated package configuration, build and deployment system for software and we're looking forwards to continuing to contribute towards this codebase.


3 Answers

The solution depends on the gameplay you're going for. If the gameplay is 100% code-driven, the anim is driven by the entity's state(state-driven animation). If it's graphics/animation-driven, the anim length determines how long the entity's in that state(anim-driven state).

The latter is typically more flexible in a commercial production environment as the designer can just say "we need that death anim to be shorter" and it gets negotiated. But when you have very precise rules in mind or a simulated system like physics, state-driven animation may be preferable. There is no 100% orthogonal and clean solution for the general case.

One thing that helps to keep it from getting too messy is to consider game AI patterns:

Game AI is typically implemented as some form of finite state machine, possibly multiple state machines or layered in some way(the most common division being a high level scripting format with low level actions/transitions).

At the low level you can say things like "in the hitreact state, playback my hitreact anim until it finishes, then find out from the high-level logic what state to continue from." At the high level there are a multitude of ways to go about defining the logic, but simple repeating loops like "approach/attack/retreat" are a good way to start.

This helps to keep the two kinds of behaviors - the planned activities, and the reactions to new events - from being too intermingled. Again, it doesn't always work out that way in practice, for the same reasons that sometimes you want code to drive data or the other way around. But that's AI for you. No general solutions here!

like image 195
user85011 Avatar answered Oct 27 '22 09:10

user85011


I think you should separate the rendering from the game logic.

You have at least two different kind of objects:

  • An entity that holds the unit's data (hit points, position, speed, strength, etc.) and logic (how it should move, what happens if it runs out of hit points, ...).
  • Its representation, that is the sprite, colors, particles attached to it, sounds, whatever. The representation can access the entity data, so it knows the position, hit points, etc.
  • Maybe a controller if the entity can be directly controlled by a human or an AI (like a car in a car simulation).

Yes that sounds like the Model-View-Controller architecture. There are lots of resources about this, see this article from deWiTTERS or The Guerrilla Guide to Game Code by Jorrit Rouwé, for game-specific examples.

About your animation problems: for a dying unit, when the Model updates its entity and figures out it has no more hit points, it could set a flag to say it's dead and remove the entity from the game (and from memory). Then later, when the View updates, it reads the flag and starts the dying animation. But it can be difficult to decide where to store this flag since the entity object should disappear.

There's a better way in my humble IMHO. When your entity dies, you could send an event to all listeners that are registered to the UnitDiedEvent that belongs to this specific entity, then remove the entity from the game. The entity representation object is listening to that event, and its handler starts the dying animation. When the animation is over, the entity representation can finally be removed.

The observer design pattern can be useful, here.

like image 1
Splo Avatar answered Oct 27 '22 11:10

Splo


Your enemy needs to have multiple states. Alive and dead are not enough. Alive, dying and dead might be. Your enemy processing loop should check its state and perform different operations:

if(state == alive and hp == 0)
{
   state = dying
   currentanimation = animation(enemy_death)
   currentanimation.play()
}
elseif(state == dying and currentanimation.isPlaying == true)
{
    // do nothing until the animation is finished.
    // more efficiently implemented as a callback.
}
elseif(state == dying and currentanimation.isPlaying == false)
{
    state = dead
    // at this point either the game engine cleans up the object, or the object deletes itself.
}
like image 1
Martin Avatar answered Oct 27 '22 09:10

Martin