Browse Source

Moved all actions to coa4u namespace.

Added methods caching for quick message processing.
Integrated MeshActor into Actor.

new Actions:
ActionStop.cs
ActionSetDirection.cs
master
parent
commit
2a5f20879b
40 changed files with 1757 additions and 1111 deletions
  1. +0
    -2
      README.md
  2. +104
    -60
      src/ActionsBase/Action.cs
  3. +75
    -79
      src/ActionsBase/ActionInterval.cs
  4. +77
    -56
      src/ActionsBase/ActionParallel.cs
  5. +68
    -47
      src/ActionsBase/ActionRandom.cs
  6. +68
    -50
      src/ActionsBase/ActionRepeat.cs
  7. +84
    -63
      src/ActionsBase/ActionSequence.cs
  8. +34
    -0
      src/ActionsBase/ActionStop.cs
  9. +33
    -13
      src/ActionsInstant/ActionHide.cs
  10. +36
    -11
      src/ActionsInstant/ActionLog.cs
  11. +56
    -29
      src/ActionsInstant/ActionSendMessage.cs
  12. +58
    -0
      src/ActionsInstant/ActionSetDirection.cs
  13. +34
    -22
      src/ActionsInstant/ActionSetPlace.cs
  14. +31
    -20
      src/ActionsInstant/ActionSetRotation.cs
  15. +29
    -12
      src/ActionsInstant/ActionSetTint.cs
  16. +33
    -13
      src/ActionsInstant/ActionShow.cs
  17. +34
    -9
      src/ActionsInstant/ActionToggleVisibility.cs
  18. +62
    -44
      src/ActionsInterval/ActionBezierAbs.cs
  19. +62
    -44
      src/ActionsInterval/ActionBezierRel.cs
  20. +43
    -31
      src/ActionsInterval/ActionBlink.cs
  21. +29
    -20
      src/ActionsInterval/ActionDelay.cs
  22. +36
    -21
      src/ActionsInterval/ActionFadeBy.cs
  23. +24
    -12
      src/ActionsInterval/ActionFadeIn.cs
  24. +24
    -12
      src/ActionsInterval/ActionFadeOut.cs
  25. +38
    -23
      src/ActionsInterval/ActionFadeTo.cs
  26. +38
    -35
      src/ActionsInterval/ActionJumpBy.cs
  27. +37
    -34
      src/ActionsInterval/ActionJumpTo.cs
  28. +28
    -25
      src/ActionsInterval/ActionMoveBy.cs
  29. +32
    -29
      src/ActionsInterval/ActionMoveTo.cs
  30. +28
    -25
      src/ActionsInterval/ActionRotateBy.cs
  31. +37
    -34
      src/ActionsInterval/ActionRotateTo.cs
  32. +48
    -45
      src/ActionsInterval/ActionScaleBy.cs
  33. +32
    -29
      src/ActionsInterval/ActionScaleTo.cs
  34. +34
    -31
      src/ActionsInterval/ActionSkewBy.cs
  35. +33
    -30
      src/ActionsInterval/ActionTintBy.cs
  36. +40
    -37
      src/ActionsInterval/ActionTintTo.cs
  37. +53
    -0
      src/CoreClasses/MethodHolder.cs
  38. +125
    -5
      src/UnityComponents/Actor.cs
  39. +20
    -5
      src/UnityComponents/ActorSampleActions.cs
  40. +0
    -54
      src/UnityComponents/MeshActor.cs

+ 0
- 2
README.md View File

@@ -63,8 +63,6 @@ Base actions
Interval actions Interval actions
- [ ] Follow - follows another actor with the given speed for the given amount of time (of forever). - [ ] Follow - follows another actor with the given speed for the given amount of time (of forever).
- [ ] LookAt - rotates the object to look at the given actor. - [ ] LookAt - rotates the object to look at the given actor.

*These two actions requires the using of MeshActor script instead of Actor.*
- [x] SkewBy - skews the mesh by given values. - [x] SkewBy - skews the mesh by given values.
- [ ] SkewTo - skews the mesh to the given values. - [ ] SkewTo - skews the mesh to the given values.




+ 104
- 60
src/ActionsBase/Action.cs View File

@@ -2,80 +2,124 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


public class Action
namespace coa4u
{ {
protected Actor target;
public float duration = 0;
protected Transform transform;
protected Renderer renderer;
protected bool is2d = false;

public Action()
/// <summary>
/// Basic action class for subclassing. To inherit interval actions, consider using the ActionInterval as the base class.
/// </summary>
public class ActionInstant
{ {
}
protected Actor target;
protected Transform transform;
protected Renderer renderer;
protected bool is2d = false;
private float durationValue = 0;
private float dtrValue = 0;
private bool isRunning = false;


public virtual Action clone()
{
return new Action();
}
public ActionInstant()
{
}


public virtual bool isRunning()
{
return false;
}
/// <summary>
/// Returns a copy of the action.
/// </summary>
public virtual ActionInstant clone()
{
return new ActionInstant();
}


/// <summary>
/// This method is called at the action start. Usable for instant and interval actions.
/// </summary>
public virtual Action reverse()
{
throw new Exception("Can reverse only the reversable interval actions");
}
/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public virtual ActionInstant reverse()
{
throw new Exception("Can reverse only the reversable interval actions");
}


/// <summary>
/// This method is called at the action start. Usable for instant and interval actions.
/// </summary>
public virtual void start()
{
if (target == null)
throw new Exception("Can start the action only after it's atached to the actor");
transform = target.gameObject.transform;
renderer = target.gameObject.renderer;
}
/// <summary>
/// This method is called at the action start. Usable for instant and interval actions.
/// </summary>
public virtual void start()
{
if (target == null)
throw new Exception("Can start the action only after it's atached to the actor");
transform = target.transformCached;
renderer = target.rendererCached;
}


/// <summary>
/// This method is called at every frame update. Not usable for instant actions.
/// </summary>
public virtual void step(float dt)
{
if (target == null)
throw new Exception("Can update the action only after it's atached to the actor");
}
/// <summary>
/// This method is called at every frame update. Not usable for instant actions.
/// </summary>
public virtual void step(float dt)
{
if (target == null)
throw new Exception("Can update the action only after it's atached to the actor");
}


/// <summary>
/// This method is called after the interval action is stopped. Not usable for instant actions.
/// </summary>
public virtual void stop()
{
if (target == null)
throw new Exception("Can stop the action only after it's atached to the actor");
}
/// <summary>
/// This method is called after the interval action is stopped. Not usable for instant actions.
/// </summary>
public virtual void stop()
{
if (target == null)
throw new Exception("Can stop the action only after it's atached to the actor");
}


public void setActor(Actor actor)
{
target = actor;
}
/// <summary>
/// This method sets the actor for the action.
/// </summary>
public void setActor(Actor actor)
{
target = actor;
}


public virtual float dtr
{
get
/// <summary>
/// Readonly property. Shows the remaining time of the action.
/// </summary>
public float duration
{
get
{
return durationValue;
}

protected set
{
durationValue = value;
}
}

/// <summary>
/// Readonly property. Shows if the action is running or not.
/// </summary>
public bool running
{ {
return 0;
get
{
return isRunning;
}

protected set
{
isRunning = value;
}
} }


protected set
/// <summary>
/// Readonly property. Contains the remaining tick time after action finished.
/// </summary>
public float dtr
{ {
get
{
return dtrValue;
}

protected set
{
dtrValue = value;
}
} }
} }

} }

+ 75
- 79
src/ActionsBase/ActionInterval.cs View File

@@ -2,102 +2,98 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionInterval : Action
namespace coa4u
{ {
protected float timer;
protected float timeScale;
protected bool running;
private float dtrdata;

public ActionInterval(float tgtDuration)
: base()
{
duration = tgtDuration;
timeScale = 1F;
dtr = 0;
}

public override Action clone()
{
return new ActionInterval(duration);
}

public override Action reverse()
{
throw new Exception("Can reverse only the reversable interval actions");
}

public override bool isRunning()
{
return running;
}

public override void start()
{
base.start();
running = true;
timer = 0F;
}

public override void stop()
{
base.stop();
running = false;
}

/// <summary> /// <summary>
/// Step method for interval actions. Don't override this method, when inheriting, put your code in stepInterval instead.
/// Interval action class for subclassing.
/// </summary> /// </summary>
public override void step(float dt)
public class ActionInterval : ActionInstant
{ {
dt *= timeScale;
base.step(dt);
if (timer + dt > duration)
protected float timer;
protected float timeScale;
private float dtrdata;

public ActionInterval(float tgtDuration)
: base()
{ {
float odt = dt;
dt = duration - timer;
timer += odt;
duration = tgtDuration;
timeScale = 1F;
dtr = 0;
} }
else

/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{ {
timer += dt;
return new ActionInterval(duration);
} }
stepInterval(dt);
if (timer > duration)

/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{ {
stop();
dtr = timer - duration;
throw new Exception("Can reverse only the reversable interval actions");
} }
}


/// <summary>
/// Step method for interval actions. Put your code here.
/// </summary>
public virtual void stepInterval(float dt)
{
}
/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{
base.start();
running = true;
timer = 0F;
}


/// <summary>
/// Property to get the remaining tick time after the action has ended.
/// </summary>
public override float dtr
{
get
/// <summary>
/// This method is called after the interval action is stopped.
/// </summary>
public override void stop()
{ {
return dtrdata;
base.stop();
running = false;
} }


protected set
/// <summary>
/// This method is called every frame update. Don't override this method, when inheriting, put your code in stepInterval instead.
/// </summary>
public override void step(float dt)
{ {
dtrdata = value;
dt *= timeScale;
base.step(dt);
if (timer + dt > duration)
{
float odt = dt;
dt = duration - timer;
timer += odt;
}
else
{
timer += dt;
}
stepInterval(dt);
if (timer > duration)
{
stop();
dtr = timer - duration;
}
} }
}


/// <summary>
/// Immediately changes the time scale for this action and all nested ones.
/// </summary>
public void setTimeScale(float ts)
{
timeScale = ts;
/// <summary>
/// This method is called every frame update. Put your code here.
/// </summary>
public virtual void stepInterval(float dt)
{
}

/// <summary>
/// Immediately changes the time scale for this action and all nested ones.
/// </summary>
public void setTimeScale(float ts)
{
timeScale = ts;
}
} }
} }

