Add support for multiple actions for one actor. #1
This commit is contained in:
@@ -4,6 +4,18 @@ using UnityEngine;
|
||||
|
||||
namespace coa4u
|
||||
{
|
||||
public enum Axises
|
||||
{
|
||||
none,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
xy,
|
||||
xz,
|
||||
yz,
|
||||
xyz
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Basic action class for subclassing. To inherit interval actions, consider using the ActionInterval as the base class.
|
||||
/// </summary>
|
||||
|
||||
@@ -79,15 +79,13 @@ namespace coa4u
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is called after the interval action is stopped.
|
||||
/// </summary>
|
||||
public override void Stop()
|
||||
{
|
||||
base.Stop();
|
||||
for (int i = 0; i < actions.Length; i++)
|
||||
{
|
||||
actions[i].Stop();
|
||||
if (actions[i].running)
|
||||
actions[i].Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,5 +71,12 @@ namespace coa4u
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
base.Stop();
|
||||
if (action.running)
|
||||
action.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ namespace coa4u
|
||||
index = 0;
|
||||
actions[0].SetActor(target);
|
||||
actions[0].Start();
|
||||
while (!actions[index].running && index < actions.Length)
|
||||
while (!actions[index].running && index < actions.Length - 1)
|
||||
{
|
||||
index += 1;
|
||||
actions[index].SetActor(target);
|
||||
@@ -84,16 +84,11 @@ namespace coa4u
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is called after the interval action is stopped.
|
||||
/// </summary>
|
||||
public override void Stop()
|
||||
{
|
||||
base.Stop();
|
||||
for (int i = 0; i < actions.Length; i++)
|
||||
{
|
||||
actions[i].Stop();
|
||||
}
|
||||
if (actions[index].running)
|
||||
actions[index].Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ namespace coa4u
|
||||
public override void Start()
|
||||
{
|
||||
base.Start();
|
||||
target.StopAction();
|
||||
target.StopAllActions();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,10 @@ namespace coa4u
|
||||
/// <summary>
|
||||
/// Prints a message in Unity debug console.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
class ActionLog : ActionInstant
|
||||
{
|
||||
string message;
|
||||
public string message;
|
||||
|
||||
public ActionLog(string targetMessage)
|
||||
: base()
|
||||
|
||||
@@ -44,9 +44,7 @@ namespace coa4u
|
||||
value = other.transformCached.position;
|
||||
}
|
||||
if (locks != Axises.none)
|
||||
{
|
||||
value.z = transform.position.z;
|
||||
}
|
||||
LockAxises(ref value);
|
||||
transform.rotation = Quaternion.LookRotation(value - transform.position);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace coa4u
|
||||
public ActionSetRotation(float angle)
|
||||
: this(new Vector3(0, 0, angle))
|
||||
{
|
||||
locks = Axises.xy;
|
||||
locks = Axises.rxy;
|
||||
}
|
||||
|
||||
public override ActionInstant Clone()
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace coa4u
|
||||
{
|
||||
|
||||
public ActionFadeIn(float targetDuration)
|
||||
: base(1, targetDuration)
|
||||
: base(2, targetDuration)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -24,5 +24,13 @@ namespace coa4u
|
||||
{
|
||||
return new ActionFadeOut(duration);
|
||||
}
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
base.Start();
|
||||
Color targetColor = renderer.material.color;
|
||||
targetColor.a = 0;
|
||||
renderer.material.color = targetColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ namespace coa4u
|
||||
class ActionMoveBy : ActionInterval
|
||||
{
|
||||
protected Vector3 delta;
|
||||
protected Vector3 referencePoint;
|
||||
|
||||
public ActionMoveBy(Vector3 targetDelta, float targetDuration)
|
||||
: base(targetDuration)
|
||||
@@ -23,12 +22,6 @@ namespace coa4u
|
||||
{
|
||||
}
|
||||
|
||||
public ActionMoveBy(ref Vector3 refPoint, float targetDuration)
|
||||
: this(Vector3.zero, targetDuration)
|
||||
{
|
||||
referencePoint = refPoint;
|
||||
}
|
||||
|
||||
public override ActionInstant Clone()
|
||||
{
|
||||
return new ActionMoveBy(delta, duration);
|
||||
@@ -39,20 +32,10 @@ namespace coa4u
|
||||
return new ActionMoveBy(delta * -1F, duration);
|
||||
}
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
base.Start();
|
||||
if (referencePoint != null)
|
||||
{
|
||||
delta = referencePoint;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Step(float dt)
|
||||
{
|
||||
float d = dt / duration;
|
||||
Vector3 target = delta * d;
|
||||
transform.Translate(target, Space.World);
|
||||
transform.Translate(delta * d, Space.World);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,8 +40,7 @@ namespace coa4u
|
||||
public override void Step(float dt)
|
||||
{
|
||||
float d = dt / duration;
|
||||
Vector3 target = path * d;
|
||||
transform.Translate(target, Space.World);
|
||||
transform.Translate(path * d, Space.World);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ namespace coa4u
|
||||
public ActionRotateBy(float angle, float targetDuration)
|
||||
: this(new Vector3(0, 0, angle), targetDuration)
|
||||
{
|
||||
locks = Axises.rxy;
|
||||
}
|
||||
|
||||
public override ActionInstant Clone()
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace coa4u
|
||||
public ActionRotateTo(float angle, float targetDuration)
|
||||
: this(new Vector3(0, 0, angle), targetDuration)
|
||||
{
|
||||
locks = Axises.xy;
|
||||
locks = Axises.rxy;
|
||||
}
|
||||
|
||||
public override ActionInstant Clone()
|
||||
@@ -37,10 +37,18 @@ namespace coa4u
|
||||
{
|
||||
float t = value[i];
|
||||
float f = transform.rotation.eulerAngles[i];
|
||||
if (Math.Abs(t - f) < Math.Abs(t + 360 - f))
|
||||
if ((f - t) <= 180 && (f - t) >= -180)
|
||||
{
|
||||
path[i] = t - f;
|
||||
else
|
||||
path[i] = t + 360 - f;
|
||||
}
|
||||
else if ((f - t) > 180)
|
||||
{
|
||||
path[i] = t - f + 360;
|
||||
}
|
||||
else if ((f - t) < -180)
|
||||
{
|
||||
path[i] = t - f - 360;
|
||||
}
|
||||
}
|
||||
if (locks != Axises.none)
|
||||
LockAxises(ref path);
|
||||
@@ -48,8 +56,8 @@ namespace coa4u
|
||||
public override void Step(float dt)
|
||||
{
|
||||
float d = dt / duration;
|
||||
Vector3 target = path * d;
|
||||
transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles + target);
|
||||
Vector3 rotation = path * d;
|
||||
transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles + rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace coa4u
|
||||
{
|
||||
/// <summary>
|
||||
/// Skews the object by the given angles.
|
||||
/// </summary>
|
||||
class ActionSkewBy : ActionInterval
|
||||
{
|
||||
protected Vector3 skewAngles1;
|
||||
protected Vector3 skewAngles2;
|
||||
protected Mesh mesh;
|
||||
|
||||
public ActionSkewBy(Vector3 targetAngles1, Vector3 targetAngles2, float targetDuration)
|
||||
: base(targetDuration)
|
||||
{
|
||||
skewAngles1 = targetAngles1;
|
||||
skewAngles2 = targetAngles2;
|
||||
}
|
||||
|
||||
public override ActionInstant Clone()
|
||||
{
|
||||
return new ActionSkewBy(skewAngles1, skewAngles2, duration);
|
||||
}
|
||||
|
||||
public override ActionInstant Reverse()
|
||||
{
|
||||
return new ActionSkewBy(-skewAngles1, -skewAngles2, duration);
|
||||
}
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
base.Start();
|
||||
if (!(target is Actor))
|
||||
{
|
||||
throw new Exception("You should use Actor class instead of Actor, if you want to skew your object.");
|
||||
}
|
||||
}
|
||||
|
||||
public override void Step(float dt)
|
||||
{
|
||||
float d = dt / duration;
|
||||
Vector3 vTarget = skewAngles1 * d;
|
||||
((Actor)target).skewAngles1 += vTarget;
|
||||
vTarget = skewAngles2 * d;
|
||||
((Actor)target).skewAngles2 += vTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,15 @@ namespace coa4u
|
||||
xy,
|
||||
xz,
|
||||
yz,
|
||||
xyz
|
||||
xyz,
|
||||
rx,
|
||||
ry,
|
||||
rz,
|
||||
rxy,
|
||||
rxz,
|
||||
ryz,
|
||||
rxyz
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,22 +10,16 @@ using coa4u;
|
||||
public class Actor : MonoBehaviour
|
||||
{
|
||||
protected Dictionary<string, MethodHolder> methodsCache = new Dictionary<string, MethodHolder>();
|
||||
protected ActionInstant action;
|
||||
protected List<ActionInstant> actions = new List<ActionInstant>();
|
||||
protected List<ActionInstant> actionsToDelete = new List<ActionInstant>();
|
||||
protected List<ActionInstant> actionsToAdd = new List<ActionInstant>();
|
||||
private bool paused = false;
|
||||
protected Vector3 angles1prev = Vector3.zero;
|
||||
protected Vector3 angles2prev = Vector3.zero;
|
||||
private bool running = false;
|
||||
protected const float coeff = Mathf.PI / 180;
|
||||
protected Vector3[] initialState;
|
||||
[HideInInspector]
|
||||
public Transform transformCached;
|
||||
[HideInInspector]
|
||||
public Renderer rendererCached;
|
||||
[HideInInspector]
|
||||
public Mesh meshCached;
|
||||
[HideInInspector]
|
||||
public Vector3 skewAngles1;
|
||||
[HideInInspector]
|
||||
public Vector3 skewAngles2;
|
||||
|
||||
/// <summary>
|
||||
/// This method is called when the script instance is being loaded.
|
||||
@@ -34,13 +28,6 @@ public class Actor : MonoBehaviour
|
||||
{
|
||||
transformCached = gameObject.transform;
|
||||
rendererCached = gameObject.renderer;
|
||||
|
||||
Component component = gameObject.GetComponent<MeshFilter>();
|
||||
if (component != null)
|
||||
{
|
||||
meshCached = ((MeshFilter)component).mesh;
|
||||
initialState = meshCached.vertices;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -48,45 +35,36 @@ public class Actor : MonoBehaviour
|
||||
/// </summary>
|
||||
protected void Update()
|
||||
{
|
||||
if (paused || action == null)
|
||||
if (paused)
|
||||
return;
|
||||
if (action.running)
|
||||
action.StepTimer(Time.deltaTime);
|
||||
if (skewAngles1 != angles1prev || skewAngles2 != angles2prev)
|
||||
UpdateSkew();
|
||||
|
||||
foreach (ActionInstant action in actions)
|
||||
{
|
||||
if (action.running)
|
||||
action.StepTimer(Time.deltaTime);
|
||||
if (!action.running)
|
||||
actionsToDelete.Add(action);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the skew for the mesh.
|
||||
/// This method is called after the every frame update.
|
||||
/// </summary>
|
||||
void UpdateSkew()
|
||||
protected void LateUpdate()
|
||||
{
|
||||
if (meshCached == null)
|
||||
return;
|
||||
|
||||
Matrix4x4 m = Matrix4x4.zero;
|
||||
m[0, 0] = 1;
|
||||
m[1, 1] = 1;
|
||||
m[2, 2] = 1;
|
||||
m[3, 3] = 1;
|
||||
m[0, 1] = Mathf.Tan(skewAngles1.x * coeff); // skewing in xy
|
||||
m[0, 2] = Mathf.Tan(skewAngles2.x * coeff); // skewing in xz
|
||||
m[1, 0] = Mathf.Tan(skewAngles1.y * coeff); // skewing in yx
|
||||
m[1, 2] = Mathf.Tan(skewAngles2.y * coeff); // skewing in yz
|
||||
m[2, 0] = Mathf.Tan(skewAngles1.z * coeff); // skewing in zx
|
||||
m[2, 1] = Mathf.Tan(skewAngles2.z * coeff); // skewing in zy
|
||||
|
||||
Vector3[] verts = new Vector3[initialState.Length];
|
||||
int i = 0;
|
||||
while (i < verts.Length)
|
||||
foreach (ActionInstant action in actionsToAdd)
|
||||
{
|
||||
verts[i] = m.MultiplyPoint3x4(initialState[i]);
|
||||
i++;
|
||||
if (action.running)
|
||||
actions.Add(action);
|
||||
}
|
||||
|
||||
meshCached.vertices = verts;
|
||||
angles1prev = skewAngles1;
|
||||
angles2prev = skewAngles2;
|
||||
foreach (ActionInstant action in actionsToDelete)
|
||||
{
|
||||
if (!action.running)
|
||||
actions.Remove(action);
|
||||
}
|
||||
actionsToDelete.Clear();
|
||||
actionsToAdd.Clear();
|
||||
running = actions.Count > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -94,31 +72,39 @@ public class Actor : MonoBehaviour
|
||||
/// </summary>
|
||||
public void AttachAction(ActionInstant targetAction)
|
||||
{
|
||||
if (action != null)
|
||||
targetAction.SetActor(this);
|
||||
targetAction.Start();
|
||||
if (targetAction.running)
|
||||
{
|
||||
action.Stop();
|
||||
actionsToAdd.Add(targetAction);
|
||||
}
|
||||
action = targetAction;
|
||||
action.SetActor(this);
|
||||
action.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stopes and removes the given action.
|
||||
/// </summary>
|
||||
public void RemoveAction(ActionInstant targetAction)
|
||||
{
|
||||
if (targetAction.running)
|
||||
targetAction.Stop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops all running actions for this actor.
|
||||
/// </summary>
|
||||
public void StopAction()
|
||||
public void StopAllActions()
|
||||
{
|
||||
if (action == null)
|
||||
return;
|
||||
if (action.running)
|
||||
action.Stop();
|
||||
action = null;
|
||||
foreach (ActionInstant action in actions)
|
||||
{
|
||||
if (action.running &! action.unstopable)
|
||||
action.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pauses actions for this actor.
|
||||
/// </summary>
|
||||
public void PauseAction()
|
||||
public void PauseActions()
|
||||
{
|
||||
paused = true;
|
||||
}
|
||||
@@ -126,7 +112,7 @@ public class Actor : MonoBehaviour
|
||||
/// <summary>
|
||||
/// Unpauses actions for this actor.
|
||||
/// </summary>
|
||||
public void UnpauseAction()
|
||||
public void UnpauseActions()
|
||||
{
|
||||
paused = false;
|
||||
}
|
||||
@@ -136,9 +122,13 @@ public class Actor : MonoBehaviour
|
||||
/// </summary>
|
||||
public void SetTimeScale(float ts)
|
||||
{
|
||||
if (action is ActionInterval)
|
||||
for (int i = 0; i < actions.Count; i++)
|
||||
{
|
||||
((ActionInterval)action).SetTimeScale(ts);
|
||||
ActionInstant action = actions[i];
|
||||
if (action is ActionInterval)
|
||||
{
|
||||
((ActionInterval)action).SetTimeScale(ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +140,9 @@ public class Actor : MonoBehaviour
|
||||
methodsCache.Add(method.Method.Name, new MethodHolder(method));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds method to cache to speed-up the ActionSendMessage.
|
||||
/// </summary>
|
||||
public void AddMethodToCache<T>(Action<T> method)
|
||||
{
|
||||
methodsCache.Add(method.Method.Name, new MethodHolder<T>(method));
|
||||
@@ -170,6 +163,9 @@ public class Actor : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Proxy method to receive messages. WARNING: If the message can be handled by the actor, it will be handled and will not be passed to the Unity3D gameobject.
|
||||
/// </summary>
|
||||
public void ReceiveMessage(string key, object param = null, SendMessageOptions options = SendMessageOptions.DontRequireReceiver)
|
||||
{
|
||||
if (methodsCache.ContainsKey(key))
|
||||
@@ -184,4 +180,15 @@ public class Actor : MonoBehaviour
|
||||
gameObject.SendMessage(key, param, options);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows if the actor has any running actions.
|
||||
/// </summary>
|
||||
public bool hasRunningActions
|
||||
{
|
||||
get
|
||||
{
|
||||
return running;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,15 +19,11 @@ public class ActorSampleActions : Actor
|
||||
new ActionDelay(1),
|
||||
new ActionBlink(5, 0.1F, 0.4F),
|
||||
new ActionDelay(1),
|
||||
new ActionSkewBy(Vector3.zero, new Vector3(0, 30, 0), 1),
|
||||
new ActionDelay(1),
|
||||
new ActionJumpBy(new Vector3(-10, 0, 0), 1, 4, 1),
|
||||
new ActionSkewBy(Vector3.zero, new Vector3(30, 0, 30), 1),
|
||||
new ActionJumpTo(new Vector3(10, 10, 10), 1, 3, 1),
|
||||
new ActionRotateBy(new Vector3(90, 0, 0), 1),
|
||||
new ActionSkewBy(Vector3.zero, new Vector3(-30, 0, -30), 1),
|
||||
new ActionJumpBy(new Vector3(-10, 0, 0), 1, 2, 1),
|
||||
new ActionSkewBy(Vector3.zero, new Vector3(0, -30, 0), 1),
|
||||
new ActionDelay(0.5F),
|
||||
new ActionBezierRel(new Vector2 (5, 0), new Vector2(5, -10), new Vector2 (0, -10), 2),
|
||||
new ActionScaleTo(new Vector3(2, 2, 2), 1),
|
||||
|
||||
Reference in New Issue
Block a user