// add a new key public void addKey(AMITarget itarget, OnAddKey addCall, int _frame, Vector3 _position, int _interp, int _easeType) { foreach (AMTranslationKey key in keys) { // if key exists on frame, update key if (key.frame == _frame) { key.position = _position; key.interp = _interp; key.easeType = _easeType; // update cache updateCache(itarget); return; } } AMTranslationKey a = addCall(gameObject, typeof(AMTranslationKey)) as AMTranslationKey; a.frame = _frame; a.position = _position; a.interp = _interp; a.easeType = _easeType; // add a new key keys.Add(a); // update cache updateCache(itarget); }
public static AMPath GenerateLinear(List <AMKey> keys, int _startIndex) { AMPath newPath = new AMPath(); // sort the keys by frame List <Vector3> _path = new List <Vector3>(); newPath.startIndex = _startIndex; newPath.endIndex = _startIndex; newPath.endFrame = keys[_startIndex].frame; _path.Add((keys[_startIndex] as AMTranslationKey).position); int nextIndex = _startIndex + 1; if (nextIndex < keys.Count) { AMTranslationKey key = keys[nextIndex] as AMTranslationKey; _path.Add(key.position); newPath.endFrame = keys[nextIndex].frame; newPath.endIndex = nextIndex; } newPath.interp = (int)AMTranslationKey.Interpolation.Linear; newPath.path = _path.ToArray(); return(newPath); }
public int endIndex; // ending key index public static AMPath GenerateCurve(List <AMKey> keys, int _startIndex) { AMPath newPath = new AMPath(); // sort the keys by frame List <Vector3> _path = new List <Vector3>(); newPath.startIndex = _startIndex; newPath.endIndex = _startIndex; newPath.endFrame = keys[_startIndex].frame; _path.Add((keys[_startIndex] as AMTranslationKey).position); // get path from startIndex until the next linear interpolation key (inclusive) for (int i = _startIndex + 1; i < keys.Count; i++) { AMTranslationKey key = keys[i] as AMTranslationKey; _path.Add(key.position); newPath.endFrame = keys[i].frame; newPath.endIndex = i; if (!keys[_startIndex].canTween || key.interp != (int)AMTranslationKey.Interpolation.Curve) { break; } } newPath.interp = (int)AMTranslationKey.Interpolation.Curve; newPath.path = _path.ToArray(); return(newPath); }
// copy properties from key public override void CopyTo(AMKey key) { base.CopyTo(key); AMTranslationKey a = key as AMTranslationKey; a.position = position; a.isConstSpeed = isConstSpeed; }
// copy properties from key public override void CopyTo(AMKey key) { AMTranslationKey a = key as AMTranslationKey; a.enabled = false; a.frame = frame; a.position = position; a.interp = interp; a.easeType = easeType; a.customEase = new List <float>(customEase); a.isConstSpeed = isConstSpeed; }
// update cache (optimized) public override void updateCache(AMITarget target) { base.updateCache(target); // get all paths and add them to the action list for (int i = 0; i < keys.Count; i++) { AMTranslationKey key = keys[i] as AMTranslationKey; int interp = key.interp; int easeType = key.easeType; key.version = version; AMPath path = new AMPath(keys, i); key.endFrame = path.endFrame; key.pathPreview = null; if (!key.canTween) { if (path.endIndex == keys.Count - 1) { AMTranslationKey lastKey = keys[path.endIndex] as AMTranslationKey; lastKey.interp = (int)AMTranslationKey.Interpolation.None; lastKey.endFrame = lastKey.frame; lastKey.path = new Vector3[0]; } } else { key.path = path.path; } //invalidate some keys in between if (path.startIndex < keys.Count - 1) { for (i = path.startIndex + 1; i <= path.endIndex - 1; i++) { key = keys[i] as AMTranslationKey; key.version = version; key.interp = interp; key.easeType = easeType; key.endFrame = key.frame; key.path = new Vector3[0]; } i = path.endIndex - 1; } } }
// update cache (optimized) public override void updateCache(AMITarget target) { base.updateCache(target); // get all paths and add them to the action list for (int i = 0; i < keys.Count; i++) { AMTranslationKey key = keys[i] as AMTranslationKey; int interp = key.interp; int easeType = key.easeType; key.version = version; AMPath path; switch ((AMTranslationKey.Interpolation)key.interp) { case AMKey.Interpolation.Curve: path = AMPath.GenerateCurve(keys, i); break; case AMKey.Interpolation.Linear: path = AMPath.GenerateLinear(keys, i); break; default: path = AMPath.GenerateSingle(keys[i], i); break; } key.endFrame = path.endFrame; key.pathPreview = null; if (!key.canTween) { if (path.endIndex == keys.Count - 1) { AMTranslationKey lastKey = keys[path.endIndex] as AMTranslationKey; lastKey.interp = (int)AMTranslationKey.Interpolation.None; lastKey.endFrame = lastKey.frame; lastKey.path = new Vector3[0]; } } else { key.path = path.path; } //invalidate some keys in between if (path.startIndex < keys.Count - 1) { int _endInd = path.endIndex; if (_endInd < keys.Count - 1) { _endInd--; } for (i = path.startIndex + 1; i <= _endInd; i++) { key = keys[i] as AMTranslationKey; key.version = version; key.interp = interp; key.easeType = easeType; key.endFrame = key.frame; key.path = new Vector3[0]; } i = _endInd; } } }
public Vector3 getPositionAtFrame(Transform t, int frame, int frameRate, bool forceWorld) { int keyCount = keys.Count; if (keyCount <= 0) { return(GetPosition(t)); } AMTranslationKey firstKey = keys[0] as AMTranslationKey; //check if behind first key if (frame <= firstKey.frame && (!firstKey.canTween || firstKey.path.Length == 1)) { return(convertPosition(t, firstKey.position, forceWorld)); } AMTranslationKey lastKey = keyCount == 1 ? firstKey : keys[keyCount - 1] as AMTranslationKey; //check if past last key if (frame >= lastKey.endFrame && !lastKey.canTween) { return(convertPosition(t, lastKey.position, forceWorld)); } //check in-between for (int i = 0; i < keyCount; i++) { AMTranslationKey key = keys[i] as AMTranslationKey; AMTranslationKey keyNext = i < keyCount - 1 ? keys[i + 1] as AMTranslationKey : null; if (frame >= key.endFrame && keyNext != null && (!keyNext.canTween || keyNext.path.Length > 1)) { continue; } if (!key.canTween || key.path.Length == 1) { return(convertPosition(t, key.position, forceWorld)); } else if (key.path.Length == 0) { continue; } float fNumFrames = (float)key.getNumberOfFrames(frameRate); float _value; float framePositionInPath = Mathf.Clamp(frame - (float)key.frame, 0f, fNumFrames); if (key.hasCustomEase()) { _value = AMUtil.EaseCustom(0.0f, 1.0f, framePositionInPath / fNumFrames, key.easeCurve); } else { var ease = AMUtil.GetEasingFunction((Ease)key.easeType); _value = ease(framePositionInPath, fNumFrames, key.amplitude, key.period); if (float.IsNaN(_value)) //this really shouldn't happen... { break; } } return(convertPosition(t, key.GetPoint(Mathf.Clamp01(_value)), forceWorld)); } Debug.LogError("Animator: Could not get " + t.name + " position at frame '" + frame + "'"); return(GetPosition(t)); }
// preview a frame in the scene view public override void previewFrame(AMITarget itarget, float frame, int frameRate, bool play, float playSpeed) { Transform t = GetTarget(itarget) as Transform; if (!t) { return; } int keyCount = keys.Count; if (keys == null || keyCount <= 0) { return; } int iFrame = Mathf.RoundToInt(frame); AMTranslationKey firstKey = keys[0] as AMTranslationKey; //check if behind first key if (iFrame <= firstKey.frame && (!firstKey.canTween || firstKey.path.Length == 1)) { SetPosition(t, firstKey.position); return; } AMTranslationKey lastKey = keyCount == 1 ? firstKey : keys[keyCount - 1] as AMTranslationKey; //check if past last key if (iFrame >= lastKey.endFrame && !lastKey.canTween) { SetPosition(t, lastKey.position); return; } //check in-between for (int i = 0; i < keyCount; i++) { AMTranslationKey key = keys[i] as AMTranslationKey; if (iFrame >= key.endFrame && i < keyCount - 1) { continue; } if (!key.canTween || key.path.Length == 1) { SetPosition(t, key.position); return; } else if (key.path.Length == 0) { continue; } float fNumFrames = (float)key.getNumberOfFrames(frameRate); float _value; float framePositionInPath = Mathf.Clamp(frame - (float)key.frame, 0f, fNumFrames); if (key.hasCustomEase()) { _value = AMUtil.EaseCustom(0.0f, 1.0f, framePositionInPath / fNumFrames, key.easeCurve); } else { var ease = AMUtil.GetEasingFunction((Ease)key.easeType); _value = ease(framePositionInPath, fNumFrames, key.amplitude, key.period); if (float.IsNaN(_value)) //this really shouldn't happen... { return; } } SetPosition(t, key.GetPoint(Mathf.Clamp01(_value))); return; } }