+ 77
- 56
src/ActionsBase/ActionParallel.cs View File

@@ -2,84 +2,105 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionParallel : ActionInterval
namespace coa4u
{ {
protected Action[] actions;

public ActionParallel(Action action1, Action action2)
: base(0)
{
actions = new Action[] {action1, action2};
}

public ActionParallel(Action[] actionsList)
: base(0)
/// <summary>
/// Runs several actions at the same time.
/// </summary>
public class ActionParallel : ActionInterval
{ {
actions = actionsList;
protected ActionInstant[] actions;


}

public override Action clone()
{
Action[] aList = new Action[actions.Length];
for (int i = 0; i < actions.Length; i++)
public ActionParallel(ActionInstant action1, ActionInstant action2)
: base(0)
{ {
aList[i] = actions[i].clone();
actions = new ActionInstant[] { action1, action2 };
} }
return new ActionSequence(aList);
}


public override Action reverse()
{
Action[] aList = new Action[actions.Length];
for (int i = 0; i < actions.Length; i++)
public ActionParallel(ActionInstant[] actionsList)
: base(0)
{ {
aList[i] = actions[i].reverse();
actions = actionsList;

} }
return new ActionSequence(aList);
}


public override void start()
{
base.start();
for (int i = 0; i < actions.Length; i++)
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{ {
actions[i].setActor(target);
actions[i].start();
ActionInstant[] aList = new ActionInstant[actions.Length];
for (int i = 0; i < actions.Length; i++)
{
aList[i] = actions[i].clone();
}
return new ActionSequence(aList);
} }
}


public override void step(float dt)
{
dt *= timeScale;
for (int i = 0; i < actions.Length; i++)
/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{ {
if (actions[i].isRunning())
actions[i].step(dt);
ActionInstant[] aList = new ActionInstant[actions.Length];
for (int i = 0; i < actions.Length; i++)
{
aList[i] = actions[i].reverse();
}
return new ActionSequence(aList);
} }
bool canStopNow = true;
float dtrdata = 0;
for (int i = 0; i < actions.Length; i++)

/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{ {
if (actions[i].isRunning())
base.start();
for (int i = 0; i < actions.Length; i++)
{ {
canStopNow = false;
dtrdata = Math.Max(actions[i].dtr, dtrdata);
actions[i].setActor(target);
actions[i].start();
} }
} }
if (canStopNow)

/// <summary>
/// This method is called every frame update.
/// </summary>
public override void step(float dt)
{ {
stop();
dtr = dtrdata;
dt *= timeScale;
for (int i = 0; i < actions.Length; i++)
{
if (actions[i].running)
actions[i].step(dt);
}
bool canStopNow = true;
float dtrdata = 0;
for (int i = 0; i < actions.Length; i++)
{
if (actions[i].running)
{
canStopNow = false;
dtrdata = Math.Max(actions[i].dtr, dtrdata);
}
}
if (canStopNow)
{
stop();
dtr = dtrdata;
}
} }
}


public override void stop()
{
base.stop();
for (int i = 0; i < actions.Length; i++)
/// <summary>
/// This method is called after the interval action is stopped.
/// </summary>
public override void stop()
{ {
actions[i].stop();
base.stop();
for (int i = 0; i < actions.Length; i++)
{
actions[i].stop();
}
} }
} }
} }

+ 68
- 47
src/ActionsBase/ActionRandom.cs View File

@@ -2,68 +2,89 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionRandom : ActionInterval
namespace coa4u
{ {
/// <summary>
/// Runs one random action from the given list.
/// </summary>
class ActionRandom : ActionInterval
{


protected Action[] actions;
protected int index;
protected ActionInstant[] actions;
protected int index;


public ActionRandom(Action action1, Action action2)
: base(0)
{
actions = new Action[] {action1, action2};
}
public ActionRandom(ActionInstant action1, ActionInstant action2)
: base(0)
{
actions = new ActionInstant[] { action1, action2 };
}


public ActionRandom(Action[] actionsList)
: base(0)
{
actions = actionsList;
public ActionRandom(ActionInstant[] actionsList)
: base(0)
{
actions = actionsList;


}
}


public override Action clone()
{
Action[] aList = new Action[actions.Length];
for (int i = 0; i < actions.Length; i++)
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{ {
aList[i] = actions[i].clone();
ActionInstant[] aList = new ActionInstant[actions.Length];
for (int i = 0; i < actions.Length; i++)
{
aList[i] = actions[i].clone();
}
return new ActionRandom(aList);
} }
return new ActionRandom(aList);
}


public override Action reverse()
{
Action[] aList = new Action[actions.Length];
for (int i = 0; i < actions.Length; i++)
/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{ {
aList[i] = actions[i].reverse();
ActionInstant[] aList = new ActionInstant[actions.Length];
for (int i = 0; i < actions.Length; i++)
{
aList[i] = actions[i].reverse();
}
return new ActionRandom(aList);
} }
return new ActionRandom(aList);
}


public override void start()
{
base.start();
index = UnityEngine.Random.Range(0, actions.Length);
actions[index].setActor(target);
actions[index].start();
}
/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{
base.start();
index = UnityEngine.Random.Range(0, actions.Length);
actions[index].setActor(target);
actions[index].start();
}


public override void step(float dt)
{
dt *= timeScale;
if (actions[index].isRunning())
actions[index].step(dt);
if (!actions[index].isRunning())
/// <summary>
/// This method is called every frame update.
/// </summary>
public override void step(float dt)
{ {
stop();
dtr = actions[index].dtr;
dt *= timeScale;
if (actions[index].running)
actions[index].step(dt);
if (!actions[index].running)
{
stop();
dtr = actions[index].dtr;
}
} }
}


public override void stop()
{
base.stop();
actions[index].stop();
/// <summary>
/// This method is called after the interval action is stopped.
/// </summary>
public override void stop()
{
base.stop();
actions[index].stop();
}
} }
} }

+ 68
- 50
src/ActionsBase/ActionRepeat.cs View File

@@ -2,68 +2,86 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionRepeat : ActionInterval
namespace coa4u
{ {
protected ActionInterval action;
protected int count;
protected int counter;
protected bool forever;

public ActionRepeat(ActionInterval tgtAction, int tgtCount)
: base(0)
/// <summary>
/// Runs the given action the several times. Also can repeat the action forever.
/// </summary>
class ActionRepeat : ActionInterval
{ {
action = tgtAction;
count = tgtCount;
counter = 0;
forever = false;
}

public ActionRepeat(ActionInterval tgtAction)
: base(0)
{
action = tgtAction;
count = 0;
counter = 0;
forever = true;
}
protected ActionInterval action;
protected int count;
protected int counter;
protected bool forever;


public override Action clone()
{
return new ActionRepeat((ActionInterval) action.clone(), count);
}
public ActionRepeat(ActionInterval tgtAction, int tgtCount)
: base(0)
{
action = tgtAction;
count = tgtCount;
counter = 0;
forever = false;
}


public override Action reverse()
{
return new ActionRepeat((ActionInterval) action.reverse(), count);
}
public ActionRepeat(ActionInterval tgtAction)
: base(0)
{
action = tgtAction;
count = 0;
counter = 0;
forever = true;
}


public override void start()
{
base.start();
action.setActor(target);
action.start();
counter = 0;
}
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionRepeat((ActionInterval)action.clone(), count);
}


public override void step(float dt)
{
dt *= timeScale;
if (action.isRunning())
/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{ {
action.step(dt);
return new ActionRepeat((ActionInterval)action.reverse(), count);
} }
if (!action.isRunning() && (forever || counter < count - 1))

/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{ {
float dtrdata = action.dtr;
base.start();
action.setActor(target);
action.start(); action.start();
if (dtrdata > 0)
action.step(dtrdata);
counter += 1;
counter = 0;
} }
else if (!action.isRunning() && counter >= count - 1)

/// <summary>
/// This method is called every frame update.
/// </summary>
public override void step(float dt)
{ {
dtr = action.dtr;
stop();
dt *= timeScale;
if (action.running)
{
action.step(dt);
}
if (!action.running && (forever || counter < count - 1))
{
float dtrdata = action.dtr;
action.start();
if (dtrdata > 0)
action.step(dtrdata);
counter += 1;
}
else if (!action.running && counter >= count - 1)
{
dtr = action.dtr;
stop();
}
} }
} }
} }

+ 84
- 63
src/ActionsBase/ActionSequence.cs View File

@@ -2,89 +2,110 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionSequence : ActionInterval
namespace coa4u
{ {
protected Action[] actions;
protected int index;

public ActionSequence(Action action1, Action action2)
: base(0)
/// <summary>
/// Runs several actions in a sequence.
/// </summary>
class ActionSequence : ActionInterval
{ {
actions = new Action[] {action1, action2};
}
protected ActionInstant[] actions;
protected int index;


public ActionSequence(Action[] actionsList)
: base(0)
{
actions = actionsList;

}

public override Action clone()
{
Action[] aList = new Action[actions.Length];
for (int i = 0; i < actions.Length; i++)
public ActionSequence(ActionInstant action1, ActionInstant action2)
: base(0)
{ {
aList[i] = actions[i].clone();
actions = new ActionInstant[] { action1, action2 };
} }
return new ActionSequence(aList);
}


public override Action reverse()
{
Action[] aList = new Action[actions.Length];
for (int i = 0; i < actions.Length; i++)
public ActionSequence(ActionInstant[] actionsList)
: base(0)
{ {
aList[actions.Length - 1 - i] = actions[i].reverse();
actions = actionsList;

} }
return new ActionSequence(aList);
}


public override void start()
{
base.start();
index = 0;
actions[0].setActor(target);
actions[0].start();
while (!actions[index].isRunning() && index < actions.Length)
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{ {
index += 1;
actions[index].setActor(target);
actions[index].start();
ActionInstant[] aList = new ActionInstant[actions.Length];
for (int i = 0; i < actions.Length; i++)
{
aList[i] = actions[i].clone();
}
return new ActionSequence(aList);
} }
}


public override void step(float dt)
{
dt *= timeScale;
float dtrdata = 0;
if (actions[index].isRunning())
/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{ {
actions[index].step(dt);
if (!actions[index].isRunning())
dtrdata = actions[index].dtr;
ActionInstant[] aList = new ActionInstant[actions.Length];
for (int i = 0; i < actions.Length; i++)
{
aList[actions.Length - 1 - i] = actions[i].reverse();
}
return new ActionSequence(aList);
} }
while (!actions[index].isRunning() && index < actions.Length - 1)

/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{ {
index += 1;
actions[index].setActor(target);
actions[index].start();
if (actions[index].isRunning() && dtrdata > 0)
actions[index].step(dtrdata);
base.start();
index = 0;
actions[0].setActor(target);
actions[0].start();
while (!actions[index].running && index < actions.Length)
{
index += 1;
actions[index].setActor(target);
actions[index].start();
}
} }
if (!actions[index].isRunning())

/// <summary>
/// This method is called every frame update.
/// </summary>
public override void step(float dt)
{ {
stop();
dtr = dtrdata;
dt *= timeScale;
float dtrdata = 0;
if (actions[index].running)
{
actions[index].step(dt);
if (!actions[index].running)
dtrdata = actions[index].dtr;
}
while (!actions[index].running && index < actions.Length - 1)
{
index += 1;
actions[index].setActor(target);
actions[index].start();
if (actions[index].running && dtrdata > 0)
actions[index].step(dtrdata);
}
if (!actions[index].running)
{
stop();
dtr = dtrdata;
}
} }
}


public override void stop()
{
base.stop();
for (int i = 0; i < actions.Length; i++)
/// <summary>
/// This method is called after the interval action is stopped.
/// </summary>
public override void stop()
{ {
actions[i].stop();
base.stop();
for (int i = 0; i < actions.Length; i++)
{
actions[i].stop();
}
} }
} }
} }

+ 34
- 0
src/ActionsBase/ActionStop.cs View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using UnityEngine;

namespace coa4u
{
/// <summary>
/// This action stops all actions for the current target.
/// </summary>
class ActionStop : ActionInstant
{
public ActionStop()
: base()
{
}

/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionStop();
}

/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{
base.start();
target.StopAction();
}
}
}

+ 33
- 13
src/ActionsInstant/ActionHide.cs View File

@@ -2,22 +2,42 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionHide : Action
namespace coa4u
{ {

public ActionHide()
: base()
/// <summary>
/// Instantly hides the target. This action does not require the transparency support in shaders.
/// </summary>
class ActionHide : ActionInstant
{ {
}


public override Action clone()
{
return new ActionHide();
}
public ActionHide()
: base()
{
}


public override void start()
{
base.start();
renderer.enabled = false;
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionHide();
}

/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{
return new ActionShow();
}

/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{
base.start();
renderer.enabled = false;
}
} }
} }

+ 36
- 11
src/ActionsInstant/ActionLog.cs View File

@@ -2,19 +2,44 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionLog : Action
namespace coa4u
{ {
string message;
public ActionLog(string tgtMessage)
: base()
/// <summary>
/// Prints a message in Unity debug console.
/// </summary>
class ActionLog : ActionInstant
{ {
message = tgtMessage;
}
string message;


public override void start()
{
base.start();
Debug.Log(message);
public ActionLog(string tgtMessage)
: base()
{
message = tgtMessage;
}

/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionLog(message);
}

/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{
return new ActionLog(message);
}

/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{
base.start();
Debug.Log(message);
}
} }
} }

+ 56
- 29
src/ActionsInstant/ActionSendMessage.cs View File

@@ -2,43 +2,70 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionSendMessage : Action
namespace coa4u
{ {
protected string message;
protected object param;
protected SendMessageOptions options = SendMessageOptions.DontRequireReceiver;
public ActionSendMessage(string tgtMessage)
: base()
/// <summary>
/// Sends the message to the current target. First, it checks the Actor's methods cache.
/// If the receiving method found in cache, it will be called directly without passing the message to the GameObject.
/// If there's no listener in cache, message will be sent GameObject (and Unity does it VERY slow).
/// </summary>
class ActionSendMessage : ActionInstant
{ {
message = tgtMessage;
}
protected string message;
protected object param;
protected SendMessageOptions options = SendMessageOptions.DontRequireReceiver;


public ActionSendMessage(string tgtMessage, object tgtParam)
: base()
{
message = tgtMessage;
param = tgtParam;
}
public ActionSendMessage(string tgtMessage)
: base()
{
message = tgtMessage;
}


public ActionSendMessage(string tgtMessage, object tgtParam, SendMessageOptions tgtOptions)
: base()
{
message = tgtMessage;
param = tgtParam;
options = tgtOptions;
}
public ActionSendMessage(string tgtMessage, object tgtParam)
: base()
{
message = tgtMessage;
param = tgtParam;
}


public override void start()
{
base.start();
if (param != null)
public ActionSendMessage(string tgtMessage, object tgtParam, SendMessageOptions tgtOptions)
: base()
{
message = tgtMessage;
param = tgtParam;
options = tgtOptions;
}

/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{ {
target.SendMessage(message, param);
return new ActionSendMessage(message, param, options);
} }
else

/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{
return new ActionSendMessage(message, param, options);
}

/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{ {
target.SendMessage(message);
base.start();
if (param != null)
{
target.ReceiveMessage(message, param, options);
}
else
{
target.ReceiveMessage(message, options);
}
} }
} }
} }

+ 58
- 0
src/ActionsInstant/ActionSetDirection.cs View File

@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using UnityEngine;

namespace coa4u
{
/// <summary>
/// Instantly rotates the target to face the given point or actor.
/// </summary>
class ActionSetDirection : ActionInstant
{
protected Vector3 value;
protected Actor other;

public ActionSetDirection(Vector3 tgtValue)
: base()
{
value = tgtValue;
}

public ActionSetDirection(Vector2 tgtValue)
: this((Vector3)tgtValue)
{
is2d = true;
}

public ActionSetDirection(Actor tgtActor)
: base()
{
other = tgtActor;
}

/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionSetDirection(value);
}

/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{
base.start();
if (other != null)
{
value = other.transform.position;
}
if (is2d)
{
value.z = transform.position.z;
}
transform.rotation = Quaternion.LookRotation(transform.position - value);
}
}
}

+ 34
- 22
src/ActionsInstant/ActionSetPlace.cs View File

@@ -2,32 +2,44 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionSetPlace : Action
namespace coa4u
{ {
protected Vector3 value;
public ActionSetPlace(Vector3 tgtPlace)
: base()
/// <summary>
/// Instantly moves the target to the given point.
/// </summary>
class ActionSetPlace : ActionInstant
{ {
value = tgtPlace;
}
protected Vector3 value;


public ActionSetPlace(Vector2 tgtPlace)
: this((Vector3) tgtPlace)
{
is2d = true;
}
public ActionSetPlace(Vector3 tgtPlace)
: base()
{
value = tgtPlace;
}


public override Action clone()
{
return new ActionSetPlace(value);
}
public ActionSetPlace(Vector2 tgtPlace)
: this((Vector3)tgtPlace)
{
is2d = true;
}


public override void start()
{
base.start();
if (is2d)
value.z = transform.position.z;
transform.position = value;
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionSetPlace(value);
}

/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{
base.start();
if (is2d)
value.z = transform.position.z;
transform.position = value;
}
} }
} }

+ 31
- 20
src/ActionsInstant/ActionSetRotation.cs View File

@@ -2,31 +2,42 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionSetRotation : Action
namespace coa4u
{ {
protected Vector3 value;
public ActionSetRotation(Vector3 tgtValue)
: base()
/// <summary>
/// Instantly rotates the target.
/// </summary>
class ActionSetRotation : ActionInstant
{ {
value = tgtValue;
}
protected Vector3 value;


public ActionSetRotation(float angle)
: this(new Vector3(0, 0, angle))
{
is2d = true;
}
public ActionSetRotation(Vector3 tgtValue)
: base()
{
value = tgtValue;
}


public override Action clone()
{
return new ActionSetRotation(value);
}
public ActionSetRotation(float angle)
: this(new Vector3(0, 0, angle))
{
is2d = true;
}


public override void start()
{
base.start();
transform.rotation = Quaternion.Euler(value);
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionSetRotation(value);
}


/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{
base.start();
transform.rotation = Quaternion.Euler(value);
}
} }
} }

+ 29
- 12
src/ActionsInstant/ActionSetTint.cs View File

@@ -2,20 +2,37 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionSetTint : Action
namespace coa4u
{ {
public Vector4 color;
protected const float coeff = 1F / 255F;

public ActionSetTint(Vector4 tgtColor)
: base()
/// <summary>
/// Instantly tints the target to the given color.
/// </summary>
class ActionSetTint : ActionInstant
{ {
color = tgtColor * coeff;
}
public Vector4 color;
protected const float coeff = 1F / 255F;


public override void start()
{
base.start();
renderer.material.color = new Color(color[0], color[1], color[2], color[3]);
public ActionSetTint(Vector4 tgtColor)
: base()
{
color = tgtColor * coeff;
}

/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionSetTint(color * 255F);
}

/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{
base.start();
renderer.material.color = new Color(color[0], color[1], color[2], color[3]);
}
} }
} }

+ 33
- 13
src/ActionsInstant/ActionShow.cs View File

@@ -2,22 +2,42 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionShow : Action
namespace coa4u
{ {

public ActionShow()
: base()
/// <summary>
/// Instantly shows the hidden target. This action does not require the transparency support in shaders.
/// </summary>
class ActionShow : ActionInstant
{ {
}


public override Action clone()
{
return new ActionShow();
}
public ActionShow()
: base()
{
}


public override void start()
{
base.start();
renderer.enabled = true;
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionShow();
}

/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{
return new ActionHide();
}

/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{
base.start();
renderer.enabled = true;
}
} }
} }

+ 34
- 9
src/ActionsInstant/ActionToggleVisibility.cs View File

@@ -2,17 +2,42 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionToggleVisibility : Action
namespace coa4u
{ {

public ActionToggleVisibility()
: base()
/// <summary>
/// Instantly hides the target or showes it, if it's hidden. This action does not require the transparency support in shaders.
/// </summary>
class ActionToggleVisibility : ActionInstant
{ {
}


public override void start()
{
base.start();
renderer.enabled = !renderer.enabled;
public ActionToggleVisibility()
: base()
{
}

/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionToggleVisibility();
}

/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{
return new ActionToggleVisibility();
}

/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{
base.start();
renderer.enabled = !renderer.enabled;
}
} }
} }

+ 62
- 44
src/ActionsInterval/ActionBezierAbs.cs View File

@@ -2,58 +2,76 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionBezierAbs : ActionInterval
namespace coa4u
{ {
protected Vector3 startPoint;
protected Vector3 endPoint;
protected Vector3 startControlPoint;
protected Vector3 endControlPoint;

public ActionBezierAbs(Vector3 tgtStart, Vector3 tgtSCP, Vector3 tgtECP, Vector3 tgtEnd, float tgtDuration)
: base(tgtDuration)
/// <summary>
/// Moves the target with a cubic Bezier in absolute coordinates (if the target is not in the start point, it'll be positioned there when the action starts).
/// </summary>
class ActionBezierAbs : ActionInterval
{ {
startPoint = tgtStart;
endPoint = tgtEnd;
startControlPoint = tgtSCP;
endControlPoint = tgtECP;
}
protected Vector3 startPoint;
protected Vector3 endPoint;
protected Vector3 startControlPoint;
protected Vector3 endControlPoint;


public ActionBezierAbs(Vector2 tgtStart, Vector2 tgtSCP, Vector2 tgtECP, Vector2 tgtEnd, float tgtDuration)
: this((Vector3) tgtStart, (Vector3) tgtSCP, (Vector3) tgtECP, (Vector3) tgtEnd, tgtDuration)
{
is2d = true;
}
public ActionBezierAbs(Vector3 tgtStart, Vector3 tgtSCP, Vector3 tgtECP, Vector3 tgtEnd, float tgtDuration)
: base(tgtDuration)
{
startPoint = tgtStart;
endPoint = tgtEnd;
startControlPoint = tgtSCP;
endControlPoint = tgtECP;
}


public override Action clone()
{
return new ActionBezierAbs(startPoint, startControlPoint, endControlPoint, endPoint, duration);
}
public ActionBezierAbs(Vector2 tgtStart, Vector2 tgtSCP, Vector2 tgtECP, Vector2 tgtEnd, float tgtDuration)
: this((Vector3)tgtStart, (Vector3)tgtSCP, (Vector3)tgtECP, (Vector3)tgtEnd, tgtDuration)
{
is2d = true;
}


public override Action reverse()
{
return new ActionBezierAbs(endPoint, endControlPoint, startControlPoint, startPoint, duration);
}
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionBezierAbs(startPoint, startControlPoint, endControlPoint, endPoint, duration);
}


public override void start()
{
base.start();
float z = transform.position.z;
if (is2d)
/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{ {
startPoint.z = z;
endPoint.z = z;
startControlPoint.z = z;
endControlPoint.z = z;
return new ActionBezierAbs(endPoint, endControlPoint, startControlPoint, startPoint, duration);
} }
}


public override void stepInterval(float dt)
{
float t = timer / duration;
Vector3 newPosition = (((-startPoint
+ 3 * (startControlPoint - endControlPoint) + endPoint) * t
+ (3 * (startPoint + endControlPoint) - 6 * startControlPoint)) * t +
3 * (startControlPoint - startPoint)) * t + startPoint;
transform.position = newPosition;
/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{
base.start();
float z = transform.position.z;
if (is2d)
{
startPoint.z = z;
endPoint.z = z;
startControlPoint.z = z;
endControlPoint.z = z;
}
}

/// <summary>
/// This method is called every frame update.
/// </summary>
public override void stepInterval(float dt)
{
float t = timer / duration;
Vector3 newPosition = (((-startPoint
+ 3 * (startControlPoint - endControlPoint) + endPoint) * t
+ (3 * (startPoint + endControlPoint) - 6 * startControlPoint)) * t +
3 * (startControlPoint - startPoint)) * t + startPoint;
transform.position = newPosition;
}
} }
} }

+ 62
- 44
src/ActionsInterval/ActionBezierRel.cs View File

@@ -2,56 +2,74 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionBezierRel : ActionInterval
namespace coa4u
{ {
protected Vector3 ep;
protected Vector3 cp1;
protected Vector3 cp2;
protected Vector3 startPoint;
protected Vector3 endPoint;
protected Vector3 startControlPoint;
protected Vector3 endControlPoint;

public ActionBezierRel(Vector3 tgtSCP, Vector3 tgtECP, Vector3 tgtEnd, float tgtDuration)
: base(tgtDuration)
/// <summary>
/// Moves the target with a cubic Bezier in relative coordinates.
/// </summary>
class ActionBezierRel : ActionInterval
{ {
ep = tgtEnd;
cp1 = tgtSCP;
cp2 = tgtECP;
}
protected Vector3 ep;
protected Vector3 cp1;
protected Vector3 cp2;
protected Vector3 startPoint;
protected Vector3 endPoint;
protected Vector3 startControlPoint;
protected Vector3 endControlPoint;


public ActionBezierRel(Vector2 tgtSCP, Vector2 tgtECP, Vector2 tgtEnd, float tgtDuration)
: this((Vector3)tgtSCP, (Vector3)tgtECP, (Vector3)tgtEnd, tgtDuration)
{
is2d = true;
}
public ActionBezierRel(Vector3 tgtSCP, Vector3 tgtECP, Vector3 tgtEnd, float tgtDuration)
: base(tgtDuration)
{
ep = tgtEnd;
cp1 = tgtSCP;
cp2 = tgtECP;
}


public override Action clone()
{
return new ActionBezierRel(startControlPoint, endControlPoint, endPoint, duration);
}
public ActionBezierRel(Vector2 tgtSCP, Vector2 tgtECP, Vector2 tgtEnd, float tgtDuration)
: this((Vector3)tgtSCP, (Vector3)tgtECP, (Vector3)tgtEnd, tgtDuration)
{
is2d = true;
}


public override Action reverse()
{
return new ActionBezierRel(-startControlPoint, -endControlPoint, -endPoint, duration);
}
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionBezierRel(startControlPoint, endControlPoint, endPoint, duration);
}


public override void start()
{
base.start();
startPoint = target.transform.position;
endPoint = startPoint + ep;
startControlPoint = startPoint + cp1;
endControlPoint = startControlPoint + cp2;
}
/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{
return new ActionBezierRel(-startControlPoint, -endControlPoint, -endPoint, duration);
}


public override void stepInterval(float dt)
{
float t = timer / duration;
Vector3 newPosition = (((-startPoint
+ 3 * (startControlPoint - endControlPoint) + endPoint) * t
+ (3 * (startPoint + endControlPoint) - 6 * startControlPoint)) * t +
3 * (startControlPoint - startPoint)) * t + startPoint;
transform.position = newPosition;
/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{
base.start();
startPoint = target.transform.position;
endPoint = startPoint + ep;
startControlPoint = startPoint + cp1;
endControlPoint = startControlPoint + cp2;
}

/// <summary>
/// This method is called every frame update.
/// </summary>
public override void stepInterval(float dt)
{
float t = timer / duration;
Vector3 newPosition = (((-startPoint
+ 3 * (startControlPoint - endControlPoint) + endPoint) * t
+ (3 * (startPoint + endControlPoint) - 6 * startControlPoint)) * t +
3 * (startControlPoint - startPoint)) * t + startPoint;
transform.position = newPosition;
}
} }
} }

+ 43
- 31
src/ActionsInterval/ActionBlink.cs View File

@@ -2,49 +2,61 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionBlink : ActionRepeat
namespace coa4u
{ {
protected bool randomDelay;
protected ActionDelay delay = new ActionDelay(0);
protected Action[] blinkSeq;
protected float durationMin;
protected float durationMax;

public ActionBlink(int tgtBlinks, float tgtDuration)
: base(null, 0)
/// <summary>
/// Blinks the target.
/// </summary>
class ActionBlink : ActionRepeat
{ {
durationMin = tgtDuration;
durationMax = tgtDuration;
count = (tgtBlinks) * 2;
blinkSeq = new Action[]
protected bool randomDelay;
protected ActionDelay delay = new ActionDelay(0);
protected ActionInstant[] blinkSeq;
protected float durationMin;
protected float durationMax;

public ActionBlink(int tgtBlinks, float tgtDuration)
: base(null, 0)
{
durationMin = tgtDuration;
durationMax = tgtDuration;
count = (tgtBlinks) * 2;
blinkSeq = new ActionInstant[]
{ {
new ActionToggleVisibility(), new ActionToggleVisibility(),
new ActionDelay(tgtDuration / tgtBlinks) new ActionDelay(tgtDuration / tgtBlinks)
}; };
action = new ActionSequence(blinkSeq);
}
action = new ActionSequence(blinkSeq);
}


public ActionBlink(int tgtBlinks, float tgtDurationMin, float tgtDurationMax)
: base(null, 0)
{
durationMin = tgtDurationMin;
durationMax = tgtDurationMax;
count = (tgtBlinks) * 2;
blinkSeq = new Action[]
public ActionBlink(int tgtBlinks, float tgtDurationMin, float tgtDurationMax)
: base(null, 0)
{
durationMin = tgtDurationMin;
durationMax = tgtDurationMax;
count = (tgtBlinks) * 2;
blinkSeq = new ActionInstant[]
{ {
new ActionToggleVisibility(), new ActionToggleVisibility(),
new ActionDelay(tgtDurationMin / tgtBlinks, tgtDurationMax / tgtBlinks) new ActionDelay(tgtDurationMin / tgtBlinks, tgtDurationMax / tgtBlinks)
}; };
action = new ActionSequence(blinkSeq);
}
action = new ActionSequence(blinkSeq);
}


public override Action clone()
{
return new ActionBlink(count / 2 - 1, durationMin, durationMax);
}
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionBlink(count / 2 - 1, durationMin, durationMax);
}


public override Action reverse()
{
return new ActionBlink(count / 2 - 1, durationMin, durationMax);
/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{
return new ActionBlink(count / 2 - 1, durationMin, durationMax);
}
} }
} }

+ 29
- 20
src/ActionsInterval/ActionDelay.cs View File

@@ -2,31 +2,40 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionDelay : ActionInterval
namespace coa4u
{ {
protected float durationMin;
protected float durationMax;

public ActionDelay(float tgtDuration)
: base(tgtDuration)
/// <summary>
/// Delays the action for the given amount of seconds.
/// </summary>
class ActionDelay : ActionInterval
{ {
durationMin = tgtDuration;
durationMax = tgtDuration;
}
protected float durationMin;
protected float durationMax;


public ActionDelay(float tgtDuration, float tgtDurationMax)
: base(tgtDuration)
{
durationMin = tgtDuration;
durationMax = tgtDurationMax;
}
public ActionDelay(float tgtDuration)
: base(tgtDuration)
{
durationMin = tgtDuration;
durationMax = tgtDuration;
}


public override void start()
{
base.start();
if (durationMax != null)
public ActionDelay(float tgtDuration, float tgtDurationMax)
: base(tgtDuration)
{
durationMin = tgtDuration;
durationMax = tgtDurationMax;
}

/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{ {
duration = UnityEngine.Random.Range(durationMin, durationMax);
base.start();
if (durationMax != null)
{
duration = UnityEngine.Random.Range(durationMin, durationMax);
}
} }
} }
} }

+ 36
- 21
src/ActionsInterval/ActionFadeBy.cs View File

@@ -2,31 +2,46 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionFadeBy : ActionInterval
namespace coa4u
{ {
protected float delta;
public ActionFadeBy(float tgtDelta, float tgtDuration)
: base(tgtDuration)
/// <summary>
/// Fades the target by the given alpha value. The tartet shaders should support transparency in order to use this action.
/// </summary>
class ActionFadeBy : ActionInterval
{ {
delta = tgtDelta;
}
protected float delta;


public override Action clone()
{
return new ActionFadeBy(delta, duration);
}
public ActionFadeBy(float tgtDelta, float tgtDuration)
: base(tgtDuration)
{
delta = tgtDelta;
}


public override Action reverse()
{
return new ActionFadeBy(-delta, duration);
}
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionFadeBy(delta, duration);
}


public override void stepInterval(float dt)
{
float d = dt / duration;
Color tgtColor = renderer.material.color;
tgtColor[3] += delta * d;
renderer.material.color = tgtColor;
/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{
return new ActionFadeBy(-delta, duration);
}

/// <summary>
/// This method is called every frame update.
/// </summary>
public override void stepInterval(float dt)
{
float d = dt / duration;
Color tgtColor = renderer.material.color;
tgtColor[3] += delta * d;
renderer.material.color = tgtColor;
}
} }
} }

+ 24
- 12
src/ActionsInterval/ActionFadeIn.cs View File

@@ -2,21 +2,33 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionFadeIn : ActionFadeTo
namespace coa4u
{ {

public ActionFadeIn(float tgtDuration)
: base(1, tgtDuration)
/// <summary>
/// Fades in the target. The tartet shaders should support transparency in order to use this action.
/// </summary>
class ActionFadeIn : ActionFadeTo
{ {
}


public override Action clone()
{
return new ActionFadeIn(duration);
}
public ActionFadeIn(float tgtDuration)
: base(1, tgtDuration)
{
}


public override Action reverse()
{
return new ActionFadeIn(duration);
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionFadeIn(duration);
}

/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{
return new ActionFadeOut(duration);
}
} }
} }

+ 24
- 12
src/ActionsInterval/ActionFadeOut.cs View File

@@ -2,21 +2,33 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionFadeOut : ActionFadeTo
namespace coa4u
{ {

public ActionFadeOut(float tgtDuration)
: base(0, tgtDuration)
/// <summary>
/// Fades out the target. The tartet shaders should support transparency in order to use this action.
/// </summary>
class ActionFadeOut : ActionFadeTo
{ {
}


public override Action clone()
{
return new ActionFadeOut(duration);
}
public ActionFadeOut(float tgtDuration)
: base(0, tgtDuration)
{
}


public override Action reverse()
{
return new ActionFadeOut(duration);
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionFadeOut(duration);
}

/// <summary>
/// Returns the reversed version of the action, if it is possible.
/// </summary>
public override ActionInstant reverse()
{
return new ActionFadeIn(duration);
}
} }
} }

+ 38
- 23
src/ActionsInterval/ActionFadeTo.cs View File

@@ -2,33 +2,48 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionFadeTo : ActionInterval
namespace coa4u
{ {
protected float value;
protected float delta;

public ActionFadeTo(float tgtValue, float tgtDuration)
: base(tgtDuration)
/// <summary>
/// Fades the target to the given alpha value. The tartet shaders should support transparency in order to use this action.
/// </summary>
class ActionFadeTo : ActionInterval
{ {
value = tgtValue;
}
protected float value;
protected float delta;


public override Action clone()
{
return new ActionFadeTo(value, duration);
}
public ActionFadeTo(float tgtValue, float tgtDuration)
: base(tgtDuration)
{
value = tgtValue;
}


public override void start()
{
base.start();
delta = value - renderer.material.color.a;
}
/// <summary>
/// Returns a copy of the action.
/// </summary>
public override ActionInstant clone()
{
return new ActionFadeTo(value, duration);
}


public override void stepInterval(float dt)
{
float d = dt / duration;
Color tgtColor = renderer.material.color;
tgtColor[3] += delta * d;
renderer.material.color = tgtColor;
/// <summary>
/// This method is called at the action start.
/// </summary>
public override void start()
{
base.start();
delta = value - renderer.material.color.a;
}

/// <summary>
/// This method is called every frame update.
/// </summary>
public override void stepInterval(float dt)
{
float d = dt / duration;
Color tgtColor = renderer.material.color;
tgtColor[3] += delta * d;
renderer.material.color = tgtColor;
}
} }
} }

+ 38
- 35
src/ActionsInterval/ActionJumpBy.cs View File

