@@ -1,4 +1,62 @@ | |||||
coa4u | 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; | |||||
} | |||||
} |