diff --git a/README.md b/README.md index 5c1e61f..9ffd371 100644 --- a/README.md +++ b/README.md @@ -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. \ No newline at end of file diff --git a/src/ActionsBase/Action.cs b/src/ActionsBase/Action.cs new file mode 100644 index 0000000..5fa089f --- /dev/null +++ b/src/ActionsBase/Action.cs @@ -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; + } + + /// + /// This method is called at the action start. Usable for instant and interval actions. + /// + public virtual Action reverse() + { + throw new Exception("Can reverse only the reversable interval actions"); + } + + /// + /// This method is called at the action start. Usable for instant and interval actions. + /// + public virtual void start() + { + if (target == null) + throw new Exception("Can start the action only after it's atached to the actor"); + } + + /// + /// This method is called at every frame update. Not usable for instant actions. + /// + public virtual void step(float dt) + { + if (target == null) + throw new Exception("Can update the action only after it's atached to the actor"); + } + + /// + /// This method is called after the interval action is stopped. Not usable for instant actions. + /// + 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 + { + } + } + +} \ No newline at end of file diff --git a/src/ActionsBase/ActionInterval.cs b/src/ActionsBase/ActionInterval.cs new file mode 100644 index 0000000..ad6c901 --- /dev/null +++ b/src/ActionsBase/ActionInterval.cs @@ -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; + } + + /// + /// Step method for interval actions. Don't override this method, when inheriting, put your code in stepInterval instead. + /// + 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; + } + } + + /// + /// Step method for interval actions. Put your code here. + /// + public virtual void stepInterval(float dt) + { + } + + /// + /// Property to get the remaining tick time after the action has ended. + /// + public override float dtr + { + get + { + return dtrdata; + } + + protected set + { + dtrdata = value; + } + } + + /// + /// Immediately changes the time scale for this action and all nested ones. + /// + public void setTimeScale(float ts) + { + timeScale = ts; + } +} \ No newline at end of file diff --git a/src/ActionsBase/ActionParallel.cs b/src/ActionsBase/ActionParallel.cs new file mode 100644 index 0000000..d038b4d --- /dev/null +++ b/src/ActionsBase/ActionParallel.cs @@ -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(); + } + } +} \ No newline at end of file diff --git a/src/ActionsBase/ActionRepeat.cs b/src/ActionsBase/ActionRepeat.cs new file mode 100644 index 0000000..91e9cee --- /dev/null +++ b/src/ActionsBase/ActionRepeat.cs @@ -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(); + } + } +} \ No newline at end of file diff --git a/src/ActionsBase/ActionSequence.cs b/src/ActionsBase/ActionSequence.cs new file mode 100644 index 0000000..a105ad9 --- /dev/null +++ b/src/ActionsBase/ActionSequence.cs @@ -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(); + } + } +} \ No newline at end of file diff --git a/src/ActionsInstant/ActionHide.cs b/src/ActionsInstant/ActionHide.cs new file mode 100644 index 0000000..ad683f4 --- /dev/null +++ b/src/ActionsInstant/ActionHide.cs @@ -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; + } +} \ No newline at end of file diff --git a/src/ActionsInstant/ActionLog.cs b/src/ActionsInstant/ActionLog.cs new file mode 100644 index 0000000..8c31115 --- /dev/null +++ b/src/ActionsInstant/ActionLog.cs @@ -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); + } +} \ No newline at end of file diff --git a/src/ActionsInstant/ActionSendMessage.cs b/src/ActionsInstant/ActionSendMessage.cs new file mode 100644 index 0000000..a31dbff --- /dev/null +++ b/src/ActionsInstant/ActionSendMessage.cs @@ -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); + } + } +} \ No newline at end of file diff --git a/src/ActionsInstant/ActionSetPlace.cs b/src/ActionsInstant/ActionSetPlace.cs new file mode 100644 index 0000000..10062f2 --- /dev/null +++ b/src/ActionsInstant/ActionSetPlace.cs @@ -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; + } +} \ No newline at end of file diff --git a/src/ActionsInstant/ActionSetRotation.cs b/src/ActionsInstant/ActionSetRotation.cs new file mode 100644 index 0000000..bcf62f2 --- /dev/null +++ b/src/ActionsInstant/ActionSetRotation.cs @@ -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); + } +} \ No newline at end of file diff --git a/src/ActionsInstant/ActionSetTint.cs b/src/ActionsInstant/ActionSetTint.cs new file mode 100644 index 0000000..70dba09 --- /dev/null +++ b/src/ActionsInstant/ActionSetTint.cs @@ -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]); + } +} \ No newline at end of file diff --git a/src/ActionsInstant/ActionShow.cs b/src/ActionsInstant/ActionShow.cs new file mode 100644 index 0000000..e47b567 --- /dev/null +++ b/src/ActionsInstant/ActionShow.cs @@ -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; + } +} \ No newline at end of file diff --git a/src/ActionsInstant/ActionToggleVisibility.cs b/src/ActionsInstant/ActionToggleVisibility.cs new file mode 100644 index 0000000..799f04e --- /dev/null +++ b/src/ActionsInstant/ActionToggleVisibility.cs @@ -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; + } +} \ No newline at end of file diff --git a/src/ActionsInterval/ActionDelay.cs b/src/ActionsInterval/ActionDelay.cs new file mode 100644 index 0000000..296450d --- /dev/null +++ b/src/ActionsInterval/ActionDelay.cs @@ -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); + } + } +} \ No newline at end of file diff --git a/src/ActionsInterval/ActionMoveBy.cs b/src/ActionsInterval/ActionMoveBy.cs new file mode 100644 index 0000000..cfe19b1 --- /dev/null +++ b/src/ActionsInterval/ActionMoveBy.cs @@ -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); + } +} \ No newline at end of file diff --git a/src/ActionsInterval/ActionMoveTo.cs b/src/ActionsInterval/ActionMoveTo.cs new file mode 100644 index 0000000..954cd31 --- /dev/null +++ b/src/ActionsInterval/ActionMoveTo.cs @@ -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); + } +} \ No newline at end of file diff --git a/src/ActionsInterval/ActionRotateBy.cs b/src/ActionsInterval/ActionRotateBy.cs new file mode 100644 index 0000000..5d299f4 --- /dev/null +++ b/src/ActionsInterval/ActionRotateBy.cs @@ -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); + } +} \ No newline at end of file diff --git a/src/ActionsInterval/ActionRotateTo.cs b/src/ActionsInterval/ActionRotateTo.cs new file mode 100644 index 0000000..446c2de --- /dev/null +++ b/src/ActionsInterval/ActionRotateTo.cs @@ -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); + } +} \ No newline at end of file diff --git a/src/ActionsInterval/ActionScaleBy.cs b/src/ActionsInterval/ActionScaleBy.cs new file mode 100644 index 0000000..7270e01 --- /dev/null +++ b/src/ActionsInterval/ActionScaleBy.cs @@ -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(); + } +} \ No newline at end of file diff --git a/src/ActionsInterval/ActionScaleTo.cs b/src/ActionsInterval/ActionScaleTo.cs new file mode 100644 index 0000000..29696d3 --- /dev/null +++ b/src/ActionsInterval/ActionScaleTo.cs @@ -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(); + } +} \ No newline at end of file diff --git a/src/ActionsInterval/ActionTintBy.cs b/src/ActionsInterval/ActionTintBy.cs new file mode 100644 index 0000000..cdc2eec --- /dev/null +++ b/src/ActionsInterval/ActionTintBy.cs @@ -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; + } +} \ No newline at end of file diff --git a/src/Examples/SampleActions.cs b/src/Examples/SampleActions.cs new file mode 100644 index 0000000..6e9f6d5 --- /dev/null +++ b/src/Examples/SampleActions.cs @@ -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); + } +} diff --git a/src/UnityComponents/Actor.cs b/src/UnityComponents/Actor.cs new file mode 100644 index 0000000..3692882 --- /dev/null +++ b/src/UnityComponents/Actor.cs @@ -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); + } + } +} diff --git a/src/UnityComponents/SkewModifier.cs b/src/UnityComponents/SkewModifier.cs new file mode 100644 index 0000000..2348d1b --- /dev/null +++ b/src/UnityComponents/SkewModifier.cs @@ -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().mesh.vertices; + int i = 0; + while (i < verts.Length) + { + verts[i] = m.MultiplyPoint3x4(verts[i]); + i++; + } + + gameObject.GetComponent().mesh.vertices = verts; + angles1prev = angles1; + angles2prev = angles2; + } +}