using System.Collections; using System.Collections.Generic; using UnityEngine; namespace Lemon.GenericLib.VFX { //to do: build linear lerping that can change duration public class SquashAndStretch : MonoBehaviour { [SerializeField] private Vector3 squashSize; [SerializeField] private Vector3 stretchSize; [SerializeField] private float transformRate = 10; [SerializeField] private bool useRealative; [SerializeField] private bool forceSnap = false; [SerializeField] private Vector3 snapingMargin = new Vector3(0.001f, 0.001f, 0.001f); public enum SquashMode { lerp, linear, addition } [SerializeField] SquashMode squashMode; [SerializeField] float linearLerpDuration; //if useRealative is enabled the squash size will be the ratio of the original size //rather than the exact size it's self private Vector3 originalSize; private Vector3 targetSize; private float timeElapsed = 0; private Vector3 startSize; // Start is called before the first frame update void Start() { originalSize = transform.localScale; targetSize = originalSize; startSize = originalSize; } Vector3 vectorToLerp = Vector3.zero; // Update is called once per frame void FixedUpdate() { //squash and stretch //if (transform.localScale != targetSize) { if (squashMode == SquashMode.lerp) { transform.localScale = Vector3.Lerp(transform.localScale, targetSize, transformRate * Time.deltaTime); //Debug.Log("squashing " + targetSize); if (forceSnap) { if (targetSize.x - transform.localScale.x <= snapingMargin.x && targetSize.y - transform.localScale.y <= snapingMargin.y && targetSize.z - transform.localScale.z <= snapingMargin.z) { transform.localScale = targetSize; } } } else if (squashMode == SquashMode.linear) { if (timeElapsed < linearLerpDuration) { transform.localScale = Vector3.Lerp(startSize, targetSize, timeElapsed / linearLerpDuration); timeElapsed += Time.deltaTime; } else { if (forceSnap) transform.localScale = targetSize; } } else if (squashMode == SquashMode.addition) { vectorToLerp.x = (transform.localScale.x - targetSize.x) * transformRate * Time.deltaTime; vectorToLerp.y = (transform.localScale.y - targetSize.y) * transformRate * Time.deltaTime; vectorToLerp.z = (transform.localScale.z - targetSize.z) * transformRate * Time.deltaTime; transform.localScale += vectorToLerp; vectorToLerp = transform.localScale; if (vectorToLerp.x >= targetSize.x || vectorToLerp.x <= targetSize.x) { vectorToLerp.x = targetSize.x; } if (vectorToLerp.y >= targetSize.y || vectorToLerp.y <= targetSize.y) { vectorToLerp.y = targetSize.y; } if (vectorToLerp.z >= targetSize.z || vectorToLerp.z <= targetSize.z) { vectorToLerp.z = targetSize.z; } transform.localScale = vectorToLerp; } //} } public void ChnageOriginalSize(Vector3 newSize) { originalSize = newSize; } public void SetToSquash() { if (useRealative) { targetSize = new Vector3(originalSize.x * squashSize.x, originalSize.y * squashSize.y, originalSize.z * squashSize.z); } else { targetSize = squashSize; } //if (squashMode == SquashMode.linear || squashMode == SquashMode.addition) { // timeElapsed = 0; // startSize = transform.localScale; //} } //returns to original size once it is done public void SetToSquash(float duration) { StartCoroutine(SquashTimer(duration)); } public void SetToStretch() { if (useRealative) { targetSize = new Vector3(originalSize.x * stretchSize.x, originalSize.y * stretchSize.y, originalSize.z * stretchSize.z); } else { targetSize = stretchSize; } if (squashMode == SquashMode.linear || squashMode == SquashMode.addition) { timeElapsed = 0; startSize = transform.localScale; } } //returns to original size once it is done public void SetToStretch(float duration) { StartCoroutine(StretchTimer(duration)); } public void customSquish(Vector3 newSize, bool useRealitive = false) { if (useRealitive) { targetSize = new Vector3(originalSize.x * newSize.x, originalSize.y * newSize.y, originalSize.z * newSize.z); } else { //Debug.Log("set target size " + targetSize); targetSize = newSize; } if (squashMode == SquashMode.linear || squashMode == SquashMode.addition) { timeElapsed = 0; startSize = transform.localScale; } } //returns to original size once it is done public void customSquish(Vector3 newSize, float duration, bool useRealitive = false) { StartCoroutine(SquishTimer(newSize, duration, useRealitive)); } //resets back to the original size public void ResetScale() { targetSize = originalSize; } //couroutine used IEnumerator SquashTimer(float duration) { SetToSquash(); yield return new WaitForSeconds(duration); ResetScale(); } IEnumerator StretchTimer(float duration) { SetToStretch(); yield return new WaitForSeconds(duration); ResetScale(); } IEnumerator SquishTimer(Vector3 newSize, float duration, bool useRealitive) { customSquish(newSize, useRealitive); yield return new WaitForSeconds(duration); ResetScale(); } } }