This commit is contained in:
2014-06-16 00:25:35 +04:00
committed by Ivan "KaiSD" Korystin
parent bb1b24e947
commit 441fa25a19
25 changed files with 1110 additions and 1 deletions

76
src/ActionsBase/Action.cs Normal file
View File

@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using UnityEngine;
public class Action
{
protected Actor target;
public float duration = 0;
public Action()
{
}
public virtual Action clone()
{
return new Action();
}
public virtual bool isRunning()
{
return false;
}
/// <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>
/// 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");
}
/// <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");
}
public void setActor(Actor actor)
{
target = actor;
}
public virtual float dtr
{
get
{
return 0;
}
protected set
{
}
}
}

View File

@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionInterval : Action
{
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>
/// Step method for interval actions. Don't override this method, when inheriting, put your code in stepInterval instead.
/// </summary>
public override void step(float dt)
{
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>
/// Step method for interval actions. Put your code here.
/// </summary>
public virtual void stepInterval(float dt)
{
}
/// <summary>
/// Property to get the remaining tick time after the action has ended.
/// </summary>
public override float dtr
{
get
{
return dtrdata;
}
protected set
{
dtrdata = value;
}
}
/// <summary>
/// Immediately changes the time scale for this action and all nested ones.
/// </summary>
public void setTimeScale(float ts)
{
timeScale = ts;
}
}

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionParallel : ActionInterval
{
protected Action[] actions;
public ActionParallel(Action action1, Action action2)
: base(0)
{
actions = new Action[] {action1, action2};
}
public ActionParallel(Action[] actionsList)
: base(0)
{
actions = actionsList;
}
public override Action clone()
{
Action[] aList = new Action[actions.Length];
for (int i = 0; i < actions.Length; i++)
{
aList[i] = actions[i].clone();
}
return new ActionSequence(aList);
}
public override Action reverse()
{
Action[] aList = new Action[actions.Length];
for (int i = 0; i < actions.Length; i++)
{
aList[i] = actions[i].reverse();
}
return new ActionSequence(aList);
}
public override void start()
{
base.start();
for (int i = 0; i < actions.Length; i++)
{
actions[i].setActor(target);
actions[i].start();
}
}
public override void step(float dt)
{
dt *= timeScale;
for (int i = 0; i < actions.Length; i++)
{
if (actions[i].isRunning())
actions[i].step(dt);
}
bool canStopNow = true;
float dtrdata = 0;
for (int i = 0; i < actions.Length; i++)
{
if (actions[i].isRunning())
{
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++)
{
actions[i].stop();
}
}
}

View File

@@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionRepeat : ActionInterval
{
protected ActionInterval action;
protected int count;
protected int counter;
protected bool forever;
public ActionRepeat(ActionInterval tgtAction, int tgtCount)
: base(0)
{
action = tgtAction;
count = tgtCount;
counter = 0;
forever = false;
}
public ActionRepeat(ActionInterval tgtAction)
: base(0)
{
action = tgtAction;
count = 0;
counter = 0;
forever = true;
}
public override Action clone()
{
return new ActionRepeat((ActionInterval) action.clone(), count);
}
public override Action reverse()
{
return new ActionRepeat((ActionInterval) action.reverse(), count);
}
public override void start()
{
base.start();
action.setActor(target);
action.start();
counter = 0;
}
public override void step(float dt)
{
dt *= timeScale;
if (action.isRunning())
{
action.step(dt);
}
if (!action.isRunning() && (forever || counter < count - 1))
{
float dtrdata = action.dtr;
action.start();
if (dtrdata > 0)
action.step(dtrdata);
counter += 1;
}
else if (!action.isRunning() && counter >= count - 1)
{
dtr = action.dtr;
stop();
}
}
}

View File

@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionSequence : ActionInterval
{
protected Action[] actions;
protected int index;
public ActionSequence(Action action1, Action action2)
: base(0)
{
actions = new Action[] {action1, action2};
}
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++)
{
aList[i] = actions[i].clone();
}
return new ActionSequence(aList);
}
public override Action reverse()
{
Action[] aList = new Action[actions.Length];
for (int i = 0; i < actions.Length; i++)
{
aList[actions.Length - 1 - i] = actions[i].reverse();
}
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)
{
index += 1;
actions[index].setActor(target);
actions[index].start();
}
}
public override void step(float dt)
{
dt *= timeScale;
float dtrdata = 0;
if (actions[index].isRunning())
{
actions[index].step(dt);
if (!actions[index].isRunning())
dtrdata = actions[index].dtr;
}
while (!actions[index].isRunning() && index < actions.Length - 1)
{
index += 1;
actions[index].setActor(target);
actions[index].start();
if (actions[index].isRunning() && dtrdata > 0)
actions[index].step(dtrdata);
}
if (!actions[index].isRunning())
{
stop();
dtr = dtrdata;
}
}
public override void stop()
{
base.stop();
for (int i = 0; i < actions.Length; i++)
{
actions[i].stop();
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionHide : Action
{
public ActionHide()
: base()
{
}
public override Action clone()
{
return new ActionHide();
}
public override void start()
{
base.start();
target.gameObject.renderer.enabled = false;
}
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionLog : Action
{
string message;
public ActionLog(string tgtMessage)
: base()
{
message = tgtMessage;
}
public override void start()
{
base.start();
Debug.Log(message);
}
}

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionSendMessage : Action
{
protected string message;
protected object param;
protected SendMessageOptions options = SendMessageOptions.DontRequireReceiver;
public ActionSendMessage(string tgtMessage)
: base()
{
message = tgtMessage;
}
public ActionSendMessage(string tgtMessage, object tgtParam)
: base()
{
message = tgtMessage;
param = tgtParam;
}
public ActionSendMessage(string tgtMessage, object tgtParam, SendMessageOptions tgtOptions)
: base()
{
message = tgtMessage;
param = tgtParam;
options = tgtOptions;
}
public override void start()
{
base.start();
if (param != null)
{
target.SendMessage(message, param);
}
else
{
target.SendMessage(message);
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionSetPlace : Action
{
protected Vector3 place;
public ActionSetPlace(Vector3 tgtPlace)
: base()
{
place = tgtPlace;
}
public override Action clone()
{
return new ActionSetPlace(place);
}
public override void start()
{
base.start();
target.gameObject.transform.position = place;
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionSetRotation : Action
{
protected Vector3 value;
public ActionSetRotation(Vector3 tgtValue)
: base()
{
value = tgtValue;
}
public override Action clone()
{
return new ActionSetRotation(value);
}
public override void start()
{
base.start();
Vector3 path = new Vector3();
for (int i = 0; i < 3; i++)
{
path[i] = value[i] - target.gameObject.transform.rotation.eulerAngles[i];
}
target.gameObject.transform.Rotate(Vector3.up, path.y);
target.gameObject.transform.Rotate(Vector3.right, path.x);
target.gameObject.transform.Rotate(Vector3.forward, path.z);
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionSetTint : Action
{
public Vector4 color;
protected const float coeff = 1F / 255F;
public ActionSetTint(Vector4 tgtColor)
: base()
{
color = tgtColor * coeff;
}
public override void start()
{
base.start();
target.gameObject.renderer.material.color = new Color(color[0], color[1], color[2], color[3]);
}
}

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionShow : Action
{
public ActionShow()
: base()
{
}
public override Action clone()
{
return new ActionShow();
}
public override void start()
{
base.start();
target.gameObject.renderer.enabled = true;
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionToggleVisibility : Action
{
public ActionToggleVisibility()
: base()
{
}
public override void start()
{
base.start();
target.gameObject.renderer.enabled = !target.gameObject.renderer.enabled;
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionDelay : ActionInterval
{
protected float durationMin;
protected float durationMax;
public ActionDelay(float tgtDuration)
: base(tgtDuration)
{
durationMin = tgtDuration;
durationMax = tgtDuration;
}
public ActionDelay(float tgtDuration, float tgtDurationMax)
: base(tgtDuration)
{
durationMin = tgtDuration;
durationMax = tgtDurationMax;
}
public override void start()
{
base.start();
if (durationMax != null)
{
duration = UnityEngine.Random.Range(durationMin, durationMax);
}
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionMoveBy : ActionInterval
{
protected Vector3 delta;
public ActionMoveBy(Vector3 tgtDelta, float tgtDuration)
: base(tgtDuration)
{
delta = tgtDelta;
}
public override Action clone()
{
return new ActionMoveBy(delta, duration);
}
public override Action reverse()
{
return new ActionMoveBy(delta * -1F, duration);
}
public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = delta * d;
target.gameObject.transform.Translate(tgt, Space.World);
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionMoveTo : ActionInterval
{
protected Vector3 value;
protected Vector3 path;
public ActionMoveTo(Vector3 tgtValue, float tgtDuration)
: base(tgtDuration)
{
value = tgtValue;
}
public override Action clone()
{
return new ActionMoveBy(value, duration);
}
public override void start()
{
base.start();
path = value - target.gameObject.transform.position;
}
public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = path * d;
target.gameObject.transform.Translate(tgt, Space.World);
}
}

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionRotateBy : ActionInterval
{
protected Vector3 delta;
public ActionRotateBy(Vector3 tgtDelta, float tgtDuration)
: base(tgtDuration)
{
delta = tgtDelta;
}
public override Action clone()
{
return new ActionRotateBy(delta, duration);
}
public override Action reverse()
{
return new ActionRotateBy(delta * -1F, duration);
}
public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = delta * d;
target.gameObject.transform.Rotate(Vector3.up, tgt.y);
target.gameObject.transform.Rotate(Vector3.right, tgt.x);
target.gameObject.transform.Rotate(Vector3.forward, tgt.z);
}
}

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionRotateTo : ActionInterval
{
protected Vector3 value;
protected Vector3 path;
public ActionRotateTo(Vector3 tgtValue, float tgtDuration)
: base(tgtDuration)
{
value = tgtValue;
}
public override Action clone()
{
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 = target.gameObject.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;
target.gameObject.transform.Rotate(Vector3.up, tgt.y);
target.gameObject.transform.Rotate(Vector3.right, tgt.x);
target.gameObject.transform.Rotate(Vector3.forward, tgt.z);
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionScaleBy : ActionInterval
{
protected Vector3 delta;
protected Vector3 path;
public ActionScaleBy(Vector3 tgtDelta, float tgtDuration)
: base(tgtDuration)
{
delta = tgtDelta;
}
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 = target.gameObject.transform.localScale;
scale.x *= delta.x;
scale.y *= delta.y;
scale.z *= delta.z;
path = scale - target.gameObject.transform.localScale;
}
public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = path * d;
target.gameObject.transform.localScale += tgt;
}
public override void stop()
{
base.stop();
}
}

View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionScaleTo : ActionInterval
{
protected Vector3 value;
protected Vector3 path;
public ActionScaleTo(Vector3 tgtValue, float tgtDuration)
: base(tgtDuration)
{
value = tgtValue;
}
public override Action clone()
{
return new ActionScaleTo(value, duration);
}
public override void start()
{
base.start();
path = value - target.gameObject.transform.localScale;
}
public override void stepInterval(float dt)
{
float d = dt / duration;
Vector3 tgt = path * d;
target.gameObject.transform.localScale += tgt;
}
public override void stop()
{
base.stop();
}
}

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using UnityEngine;
class ActionTintBy : ActionInterval
{
public Vector4 color;
protected const float coeff = 1F / 255F;
public ActionTintBy(Vector4 tgtColor, float tgtDuration)
: base(tgtDuration)
{
color = tgtColor * coeff;
}
public override Action clone()
{
return new ActionTintBy(color / coeff, duration);
}
public override Action reverse()
{
return new ActionTintBy(-color / coeff, duration);
}
public override void stepInterval(float dt)
{
float d = dt / duration;
Vector4 tgt = color * d;
Color tgtColor = target.gameObject.renderer.material.color;
tgtColor[0] += tgt[0];
tgtColor[1] += tgt[1];
tgtColor[2] += tgt[2];
tgtColor[3] += tgt[3];
target.gameObject.renderer.material.color = tgtColor;
}
}

View File

@@ -0,0 +1,35 @@
using UnityEngine;
using System.Collections;
public class SampleActions : MonoBehaviour
{
public void Start()
{
Action seq = new ActionRepeat (new ActionSequence(new Action[]
{
new ActionTintBy(new Vector4(-50,50,-50,-50),1),
new ActionParallel(new Action[] {
new ActionMoveBy(new Vector3(10, 0, 0), 1),
new ActionMoveBy(new Vector3(0, 10, 0), 1),
// new ActionRotateBy(new Vector3(90, 0, 0), 1)
}),
new ActionScaleBy(new Vector3(2, 2, 1), 1),
new ActionScaleBy(new Vector3(0.5F, 0.5F, 2), 1),
new ActionDelay(1),
new ActionRepeat(new ActionSequence(new Action[] {
new ActionHide(),
new ActionDelay(0F, 0.2F),
new ActionShow(),
new ActionDelay(0F, 0.2F),
}), 5),
new ActionDelay(1),
new ActionMoveBy(new Vector3(-10, 0, 0), 1),
new ActionDelay(0.5F),
new ActionMoveTo(new Vector3(0, 0, 10), 1),
new ActionScaleTo(new Vector3(2, 2, 2), 1),
new ActionRotateTo(new Vector3(0, 0, 0), 1),
new ActionTintBy(new Vector4(50,-50,50,50),3)
}), 5);
gameObject.SendMessage("AttachAction", seq);
}
}

View File

@@ -0,0 +1,47 @@
using UnityEngine;
using System.Collections;
public class Actor : MonoBehaviour
{
protected Action action;
private bool paused = false;
void Update()
{
if (paused || action == null)
return;
if (action.isRunning())
action.step(Time.deltaTime);
}
public void AttachAction(Action tgtAction)
{
action = tgtAction;
action.setActor(this);
action.start();
}
public void StopAction()
{
action.stop();
action = null;
}
public void PauseAction()
{
paused = true;
}
public void UnpauseAction()
{
paused = false;
}
public void SetTimeScale(float ts)
{
if (action is ActionInterval)
{
((ActionInterval)action).setTimeScale(ts);
}
}
}

View File

@@ -0,0 +1,45 @@
using UnityEngine;
using System.Collections;
[System.Serializable]
public class SkewModifier : MonoBehaviour
{
public Vector3 angles1;
public Vector3 angles2;
protected Vector3 angles1prev = Vector3.zero;
protected Vector3 angles2prev = Vector3.zero;
protected const float coeff = Mathf.PI/180;
void Update()
{
if (angles1 != angles1prev || angles2 != 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(angles1.x * coeff) - Mathf.Tan(angles1prev.x * coeff); // skewing in xy
m[0, 2] = Mathf.Tan(angles2.x * coeff) - Mathf.Tan(angles2prev.x * coeff); // skewing in xz
m[1, 0] = Mathf.Tan(angles1.y * coeff) - Mathf.Tan(angles1prev.y * coeff); // skewing in yx
m[1, 2] = Mathf.Tan(angles2.y * coeff) - Mathf.Tan(angles2prev.y * coeff); // skewing in yz
m[2, 0] = Mathf.Tan(angles1.z * coeff) - Mathf.Tan(angles1prev.z * coeff); // skewing in zx
m[2, 1] = Mathf.Tan(angles2.z * coeff) - Mathf.Tan(angles2prev.z * coeff); // skewing in zy
Vector3[] verts = gameObject.GetComponent<MeshFilter>().mesh.vertices;
int i = 0;
while (i < verts.Length)
{
verts[i] = m.MultiplyPoint3x4(verts[i]);
i++;
}
gameObject.GetComponent<MeshFilter>().mesh.vertices = verts;
angles1prev = angles1;
angles2prev = angles2;
}
}