using OfficeOpenXml.FormulaParsing.Excel.Functions.Math; using UnityEngine; public class StressReceiver : MonoBehaviour { public float trauma; private float _trauma; private Vector3 _lastPosition; private Vector3 _lastRotation; [Tooltip("Exponent for calculating the shake factor. Useful for creating different effect fade outs")] public float TraumaExponent = 1; [Tooltip("Maximum angle that the gameobject can shake. In euler angles.")] public Vector3 MaximumAngularShake = Vector3.one * 5; [Tooltip("Maximum translation that the gameobject can receive when applying the shake effect.")] public Vector3 MaximumTranslationShake = Vector3.one * .75f; private System.Action callBack; [ContextMenu("asdasda")] public void Test() { InduceStress(trauma,null); } private void Update() { float shake = Mathf.Pow(_trauma, TraumaExponent); /* Only apply this when there is active trauma */ if(shake > 0.01f) { var previousRotation = _lastRotation; var previousPosition = _lastPosition; /* In order to avoid affecting the transform current position and rotation each frame we substract the previous translation and rotation */ _lastPosition = new Vector3( MaximumTranslationShake.x * (Mathf.PerlinNoise(0, Time.time * 25) * 2 - 1), MaximumTranslationShake.y * (Mathf.PerlinNoise(1, Time.time * 25) * 2 - 1), MaximumTranslationShake.z * (Mathf.PerlinNoise(2, Time.time * 25) * 2 - 1) ) * shake; _lastRotation = new Vector3( MaximumAngularShake.x * (Mathf.PerlinNoise(3, Time.time * 25) * 2 - 1), MaximumAngularShake.y * (Mathf.PerlinNoise(4, Time.time * 25) * 2 - 1), MaximumAngularShake.z * (Mathf.PerlinNoise(5, Time.time * 25) * 2 - 1) ) * shake; transform.localPosition += _lastPosition - previousPosition; transform.localRotation = Quaternion.Euler(transform.localRotation.eulerAngles + _lastRotation - previousRotation); _trauma = Mathf.Clamp01(_trauma - Time.deltaTime); } else { if (_lastPosition == Vector3.zero && _lastRotation == Vector3.zero) { callBack?.Invoke(); return; } /* Clear the transform of any left over translation and rotations */ transform.localPosition -= _lastPosition; transform.localRotation = Quaternion.Euler(transform.localRotation.eulerAngles - _lastRotation); _lastPosition = Vector3.zero; _lastRotation = Vector3.zero; callBack?.Invoke(); } } /// /// Applies a stress value to the current object. /// /// [0,1] Amount of stress to apply to the object public void InduceStress(float Stress,System.Action callBack) { this.callBack = callBack; _trauma = Mathf.Clamp01(_trauma + Stress); } }