@@ -2,48 +2,51 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionJumpBy : ActionSequence
namespace coa4u
{ {
protected Vector3 point;
float height;
int jumps;

public ActionJumpBy(Vector3 tgtPoint, float tgtHeight, int tgtJumps, float tgtDuration)
: base(new Action[tgtJumps])
class ActionJumpBy : ActionSequence
{ {
point = tgtPoint;
jumps = tgtJumps;
height = tgtHeight;
duration = tgtDuration;
}
protected Vector3 point;
float height;
int jumps;


public ActionJumpBy(Vector2 tgtPoint, float tgtHeight, int tgtJumps, float tgtDuration)
: this((Vector3)tgtPoint, tgtHeight, tgtJumps, tgtDuration)
{
is2d = true;
}
public ActionJumpBy(Vector3 tgtPoint, float tgtHeight, int tgtJumps, float tgtDuration)
: base(new ActionInstant[tgtJumps])
{
point = tgtPoint;
jumps = tgtJumps;
height = tgtHeight;
duration = tgtDuration;
}


public override Action clone()
{
return new ActionJumpBy(point, height, jumps, duration);
}
public ActionJumpBy(Vector2 tgtPoint, float tgtHeight, int tgtJumps, float tgtDuration)
: this((Vector3)tgtPoint, tgtHeight, tgtJumps, tgtDuration)
{
is2d = true;
}


public override Action reverse()
{
return new ActionJumpBy(-point, height, jumps, duration);
}
public override ActionInstant clone()
{
return new ActionJumpBy(point, height, jumps, duration);
}


public override void start()
{
float coeff = 1F / jumps;
Vector3 end = point * coeff;
Vector3 cp1 = Vector3.up * height;
Vector3 cp2 = end + cp1;
ActionBezierRel singleJump = new ActionBezierRel(cp1, cp2, end, duration * coeff);
for (int i = 0; i < jumps; i++)
public override ActionInstant reverse()
{
return new ActionJumpBy(-point, height, jumps, duration);
}

public override void start()
{ {
actions[i] = singleJump;
float coeff = 1F / jumps;
Vector3 end = point * coeff;
Vector3 cp1 = Vector3.up * height;
Vector3 cp2 = end + cp1;
ActionBezierRel singleJump = new ActionBezierRel(cp1, cp2, end, duration * coeff);
for (int i = 0; i < jumps; i++)
{
actions[i] = singleJump;
}
base.start();
} }
base.start();
} }
} }

+ 37
- 34
src/ActionsInterval/ActionJumpTo.cs View File

@@ -2,46 +2,49 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionJumpTo : ActionSequence
namespace coa4u
{ {
protected Vector3 point;
float height;
int jumps;

public ActionJumpTo(Vector3 tgtPoint, float tgtHeight, int tgtJumps, float tgtDuration)
: base(new Action[tgtJumps])
class ActionJumpTo : ActionSequence
{ {
point = tgtPoint;
jumps = tgtJumps;
height = tgtHeight;
duration = tgtDuration;
}
protected Vector3 point;
float height;
int jumps;


public ActionJumpTo(Vector2 tgtPoint, float tgtHeight, int tgtJumps, float tgtDuration)
: this((Vector3)tgtPoint, tgtHeight, tgtJumps, tgtDuration)
{
is2d = true;
}
public ActionJumpTo(Vector3 tgtPoint, float tgtHeight, int tgtJumps, float tgtDuration)
: base(new ActionInstant[tgtJumps])
{
point = tgtPoint;
jumps = tgtJumps;
height = tgtHeight;
duration = tgtDuration;
}


public override Action clone()
{
return new ActionJumpTo(point, height, jumps, duration);
}
public ActionJumpTo(Vector2 tgtPoint, float tgtHeight, int tgtJumps, float tgtDuration)
: this((Vector3)tgtPoint, tgtHeight, tgtJumps, tgtDuration)
{
is2d = true;
}


public override void start()
{
float coeff = 1F / jumps;
if (is2d)
point.z = transform.position.z;
Vector3 start = target.gameObject.transform.position;
Vector3 end = (point - start) * coeff;
Vector3 cp1 = Vector3.up * height;
Vector3 cp2 = end + cp1;
ActionBezierRel singleJump = new ActionBezierRel(cp1, cp2, end, duration * coeff);
for (int i = 0; i < jumps; i++)
public override ActionInstant clone()
{
return new ActionJumpTo(point, height, jumps, duration);
}

public override void start()
{ {
actions[i] = singleJump;
float coeff = 1F / jumps;
if (is2d)
point.z = transform.position.z;
Vector3 start = target.gameObject.transform.position;
Vector3 end = (point - start) * coeff;
Vector3 cp1 = Vector3.up * height;
Vector3 cp2 = end + cp1;
ActionBezierRel singleJump = new ActionBezierRel(cp1, cp2, end, duration * coeff);
for (int i = 0; i < jumps; i++)
{
actions[i] = singleJump;
}
base.start();
} }
base.start();
} }
} }

+ 28
- 25
src/ActionsInterval/ActionMoveBy.cs View File

@@ -2,36 +2,39 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionMoveBy : ActionInterval
namespace coa4u
{ {
protected Vector3 delta;

public ActionMoveBy(Vector3 tgtDelta, float tgtDuration)
: base(tgtDuration)
class ActionMoveBy : ActionInterval
{ {
delta = tgtDelta;
}
protected Vector3 delta;


public ActionMoveBy(Vector2 tgtValue, float tgtDuration)
: this((Vector3) tgtValue, tgtDuration)
{
is2d = true;
}
public ActionMoveBy(Vector3 tgtDelta, float tgtDuration)
: base(tgtDuration)
{
delta = tgtDelta;
}


public override Action clone()
{
return new ActionMoveBy(delta, duration);
}
public ActionMoveBy(Vector2 tgtValue, float tgtDuration)
: this((Vector3)tgtValue, tgtDuration)
{
is2d = true;
}


public override Action reverse()
{
return new ActionMoveBy(delta * -1F, duration);
}
public override ActionInstant clone()
{
return new ActionMoveBy(delta, duration);
}


public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = delta * d;
transform.Translate(tgt, Space.World);
public override ActionInstant reverse()
{
return new ActionMoveBy(delta * -1F, duration);
}

public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = delta * d;
transform.Translate(tgt, Space.World);
}
} }
} }

+ 32
- 29
src/ActionsInterval/ActionMoveTo.cs View File

@@ -2,40 +2,43 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionMoveTo : ActionInterval
namespace coa4u
{ {
protected Vector3 value;
protected Vector3 path;

public ActionMoveTo(Vector3 tgtValue, float tgtDuration)
: base(tgtDuration)
class ActionMoveTo : ActionInterval
{ {
value = tgtValue;
}
protected Vector3 value;
protected Vector3 path;


public ActionMoveTo(Vector2 tgtValue, float tgtDuration)
: this((Vector3) tgtValue, tgtDuration)
{
is2d = true;
}
public ActionMoveTo(Vector3 tgtValue, float tgtDuration)
: base(tgtDuration)
{
value = tgtValue;
}


public override Action clone()
{
return new ActionMoveBy(value, duration);
}
public ActionMoveTo(Vector2 tgtValue, float tgtDuration)
: this((Vector3)tgtValue, tgtDuration)
{
is2d = true;
}


public override void start()
{
base.start();
if (is2d)
value.z = transform.position.z;
path = value - transform.position;
}
public override ActionInstant clone()
{
return new ActionMoveBy(value, duration);
}


public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = path * d;
transform.Translate(tgt, Space.World);
public override void start()
{
base.start();
if (is2d)
value.z = transform.position.z;
path = value - transform.position;
}

public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = path * d;
transform.Translate(tgt, Space.World);
}
} }
} }

+ 28
- 25
src/ActionsInterval/ActionRotateBy.cs View File

@@ -2,36 +2,39 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionRotateBy : ActionInterval
namespace coa4u
{ {
protected Vector3 delta;

public ActionRotateBy(Vector3 tgtDelta, float tgtDuration)
: base(tgtDuration)
class ActionRotateBy : ActionInterval
{ {
delta = tgtDelta;
}
protected Vector3 delta;


public ActionRotateBy(float angle, float tgtDuration)
: this(new Vector3(0, 0, angle), tgtDuration)
{
is2d = true;
}
public ActionRotateBy(Vector3 tgtDelta, float tgtDuration)
: base(tgtDuration)
{
delta = tgtDelta;
}


public override Action clone()
{
return new ActionRotateBy(delta, duration);
}
public ActionRotateBy(float angle, float tgtDuration)
: this(new Vector3(0, 0, angle), tgtDuration)
{
is2d = true;
}


public override Action reverse()
{
return new ActionRotateBy(delta * -1F, duration);
}
public override ActionInstant clone()
{
return new ActionRotateBy(delta, duration);
}


public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = delta * d;
transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles + tgt);
public override ActionInstant reverse()
{
return new ActionRotateBy(delta * -1F, duration);
}

public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = delta * d;
transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles + tgt);
}
} }
} }

+ 37
- 34
src/ActionsInterval/ActionRotateTo.cs View File

