@@ -1,4 +1,62 @@ | |||
coa4u | |||
===== | |||
## Cocos2d-like Actions for Unity3d | |||
Cocos2d Actions for Unity3d | |||
Unity3d is a very good game engine. It's almost perfect for quick prototyping. | |||
After switching from Cocos2D to Unity3d, i'm still missing just one cocos's feature - actions. | |||
It's a great combination of simplicity and flexibility, and i haven't found the suitable replacement for it. | |||
Since actions are quite simple, i implemented them myself. | |||
### Included actions (ready and WIP) | |||
Base actions | |||
- [x] Sequence | |||
- [x] Parallel | |||
- [x] Repeat and Loop *implemented in one action* | |||
- [ ] Reverse | |||
Interval actions | |||
- [x] MoveTo | |||
- [x] MoveBy | |||
- [x] RotateTo | |||
- [x] RotateBy | |||
- [x] ScaleTo | |||
- [x] ScaleBy | |||
- [x] TintBy | |||
- [x] Delay and RandomDelay *implemented in one action* | |||
- [ ] TintTo | |||
- [ ] FadeOut | |||
- [ ] FadeIn | |||
- [ ] FadeTo | |||
- [ ] JumpTo | |||
- [ ] JumpBy | |||
- [ ] Bezier | |||
- [ ] Blink | |||
Instant actions | |||
- [x] Place *renamed to SetPlace* | |||
- [x] CallFunc *renamed to SendMessage* | |||
- [x] Hide | |||
- [x] Show | |||
- [x] ToggleVisibility | |||
### Some additional actions | |||
Interval actions | |||
- [ ] SkewBy | |||
- [ ] SkewTo | |||
Instant actions | |||
- [x] SetRotation | |||
- [x] SetTint | |||
### Future plans | |||
After completing these actions, i'm going to add some more to the list. | |||
## License | |||
Just like Cocos2D, this code licensed under the [MIT License](http://en.wikipedia.org/wiki/MIT_License) | |||
## Help and donations | |||
I'm not doing it to make profit, but if you want, [you can send me a couple of bucks via PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Z64675TKXFRFU). | |||
Also, if you'll write some action based on mine, feel free to send it to me, if you want me to add it to the library. I'll put your name on this page. |
@@ -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 | |||
{ | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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]); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |