private void CheckShakeEnd() { if( Time.timeSinceLevelLoad > m_ShakeEndTime ) { this.gameObject.transform.position = m_OrgPosition ; m_State = ShakeState.UnActive ; } }
public void StartShake() { if( m_State == ShakeState.InShake ) return ; m_ShakeStartTime = Time.timeSinceLevelLoad ; m_ShakeEndTime = m_ShakeStartTime + m_ShakeElapsedSec ; m_State = ShakeState.InShake ; m_OrgPosition = this.gameObject.transform.position ; }
private IEnumerator DoShake_Internal(Camera cam, Vector3 seed, int numberOfShakes, Vector3 shakeAmount, Vector3 rotationAmount, float distance, float speed, float decay, float guiShakeModifier, bool multiplyByTimeScale, System.Action callback) { // Wait for async cancel operations to complete if (cancelling) yield return null; // Set random values var mod1 = seed.x > .5f ? 1 : -1; var mod2 = seed.y > .5f ? 1 : -1; var mod3 = seed.z > .5f ? 1 : -1; // First shake if (!shaking) { shaking = true; if (cameraShakeStarted != null) cameraShakeStarted(); } if (shakeCount.ContainsKey(cam)) shakeCount[cam]++; else shakeCount.Add(cam, 1); // Pixel width is always based on the first camera float pixelWidth = GetPixelWidth(cameras[0].transform, cameras[0]); // Set other values Transform cachedTransform = cam.transform; Vector3 camOffset = Vector3.zero; Quaternion camRot = Quaternion.identity; int currentShakes = numberOfShakes; float shakeDistance = distance; float rotationStrength = 1; float startTime = Time.time; float scale = multiplyByTimeScale ? Time.timeScale : 1; float pixelScale = pixelWidth * guiShakeModifier * scale; Vector3 start1 = Vector2.zero; Quaternion startR = Quaternion.identity; Vector2 start2 = Vector2.zero; ShakeState state = new ShakeState(cachedTransform.position, cachedTransform.rotation, new Vector2(shakeRect.x, shakeRect.y)); List<ShakeState> stateList; if (states.TryGetValue(cam, out stateList)) { stateList.Add(state); } else { stateList = new List<ShakeState>(); stateList.Add(state); states.Add(cam, stateList); } // Main loop while (currentShakes > 0) { if (checkForMinimumValues) { // Early break when rotation is less than the minimum value. if (rotationAmount.sqrMagnitude != 0 && rotationStrength <= minRotationValue) break; // Early break when shake amount is less than the minimum value. if (shakeAmount.sqrMagnitude != 0 && distance != 0 && shakeDistance <= minShakeValue) break; } var timer = (Time.time - startTime) * speed; state.shakePosition = start1 + new Vector3( mod1 * Mathf.Sin(timer) * (shakeAmount.x * shakeDistance * scale), mod2 * Mathf.Cos(timer) * (shakeAmount.y * shakeDistance * scale), mod3 * Mathf.Sin(timer) * (shakeAmount.z * shakeDistance * scale)); state.shakeRotation = startR * Quaternion.Euler( mod1 * Mathf.Cos(timer) * (rotationAmount.x * rotationStrength * scale), mod2 * Mathf.Sin(timer) * (rotationAmount.y * rotationStrength * scale), mod3 * Mathf.Cos(timer) * (rotationAmount.z * rotationStrength * scale)); state.guiShakePosition = new Vector2( start2.x - (mod1 * Mathf.Sin(timer) * (shakeAmount.x * shakeDistance * pixelScale)), start2.y - (mod2 * Mathf.Cos(timer) * (shakeAmount.y * shakeDistance * pixelScale))); camOffset = GetGeometricAvg(stateList, true); camRot = GetAvgRotation(stateList); NormalizeQuaternion(ref camRot); Matrix4x4 m = Matrix4x4.TRS(camOffset, camRot, new Vector3(1, 1, -1)); cam.worldToCameraMatrix = m * cachedTransform.worldToLocalMatrix; var avg = GetGeometricAvg(stateList, false); shakeRect.x = avg.x; shakeRect.y = avg.y; if (timer > Mathf.PI * 2) { startTime = Time.time; shakeDistance *= (1 - Mathf.Clamp01(decay)); rotationStrength *= (1 - Mathf.Clamp01(decay)); currentShakes--; } yield return null; } // End conditions shakeCount[cam]--; // Last shake if (shakeCount[cam] == 0) { shaking = false; ResetState(cam.transform, cam); if (allCameraShakesCompleted != null) { allCameraShakesCompleted(); } } else { stateList.Remove(state); } if (callback != null) callback(); }