@@ -2,46 +2,49 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionRotateTo : ActionInterval
namespace coa4u
{ {
protected Vector3 value;
protected Vector3 path;

public ActionRotateTo(Vector3 tgtValue, float tgtDuration)
: base(tgtDuration)
class ActionRotateTo : ActionInterval
{ {
value = tgtValue;
}
protected Vector3 value;
protected Vector3 path;


public ActionRotateTo(float angle, float tgtDuration)
: this(new Vector3(0, 0, angle), tgtDuration)
{
is2d = true;
}
public ActionRotateTo(Vector3 tgtValue, float tgtDuration)
: base(tgtDuration)
{
value = tgtValue;
}


public override Action clone()
{
return new ActionRotateTo(value, duration);
}
public ActionRotateTo(float angle, float tgtDuration)
: this(new Vector3(0, 0, angle), tgtDuration)
{
is2d = true;
}


public override void start()
{
base.start();
path = new Vector3();
for (int i = 0; i < 3; i++)
public override ActionInstant clone()
{ {
float t = value[i];
float f = transform.rotation.eulerAngles[i];
if (Math.Abs(t - f) < Math.Abs(t + 360 - f))
path[i] = t - f;
else
path[i] = t + 360 - f;
return new ActionRotateTo(value, duration);
}

public override void start()
{
base.start();
path = new Vector3();
for (int i = 0; i < 3; i++)
{
float t = value[i];
float f = transform.rotation.eulerAngles[i];
if (Math.Abs(t - f) < Math.Abs(t + 360 - f))
path[i] = t - f;
else
path[i] = t + 360 - f;
}
}
public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = path * d;
transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles + tgt);
} }
}
public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = path * d;
transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles + tgt);
} }
} }

+ 48
- 45
src/ActionsInterval/ActionScaleBy.cs View File

@@ -2,52 +2,55 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionScaleBy : ActionInterval
namespace coa4u
{ {
protected Vector3 delta;
protected Vector3 path;

public ActionScaleBy(Vector3 tgtDelta, float tgtDuration)
: base(tgtDuration)
{
delta = tgtDelta;
}

public ActionScaleBy(Vector2 tgtValue, float tgtDuration)
: this((Vector3)tgtValue, tgtDuration)
{
is2d = true;
}

public override Action clone()
{
return new ActionScaleBy(delta, duration);
}

public override Action reverse()
{
return new ActionScaleBy(delta * -1F, duration);
}

public override void start()
{
base.start();
Vector3 scale = transform.localScale;
scale.x *= delta.x;
scale.y *= delta.y;
scale.z *= delta.z;
path = scale - transform.localScale;
}

public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = path * d;
transform.localScale += tgt;
}

public override void stop()
class ActionScaleBy : ActionInterval
{ {
base.stop();
protected Vector3 delta;
protected Vector3 path;

public ActionScaleBy(Vector3 tgtDelta, float tgtDuration)
: base(tgtDuration)
{
delta = tgtDelta;
}

public ActionScaleBy(Vector2 tgtValue, float tgtDuration)
: this((Vector3)tgtValue, tgtDuration)
{
is2d = true;
}

public override ActionInstant clone()
{
return new ActionScaleBy(delta, duration);
}

public override ActionInstant reverse()
{
return new ActionScaleBy(delta * -1F, duration);
}

public override void start()
{
base.start();
Vector3 scale = transform.localScale;
scale.x *= delta.x;
scale.y *= delta.y;
scale.z *= delta.z;
path = scale - transform.localScale;
}

public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = path * d;
transform.localScale += tgt;
}

public override void stop()
{
base.stop();
}
} }
} }

+ 32
- 29
src/ActionsInterval/ActionScaleTo.cs View File

@@ -2,40 +2,43 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionScaleTo : ActionInterval
namespace coa4u
{ {
protected Vector3 value;
protected Vector3 path;

public ActionScaleTo(Vector3 tgtValue, float tgtDuration)
: base(tgtDuration)
class ActionScaleTo : ActionInterval
{ {
value = tgtValue;
}
protected Vector3 value;
protected Vector3 path;


public ActionScaleTo(Vector2 tgtValue, float tgtDuration)
: this((Vector3) tgtValue, tgtDuration)
{
is2d = true;
}
public ActionScaleTo(Vector3 tgtValue, float tgtDuration)
: base(tgtDuration)
{
value = tgtValue;
}


public override Action clone()
{
return new ActionScaleTo(value, duration);
}
public ActionScaleTo(Vector2 tgtValue, float tgtDuration)
: this((Vector3)tgtValue, tgtDuration)
{
is2d = true;
}


public override void start()
{
base.start();
if (is2d)
value.z = transform.localScale.z;
path = value - transform.localScale;
}
public override ActionInstant clone()
{
return new ActionScaleTo(value, duration);
}


public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = path * d;
transform.localScale += tgt;
public override void start()
{
base.start();
if (is2d)
value.z = transform.localScale.z;
path = value - transform.localScale;
}

public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = path * d;
transform.localScale += tgt;
}
} }
} }

+ 34
- 31
src/ActionsInterval/ActionSkewBy.cs View File

@@ -2,44 +2,47 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionSkewBy : ActionInterval
namespace coa4u
{ {
protected Vector3 skewAngles1;
protected Vector3 skewAngles2;
protected Mesh mesh;

public ActionSkewBy(Vector3 tgtAngles1, Vector3 tgtAngles2, float tgtDuration)
: base(tgtDuration)
class ActionSkewBy : ActionInterval
{ {
skewAngles1 = tgtAngles1;
skewAngles2 = tgtAngles2;
}
protected Vector3 skewAngles1;
protected Vector3 skewAngles2;
protected Mesh mesh;


public override Action clone()
{
return new ActionSkewBy(skewAngles1, skewAngles2, duration);
}
public ActionSkewBy(Vector3 tgtAngles1, Vector3 tgtAngles2, float tgtDuration)
: base(tgtDuration)
{
skewAngles1 = tgtAngles1;
skewAngles2 = tgtAngles2;
}


public override Action reverse()
{
return new ActionSkewBy(-skewAngles1, -skewAngles2, duration);
}
public override ActionInstant clone()
{
return new ActionSkewBy(skewAngles1, skewAngles2, duration);
}


public override void start()
{
base.start();
if (!(target is MeshActor))
public override ActionInstant reverse()
{ {
throw new Exception("You should use MeshActor class instead of Actor, if you want to skew your object.");
return new ActionSkewBy(-skewAngles1, -skewAngles2, duration);
} }
}


public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = skewAngles1 * d;
((MeshActor)target).skewAngles1 += tgt;
tgt = skewAngles2 * d;
((MeshActor)target).skewAngles2 += tgt;
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 stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = skewAngles1 * d;
((Actor)target).skewAngles1 += tgt;
tgt = skewAngles2 * d;
((Actor)target).skewAngles2 += tgt;
}
} }
} }

+ 33
- 30
src/ActionsInterval/ActionTintBy.cs View File

@@ -2,41 +2,44 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionTintBy : ActionInterval
namespace coa4u
{ {
protected Vector4 color;
protected const float coeff = 1F / 255F;

public ActionTintBy(Vector4 tgtColor, float tgtDuration)
: base(tgtDuration)
class ActionTintBy : ActionInterval
{ {
color = tgtColor * coeff;
}
protected Vector4 color;
protected const float coeff = 1F / 255F;


public ActionTintBy(Vector3 tgtColor, float tgtDuration)
: this(new Vector4(tgtColor.x, tgtColor.y, tgtColor.z), tgtDuration)
{
}
public ActionTintBy(Vector4 tgtColor, float tgtDuration)
: base(tgtDuration)
{
color = tgtColor * coeff;
}


public override Action clone()
{
return new ActionTintBy(color / coeff, duration);
}
public ActionTintBy(Vector3 tgtColor, float tgtDuration)
: this(new Vector4(tgtColor.x, tgtColor.y, tgtColor.z), tgtDuration)
{
}


public override Action reverse()
{
return new ActionTintBy(-color / coeff, duration);
}
public override ActionInstant clone()
{
return new ActionTintBy(color / coeff, duration);
}


public override void stepInterval(float dt)
{
float d = dt / duration;
Vector4 tgt = color * d;
Color tgtColor = renderer.material.color;
tgtColor[0] += tgt[0];
tgtColor[1] += tgt[1];
tgtColor[2] += tgt[2];
tgtColor[3] += tgt[3];
renderer.material.color = tgtColor;
public override ActionInstant reverse()
{
return new ActionTintBy(-color / coeff, duration);
}

public override void stepInterval(float dt)
{
float d = dt / duration;
Vector4 tgt = color * d;
Color tgtColor = renderer.material.color;
tgtColor[0] += tgt[0];
tgtColor[1] += tgt[1];
tgtColor[2] += tgt[2];
tgtColor[3] += tgt[3];
renderer.material.color = tgtColor;
}
} }
} }

+ 40
- 37
src/ActionsInterval/ActionTintTo.cs View File

@@ -2,48 +2,51 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;


