using System; using UnityEngine; using System.Collections; using System.Collections.Generic; using coa4u; /// /// The default Actor class for the Action system. /// public class Actor : MonoBehaviour { protected Dictionary methodsCache = new Dictionary(); protected ActionInstant action; private bool paused = false; protected Vector3 angles1prev = Vector3.zero; protected Vector3 angles2prev = Vector3.zero; protected const float coeff = Mathf.PI / 180; protected Vector3[] initialState; public Transform transformCached; public Renderer rendererCached; public Mesh meshCached; public Vector3 skewAngles1; public Vector3 skewAngles2; /// /// This method is called when the script instance is being loaded. /// protected void Awake() { transformCached = gameObject.transform; rendererCached = gameObject.renderer; meshCached = gameObject.GetComponent().mesh; initialState = meshCached.vertices; } /// /// This method is called at every frame update. /// protected void Update() { if (paused || action == null) return; if (action.running) action.step(Time.deltaTime); if (skewAngles1 != angles1prev || skewAngles2 != angles2prev) updateSkew(); } /// /// Updates the skew for the mesh. /// void updateSkew() { Matrix4x4 m = Matrix4x4.zero; m[0, 0] = 1; m[1, 1] = 1; m[2, 2] = 1; m[3, 3] = 1; m[0, 1] = Mathf.Tan(skewAngles1.x * coeff); // skewing in xy m[0, 2] = Mathf.Tan(skewAngles2.x * coeff); // skewing in xz m[1, 0] = Mathf.Tan(skewAngles1.y * coeff); // skewing in yx m[1, 2] = Mathf.Tan(skewAngles2.y * coeff); // skewing in yz m[2, 0] = Mathf.Tan(skewAngles1.z * coeff); // skewing in zx m[2, 1] = Mathf.Tan(skewAngles2.z * coeff); // skewing in zy Vector3[] verts = new Vector3[initialState.Length]; int i = 0; while (i < verts.Length) { verts[i] = m.MultiplyPoint3x4(initialState[i]); i++; } meshCached.vertices = verts; angles1prev = skewAngles1; angles2prev = skewAngles2; } /// /// Attaches and starts the action. /// public void AttachAction(ActionInstant tgtAction) { if (action != null) { action.stop(); } action = tgtAction; action.setActor(this); action.start(); } /// /// Stops all running actions for this actor. /// public void StopAction() { if (action == null) return; if (action.running) action.stop(); action = null; } /// /// Pauses actions for this actor. /// public void PauseAction() { paused = true; } /// /// Unpauses actions for this actor. /// public void UnpauseAction() { paused = false; } /// /// Sets the timescale for current action. /// public void SetTimeScale(float ts) { if (action is ActionInterval) { ((ActionInterval)action).setTimeScale(ts); } } /// /// Adds method to cache to speed-up /// public void AddMethodToCache(MethodHolder method) { methodsCache.Add(method.name, method); } public void RemoveMethodFromCache(string key) { if (methodsCache.ContainsKey(key)) { methodsCache.Remove(key); } else { throw new Exception("Method " + key + " not found in cache."); } } public void ReceiveMessage(string key, object param = null, SendMessageOptions options = SendMessageOptions.DontRequireReceiver) { if (methodsCache.ContainsKey(key)) { if (param == null) methodsCache[key].run(); else methodsCache[key].run(param); } else { gameObject.SendMessage(key, param, options); } } }