Animation States
Summary
Control animation states from a Reactor server using entity properties as animation parameters linked to animation transitions in an animation controller.
Setup
- Import 4 animations. Idle, Walk, Run, and Cheering and configure the following properties on all animations
Loop Time = Checked
Root Tranform Rotation
Based Into Pose = Checked
Based Upon = Body Orientation
Root Tranform Position Y
Based Into Pose = Checked
Based Upon (at Start) = Original
Root Tranform Position XZ
Based Into Pose = Checked
Based Upon (at Start) = Original
- Create an animation controller and add the imported animations. Add a float parameter named
Speed
and a bool parameter namedCheering
to the animation controller. Add transitions between the animation states with conditions based on the two parameters:
Idle (Linked from Entry)
Transition To Walk, exit time disabled, Speed > 0.01 condition.
Transition To Cheering, exit time disabled, Cheering = True condition.
Walking
Transition To Idle, exit time disabled, Speed < 0.01 condition.
Transition To Run, exit time disabled, Speed > 1 condition.
Transition To Cheering, exit time disabled, Cheering = True condition.
Running
Transition To Walk, exit time disabled, Speed < 1 condition.
Transition To Cheering, exit time disabled, Cheering = True condition.
Cheering
Transition To Idle, exit time disabled, Cheering = False condition.
Creat an NPC GameObject from the idle animation asset. Set the NPC animator controller reference to the animation controller created above.
Add a Reactor ksEntityComponent to the NPC and uncheck the IsPermanent property. Add a Reactor client entity script named
ceAnimator
to the NPC. This script listens for changes on entity property 0 which we use for the Speed and property 1 which we use for Cheering. When the property change events fire, they set the corresponding value in the NPC animator.
using UnityEngine;
using KS.Reactor;
using KS.Reactor.Client.Unity;
public class ceAnimator : ksEntityScript
{
private Animator m_animator;
public override void Initialize()
{
m_animator = GetComponent<Animator>();
Entity.OnPropertyChange[0] += ChangeSpeedProperty;
Entity.OnPropertyChange[1] += ChangeCheerProperty;
}
public override void Detached()
{
Entity.OnPropertyChange[0] -= ChangeSpeedProperty;
Entity.OnPropertyChange[1] -= ChangeCheerProperty;
}
private void ChangeSpeedProperty(ksMultiType oldValue, ksMultiType newValue)
{
if (m_animator != null)
m_animator.SetFloat("Speed", newValue.Float);
}
private void ChangeCheerProperty(ksMultiType oldValue, ksMultiType newValue)
{
if (m_animator != null)
m_animator.SetBool("Cheering", newValue.Bool);
}
}
Add a Reator server entity script named seAnimator
to the NPC. This script sets the entity property 0 (Speed) value and the entity property 1 (Cheering) property during an update loop. The script changes the speed during the update loop and periodically sets and unsets the cheering property. This is just an example script, actual scripts used in games will drive animation states in different ways.
using KS.Reactor.Server;
public class seAnimator : ksServerEntityScript
{
private float m_cheerDuration = 0f;
private float m_cheerTime= 10f;
private float m_speed = -1f;
private bool m_increaseSpeed = true;
public override void Initialize()
{
Room.OnUpdate[0] += Update;
}
public override void Detached()
{
Room.OnUpdate[0] -= Update;
}
private void Update()
{
// Ping pong speed up and down to switch between idle, walking and running
if (m_speed < -1.0f)
m_increaseSpeed = true;
else if (m_speed > 2.0f)
m_increaseSpeed = false;
m_speed += 0.5f * (m_increaseSpeed ? Time.Delta : -Time.Delta);
Entity.Properties[0] = m_speed;
//Start Cheering
m_cheerTime -= Time.Delta;
if (m_cheerTime <= 0)
{
m_cheerTime = 10.0f;
m_cheerDuration = 2.0f;
Entity.Properties[1] = true;
}
// Stop Cheering
if (m_cheerDuration > 0)
{
m_cheerDuration -= Time.Delta;
if (m_cheerDuration <= 0)
{
Entity.Properties[1] = false;
}
}
}
}