class ActionTintTo : ActionInterval
namespace coa4u
{ {
protected Vector4 color;
protected Vector4 path;
protected const float coeff = 1F / 255F;

public ActionTintTo(Vector4 tgtColor, float tgtDuration)
: base(tgtDuration)
class ActionTintTo : ActionInterval
{ {
color = tgtColor * coeff;
path = Vector4.zero;
}
protected Vector4 color;
protected Vector4 path;
protected const float coeff = 1F / 255F;


public ActionTintTo(Vector3 tgtColor, float tgtDuration)
: this(new Vector4(tgtColor.x, tgtColor.y, tgtColor.z), tgtDuration)
{
}
public ActionTintTo(Vector4 tgtColor, float tgtDuration)
: base(tgtDuration)
{
color = tgtColor * coeff;
path = Vector4.zero;
}


public override Action clone()
{
return new ActionTintTo(color / coeff, duration);
}
public ActionTintTo(Vector3 tgtColor, float tgtDuration)
: this(new Vector4(tgtColor.x, tgtColor.y, tgtColor.z), tgtDuration)
{
}


public override void start()
{
base.start();
Color tgtColor = renderer.material.color;
path[0] = color[0] - tgtColor[0];
path[1] = color[1] - tgtColor[1];
path[2] = color[2] - tgtColor[2];
path[3] = color[3] - tgtColor[3];
}
public override ActionInstant clone()
{
return new ActionTintTo(color / coeff, duration);
}


public override void stepInterval(float dt)
{
float d = dt / duration;
Vector4 tgt = path * d;
Color tgtColor = renderer.material.color;
tgtColor[0] += tgt[0];
tgtColor[1] += tgt[1];
tgtColor[2] += tgt[2];
tgtColor[3] += tgt[3];
renderer.material.color = tgtColor;
public override void start()
{
base.start();
Color tgtColor = renderer.material.color;
path[0] = color[0] - tgtColor[0];
path[1] = color[1] - tgtColor[1];
path[2] = color[2] - tgtColor[2];
path[3] = color[3] - tgtColor[3];
}

public override void stepInterval(float dt)
{
float d = dt / duration;
Vector4 tgt = path * d;
Color tgtColor = renderer.material.color;
tgtColor[0] += tgt[0];
tgtColor[1] += tgt[1];
tgtColor[2] += tgt[2];
tgtColor[3] += tgt[3];
renderer.material.color = tgtColor;
}
} }
} }

+ 53
- 0
src/CoreClasses/MethodHolder.cs View File

@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using UnityEngine;

namespace coa4u
{
public class MethodHolder
{
protected Action method;
protected string methodName;

public MethodHolder()
{
}

public MethodHolder(Action tgtMethod)
{
method = tgtMethod;
methodName = tgtMethod.Method.Name;
}

public virtual void run(object param = null)
{
if (method != null)
method.Invoke();
}

public string name
{
get
{
return methodName;
}
}
}

public class MethodHolder<T> : MethodHolder
{
protected Action<T> methodParam;

public MethodHolder(Action<T> tgtMethod)
{
methodParam = tgtMethod;
methodName = tgtMethod.Method.Name;
}

public override void run(object param)
{
if (methodParam != null)
methodParam.Invoke((T)param);
}
}
}

+ 125
- 5
src/UnityComponents/Actor.cs View File

@@ -1,42 +1,126 @@
using UnityEngine;
using System;
using UnityEngine;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using coa4u;


/// <summary>
/// The default Actor class for the Action system.
/// </summary>
public class Actor : MonoBehaviour public class Actor : MonoBehaviour
{ {
protected Action action;
protected Dictionary<string, MethodHolder> methodsCache = new Dictionary<string, MethodHolder>();
protected ActionInstant action;
private bool paused = false; private bool paused = false;
protected Vector3 angles1prev = Vector3.zero;
protected Vector3 angles2prev = Vector3.zero;
protected const float coeff = Mathf.PI / 180;
protected Vector3[] initialState;
public Transform transformCached;
public Renderer rendererCached;
public Mesh meshCached;
public Vector3 skewAngles1;
public Vector3 skewAngles2;


/// <summary>
/// This method is called when the script instance is being loaded.
/// </summary>
protected void Awake()
{
transformCached = gameObject.transform;
rendererCached = gameObject.renderer;
meshCached = gameObject.GetComponent<MeshFilter>().mesh;
initialState = meshCached.vertices;
}

/// <summary>
/// This method is called at every frame update.
/// </summary>
protected void Update() protected void Update()
{ {
if (paused || action == null) if (paused || action == null)
return; return;
if (action.isRunning())
if (action.running)
action.step(Time.deltaTime); action.step(Time.deltaTime);
if (skewAngles1 != angles1prev || skewAngles2 != angles2prev)
updateSkew();
}

/// <summary>
/// Updates the skew for the mesh.
/// </summary>
void updateSkew()
{
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)
{
verts[i] = m.MultiplyPoint3x4(initialState[i]);
i++;
}

meshCached.vertices = verts;
angles1prev = skewAngles1;
angles2prev = skewAngles2;
} }


public void AttachAction(Action tgtAction)
/// <summary>
/// Attaches and starts the action.
/// </summary>
public void AttachAction(ActionInstant tgtAction)
{ {
if (action != null)
{
action.stop();
}
action = tgtAction; action = tgtAction;
action.setActor(this); action.setActor(this);
action.start(); action.start();
} }


/// <summary>
/// Stops all running actions for this actor.
/// </summary>
public void StopAction() public void StopAction()
{ {
action.stop();
if (action == null)
return;
if (action.running)
action.stop();
action = null; action = null;
} }


/// <summary>
/// Pauses actions for this actor.
/// </summary>
public void PauseAction() public void PauseAction()
{ {
paused = true; paused = true;
} }


/// <summary>
/// Unpauses actions for this actor.
/// </summary>
public void UnpauseAction() public void UnpauseAction()
{ {
paused = false; paused = false;
} }


/// <summary>
/// Sets the timescale for current action.
/// </summary>
public void SetTimeScale(float ts) public void SetTimeScale(float ts)
{ {
if (action is ActionInterval) if (action is ActionInterval)
@@ -44,4 +128,40 @@ public class Actor : MonoBehaviour
((ActionInterval)action).setTimeScale(ts); ((ActionInterval)action).setTimeScale(ts);
} }
} }

/// <summary>
/// Adds method to cache to speed-up
/// </summary>
public void AddMethodToCache(MethodHolder method)
{
methodsCache.Add(method.name, method);
}

public void RemoveMethodFromCache(string key)
{
if (methodsCache.ContainsKey(key))
{
methodsCache.Remove(key);
}
else
{
throw new Exception("Method " + key + " not found in cache.");
}
}


public void ReceiveMessage(string key, object param = null, SendMessageOptions options = SendMessageOptions.DontRequireReceiver)
{
if (methodsCache.ContainsKey(key))
{
if (param == null)
methodsCache[key].run();
else
methodsCache[key].run(param);
}
else
{
gameObject.SendMessage(key, param, options);
}
}
} }

+ 20
- 5
src/UnityComponents/ActorSampleActions.cs View File

@@ -1,14 +1,15 @@
using UnityEngine; using UnityEngine;
using System.Collections; using System.Collections;
using coa4u;


public class ActorSampleActions : MeshActor
public class ActorSampleActions : Actor
{ {
public void Start() public void Start()
{ {
Action seq = new ActionRepeat (new ActionSequence(new Action[]
ActionInstant seq = new ActionRepeat (new ActionSequence(new ActionInstant[]
{ {
new ActionFadeIn(2), new ActionFadeIn(2),
new ActionParallel(new Action[] {
new ActionParallel(new ActionInstant[] {
new ActionMoveBy(new Vector3(10, 10, 0), 1), new ActionMoveBy(new Vector3(10, 10, 0), 1),
new ActionRotateBy(new Vector3(90, 90, 0), 1), new ActionRotateBy(new Vector3(90, 90, 0), 1),
new ActionTintBy(new Vector4(-50, 50, -150), 1) new ActionTintBy(new Vector4(-50, 50, -150), 1)
@@ -32,9 +33,23 @@ public class ActorSampleActions : MeshActor
new ActionScaleTo(new Vector3(2, 2, 2), 1), new ActionScaleTo(new Vector3(2, 2, 2), 1),
new ActionRotateTo(new Vector3(0, 0, 0), 1), new ActionRotateTo(new Vector3(0, 0, 0), 1),
new ActionFadeOut(2), new ActionFadeOut(2),
new ActionSetTint(new Vector4(67, 105, 181))
new ActionSetTint(new Vector4(67, 105, 181)),
new ActionSendMessage("msgHello"),
new ActionSendMessage("msgHelloTo", "world"),
}), 5); }), 5);
SetTimeScale(2);
this.AttachAction(seq); this.AttachAction(seq);

AddMethodToCache(new MethodHolder(msgHello));
AddMethodToCache(new MethodHolder<string>(msgHelloTo));
}

void msgHello()
{
Debug.Log("Hello!");
}

void msgHelloTo(string who)
{
Debug.Log("Hello " + who.ToString() + "!");
} }
} }

+ 0
- 54
src/UnityComponents/MeshActor.cs View File

@@ -1,54 +0,0 @@
using UnityEngine;
using System.Collections;

[System.Serializable]
public class MeshActor : Actor
{
public Vector3 skewAngles1;
public Vector3 skewAngles2;
protected Vector3 angles1prev = Vector3.zero;
protected Vector3 angles2prev = Vector3.zero;
protected const float coeff = Mathf.PI/180;
protected Mesh mesh;
protected Vector3[] initialState;

void Awake()
{
mesh = gameObject.GetComponent<MeshFilter>().mesh;
initialState = mesh.vertices;
}

protected void Update()
{
base.Update();
if (skewAngles1 != angles1prev || skewAngles2 != angles2prev)
updateMesh();
}

protected void updateMesh()
{
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)
{
verts[i] = m.MultiplyPoint3x4(initialState[i]);
i++;
}

mesh.vertices = verts;
angles1prev = skewAngles1;
angles2prev = skewAngles2;
}
}