Vector3 ComputeGroupBounds(CinemachineTargetGroup group, ref CameraState curState) { Vector3 cameraPos = curState.RawPosition; Vector3 fwd = curState.RawOrientation * Vector3.forward; // Get the bounding box from camera's direction in view space LastBoundsMatrix = Matrix4x4.TRS(cameraPos, curState.RawOrientation, Vector3.one); Bounds b = group.GetViewSpaceBoundingBox(LastBoundsMatrix); Vector3 groupCenter = LastBoundsMatrix.MultiplyPoint3x4(b.center); float boundsDepth = b.extents.z; if (!curState.Lens.Orthographic) { // Parallax might change bounds - refine float d = (Quaternion.Inverse(curState.RawOrientation) * (groupCenter - cameraPos)).z; cameraPos = groupCenter - fwd * (Mathf.Max(d, boundsDepth) + boundsDepth); // Will adjust cameraPos b = GetScreenSpaceGroupBoundingBox(group, ref cameraPos, curState.RawOrientation); LastBoundsMatrix = Matrix4x4.TRS(cameraPos, curState.RawOrientation, Vector3.one); groupCenter = LastBoundsMatrix.MultiplyPoint3x4(b.center); } LastBounds = b; return(groupCenter - fwd * boundsDepth); }
public override void MutateCameraState(ref CameraState curState, float deltaTime) { CinemachineTargetGroup targetGroup = this.TargetGroup; if (targetGroup == null) { base.MutateCameraState(ref curState, deltaTime); return; } if (!this.IsValid || !curState.HasLookAt) { this.m_prevTargetHeight = 0f; return; } curState.ReferenceLookAt = this.GetLookAtPointAndSetTrackedPoint(targetGroup.transform.position); Vector3 v = base.TrackedPoint - curState.RawPosition; float magnitude = v.magnitude; if (magnitude < 0.0001f) { return; } Vector3 vector = v.AlmostZero() ? Vector3.forward : v.normalized; Bounds boundingBox = targetGroup.BoundingBox; this.m_lastBoundsMatrix = Matrix4x4.TRS(boundingBox.center - vector * boundingBox.extents.magnitude, Quaternion.LookRotation(vector, curState.ReferenceUp), Vector3.one); this.m_LastBounds = targetGroup.GetViewSpaceBoundingBox(this.m_lastBoundsMatrix); float num = this.GetTargetHeight(this.m_LastBounds); Vector3 a = this.m_lastBoundsMatrix.MultiplyPoint3x4(this.m_LastBounds.center); if (deltaTime >= 0f) { float num2 = num - this.m_prevTargetHeight; num2 = Damper.Damp(num2, this.m_FrameDamping, deltaTime); num = this.m_prevTargetHeight + num2; } this.m_prevTargetHeight = num; if (!curState.Lens.Orthographic && this.m_AdjustmentMode != CinemachineGroupComposer.AdjustmentMode.ZoomOnly) { float fieldOfView = curState.Lens.FieldOfView; float num3 = num / (2f * Mathf.Tan(fieldOfView * 0.0174532924f / 2f)) + this.m_LastBounds.extents.z; num3 = Mathf.Clamp(num3, magnitude - this.m_MaxDollyIn, magnitude + this.m_MaxDollyOut); num3 = Mathf.Clamp(num3, this.m_MinimumDistance, this.m_MaximumDistance); curState.PositionCorrection += a - vector * num3 - curState.RawPosition; } if (curState.Lens.Orthographic || this.m_AdjustmentMode != CinemachineGroupComposer.AdjustmentMode.DollyOnly) { float num4 = (base.TrackedPoint - curState.CorrectedPosition).magnitude - this.m_LastBounds.extents.z; float value = 179f; if (num4 > 0.0001f) { value = 2f * Mathf.Atan(num / (2f * num4)) * 57.29578f; } LensSettings lens = curState.Lens; lens.FieldOfView = Mathf.Clamp(value, this.m_MinimumFOV, this.m_MaximumFOV); lens.OrthographicSize = Mathf.Clamp(num / 2f, this.m_MinimumOrthoSize, this.m_MaximumOrthoSize); curState.Lens = lens; } base.MutateCameraState(ref curState, deltaTime); }
static Bounds GetScreenSpaceGroupBoundingBox( CinemachineTargetGroup group, ref Vector3 pos, Quaternion orientation) { Matrix4x4 observer = Matrix4x4.TRS(pos, orientation, Vector3.one); Vector2 minAngles, maxAngles, zRange; group.GetViewSpaceAngularBounds(observer, out minAngles, out maxAngles, out zRange); Quaternion q = Quaternion.identity.ApplyCameraRotation((minAngles + maxAngles) / 2, Vector3.up); Vector3 localPosAdustment = q * new Vector3(0, 0, (zRange.y + zRange.x) / 2); localPosAdustment.z = 0; pos = observer.MultiplyPoint3x4(localPosAdustment); observer = Matrix4x4.TRS(pos, orientation, Vector3.one); group.GetViewSpaceAngularBounds(observer, out minAngles, out maxAngles, out zRange); float zSize = zRange.y - zRange.x; float z = zRange.x + (zSize / 2); Vector2 angles = new Vector2(89.5f, 89.5f); if (zRange.x > 0) { angles = Vector3.Max(maxAngles, UnityVectorExtensions.Abs(minAngles)) * Mathf.Deg2Rad; angles = Vector2.Min(angles, new Vector2(89.5f, 89.5f)); } return(new Bounds(new Vector3(0, 0, z), new Vector3(Mathf.Tan(angles.y) * z * 2, Mathf.Tan(angles.x) * z * 2, zSize))); }
public void RemoveMe() { if (test) { test.RemoveMember(gameObject.transform); test = null; } }
float AdjustCameraDepthAndLensForGroupFraming( CinemachineTargetGroup group, float targetZ, ref CameraState curState, float deltaTime) { float cameraOffset = 0; // Get the bounding box from that POV in view space, and find its height Bounds bounds = group.BoundingBox; Vector3 fwd = curState.RawOrientation * Vector3.forward; m_lastBoundsMatrix = Matrix4x4.TRS( bounds.center - (fwd * bounds.extents.magnitude), curState.RawOrientation, Vector3.one); m_LastBounds = group.GetViewSpaceBoundingBox(m_lastBoundsMatrix); float targetHeight = GetTargetHeight(m_LastBounds); // Apply damping if (deltaTime >= 0) { float delta = targetHeight - m_prevTargetHeight; delta = Damper.Damp(delta, m_ZDamping, deltaTime); targetHeight = m_prevTargetHeight + delta; } m_prevTargetHeight = targetHeight; // Move the camera if (!curState.Lens.Orthographic && m_AdjustmentMode != AdjustmentMode.ZoomOnly) { // What distance would be needed to get the target height, at the current FOV float desiredDistance = targetHeight / (2f * Mathf.Tan(curState.Lens.FieldOfView * Mathf.Deg2Rad / 2f)); // target the near surface of the bounding box desiredDistance += m_LastBounds.extents.z; // Clamp to respect min/max distance settings desiredDistance = Mathf.Clamp( desiredDistance, targetZ - m_MaxDollyIn, targetZ + m_MaxDollyOut); desiredDistance = Mathf.Clamp(desiredDistance, m_MinimumDistance, m_MaximumDistance); // Apply cameraOffset += desiredDistance - targetZ; } // Apply zoom if (curState.Lens.Orthographic || m_AdjustmentMode != AdjustmentMode.DollyOnly) { float nearBoundsDistance = (targetZ + cameraOffset) - m_LastBounds.extents.z; float currentFOV = 179; if (nearBoundsDistance > Epsilon) currentFOV = 2f * Mathf.Atan(targetHeight / (2 * nearBoundsDistance)) * Mathf.Rad2Deg; LensSettings lens = curState.Lens; lens.FieldOfView = Mathf.Clamp(currentFOV, m_MinimumFOV, m_MaximumFOV); lens.OrthographicSize = Mathf.Clamp(targetHeight / 2, m_MinimumOrthoSize, m_MaximumOrthoSize); curState.Lens = lens; } return -cameraOffset; }
void UpdateFollowTargetCache() { mCachedFollowTargetVcam = null; mCachedFollowTargetGroup = null; mCachedFollowTarget = FollowTarget; if (mCachedFollowTarget != null) { mCachedFollowTargetVcam = mCachedFollowTarget.GetComponent <CinemachineVirtualCameraBase>(); mCachedFollowTargetGroup = mCachedFollowTarget.GetComponent <CinemachineTargetGroup>(); } }
// Start is called before the first frame update void Start() { Debug.Log("Setting TARGET GROUP"); group = GetComponent <Cinemachine.CinemachineTargetGroup>(); player = FindObjectOfType <Player>().transform; push = player.GetChild(14); group.m_Targets[1].target = push; group.m_Targets[1].weight = 1.0f; group.m_Targets[0].target = player; group.m_Targets[0].weight = 1.0f; int count = 0; foreach (Cinemachine.CinemachineTargetGroup.Target g in group.m_Targets) { Debug.Log(++count + " " + g.target); } }
void Start() { targetGroup = GetComponent <Cinemachine.CinemachineTargetGroup>(); int numPieces = piecesGroup.transform.childCount; int radius = 2; for (int i = 0; i < numPieces; i++) { if (i == numPieces - 1) { radius = 10; } targetGroup.AddMember(piecesGroup.transform.GetChild(i), 1, radius); } StartCoroutine(RemoveStartTargetMembers(waitTime)); }
/// <param name="observer">Point of view</param> /// <param name="newFwd">New forward direction to use when interpreting the return value</param> /// <returns>Bounding box in a slightly rotated version of observer, as specified by newFwd</returns> static Bounds GetScreenSpaceGroupBoundingBox( CinemachineTargetGroup group, Matrix4x4 observer, out Vector3 newFwd) { Vector2 minAngles, maxAngles, zRange; group.GetViewSpaceAngularBounds(observer, out minAngles, out maxAngles, out zRange); Vector2 shift = (minAngles + maxAngles) / 2; newFwd = Quaternion.identity.ApplyCameraRotation(shift, Vector3.up) * Vector3.forward; newFwd = observer.MultiplyVector(newFwd); float d = (zRange.y + zRange.x); Vector2 angles = (maxAngles - shift) * Mathf.Deg2Rad; angles = Vector2.Min(angles, new Vector2(89.5f, 89.5f)); return(new Bounds( new Vector3(0, 0, d / 2), new Vector3(Mathf.Tan(angles.y) * d, Mathf.Tan(angles.x) * d, zRange.y - zRange.x))); }
private void Awake() { if (instance == null) { instance = this; Physics2D.IgnoreLayerCollision(8, 8); Physics2D.IgnoreLayerCollision(8, 9); meteorManager = FindObjectOfType <MeteorManager>(); targetGroup = FindObjectOfType <Cinemachine.CinemachineTargetGroup>(); foreach (Human human in humans) { human.onDeath.AddListener(new UnityAction(() => { targetGroup.RemoveMember(human.transform); })); targetGroup.AddMember(human.transform, 1, 2); } } }
private float AdjustCameraDepthAndLensForGroupFraming(CinemachineTargetGroup group, float targetZ, ref CameraState curState, float deltaTime) { float num = 0f; Bounds boundingBox = group.BoundingBox; Vector3 a = curState.RawOrientation * Vector3.forward; this.m_lastBoundsMatrix = Matrix4x4.TRS(boundingBox.center - a * boundingBox.extents.magnitude, curState.RawOrientation, Vector3.one); this.m_LastBounds = group.GetViewSpaceBoundingBox(this.m_lastBoundsMatrix); float num2 = this.GetTargetHeight(this.m_LastBounds); if (deltaTime >= 0f) { float num3 = num2 - this.m_prevTargetHeight; num3 = Damper.Damp(num3, this.m_ZDamping, deltaTime); num2 = this.m_prevTargetHeight + num3; } this.m_prevTargetHeight = num2; if (!curState.Lens.Orthographic && this.m_AdjustmentMode != CinemachineFramingTransposer.AdjustmentMode.ZoomOnly) { float num4 = num2 / (2f * Mathf.Tan(curState.Lens.FieldOfView * 0.0174532924f / 2f)); num4 += this.m_LastBounds.extents.z; num4 = Mathf.Clamp(num4, targetZ - this.m_MaxDollyIn, targetZ + this.m_MaxDollyOut); num4 = Mathf.Clamp(num4, this.m_MinimumDistance, this.m_MaximumDistance); num += num4 - targetZ; } if (curState.Lens.Orthographic || this.m_AdjustmentMode != CinemachineFramingTransposer.AdjustmentMode.DollyOnly) { float num5 = targetZ + num - this.m_LastBounds.extents.z; float value = 179f; if (num5 > 0.0001f) { value = 2f * Mathf.Atan(num2 / (2f * num5)) * 57.29578f; } LensSettings lens = curState.Lens; lens.FieldOfView = Mathf.Clamp(value, this.m_MinimumFOV, this.m_MaximumFOV); lens.OrthographicSize = Mathf.Clamp(num2 / 2f, this.m_MinimumOrthoSize, this.m_MaximumOrthoSize); curState.Lens = lens; } return(-num); }
public override void MutateCameraState(ref CameraState curState, float deltaTime) { if (deltaTime < 0f) { this.m_Predictor.Reset(); this.m_PreviousCameraPosition = curState.RawPosition + curState.RawOrientation * Vector3.back * this.m_CameraDistance; } if (!this.IsValid) { return; } Vector3 previousCameraPosition = this.m_PreviousCameraPosition; curState.ReferenceLookAt = base.FollowTarget.position; this.m_Predictor.Smoothing = this.m_LookaheadSmoothing; this.m_Predictor.AddPosition(curState.ReferenceLookAt); this.TrackedPoint = ((this.m_LookaheadTime > 0f) ? this.m_Predictor.PredictPosition(this.m_LookaheadTime) : curState.ReferenceLookAt); Quaternion rawOrientation = curState.RawOrientation; Quaternion rotation = Quaternion.Inverse(rawOrientation); Vector3 vector = rotation * previousCameraPosition; Vector3 vector2 = rotation * this.TrackedPoint - vector; Vector3 vector3 = Vector3.zero; float num = Mathf.Max(0.01f, this.m_CameraDistance - this.m_DeadZoneDepth / 2f); float num2 = Mathf.Max(num, this.m_CameraDistance + this.m_DeadZoneDepth / 2f); if (vector2.z < num) { vector3.z = vector2.z - num; } if (vector2.z > num2) { vector3.z = vector2.z - num2; } CinemachineTargetGroup targetGroup = this.TargetGroup; if (targetGroup != null && this.m_GroupFramingMode != CinemachineFramingTransposer.FramingMode.None) { vector3.z += this.AdjustCameraDepthAndLensForGroupFraming(targetGroup, vector2.z - vector3.z, ref curState, deltaTime); } vector2.z -= vector3.z; float orthoSize = curState.Lens.Orthographic ? curState.Lens.OrthographicSize : (Mathf.Tan(0.5f * curState.Lens.FieldOfView * 0.0174532924f) * vector2.z); Rect screenRect = this.ScreenToOrtho(this.SoftGuideRect, orthoSize, curState.Lens.Aspect); if (deltaTime < 0f) { Rect screenRect2 = new Rect(screenRect.center, Vector2.zero); vector3 += this.OrthoOffsetToScreenBounds(vector2, screenRect2); } else { vector3 += this.OrthoOffsetToScreenBounds(vector2, screenRect); Vector3 vector4 = Vector3.zero; if (!this.m_UnlimitedSoftZone) { Rect screenRect3 = this.ScreenToOrtho(this.HardGuideRect, orthoSize, curState.Lens.Aspect); vector4 = this.OrthoOffsetToScreenBounds(vector2, screenRect3); float d = Mathf.Max(vector4.x / (vector3.x + 0.0001f), vector4.y / (vector3.y + 0.0001f)); vector4 = vector3 * d; } vector3 = vector4 + Damper.Damp(vector3 - vector4, new Vector3(this.m_XDamping, this.m_YDamping, this.m_ZDamping), deltaTime); } curState.RawPosition = (this.m_PreviousCameraPosition = rawOrientation * (vector + vector3)); }
private void Awake() { targetGroup = GetComponent <Cinemachine.CinemachineTargetGroup>(); }
/// <summary>Positions the virtual camera according to the transposer rules.</summary> /// <param name="curState">The current camera state</param> /// <param name="deltaTime">Used for damping. If less than 0, no damping is done.</param> public override void MutateCameraState(ref CameraState curState, float deltaTime) { Vector3 followTargetPosition = FollowTargetPosition; if (deltaTime < 0) { m_Predictor.Reset(); m_PreviousCameraPosition = FollowTargetPosition + (curState.RawOrientation * Vector3.back) * m_CameraDistance; m_prevFOV = 0; } if (!IsValid) { return; } // Compute group bounds and adjust follow target for group framing CinemachineTargetGroup group = FollowTargetGroup; bool isGroupFraming = group != null && m_GroupFramingMode != FramingMode.None; if (isGroupFraming) { followTargetPosition = ComputeGroupBounds(group, ref curState); } if (m_LookaheadTime > Epsilon) { m_Predictor.IgnoreY = m_LookaheadIgnoreY; m_Predictor.Smoothing = m_LookaheadSmoothing; m_Predictor.AddPosition(followTargetPosition); var p = m_Predictor.PredictPosition(m_LookaheadTime); if (isGroupFraming) { var b = LastBounds; b.center += p - followTargetPosition; LastBounds = b; } followTargetPosition = p; } TrackedPoint = followTargetPosition; if (!curState.HasLookAt) { curState.ReferenceLookAt = followTargetPosition; } // Adjust the desired depth for group framing float targetDistance = m_CameraDistance; bool isOrthographic = curState.Lens.Orthographic; float targetHeight = isGroupFraming ? GetTargetHeight(LastBounds.size / m_GroupFramingSize) : 0; if (!isOrthographic && isGroupFraming) { // Adjust height for perspective - we want the height at the near surface float boundsDepth = LastBounds.extents.z; float z = LastBounds.center.z; if (z > boundsDepth) { targetHeight = Mathf.Lerp(0, targetHeight, (z - boundsDepth) / z); } if (m_AdjustmentMode != AdjustmentMode.ZoomOnly) { // What distance from near edge would be needed to get the adjusted // target height, at the current FOV targetDistance = targetHeight / (2f * Mathf.Tan(curState.Lens.FieldOfView * Mathf.Deg2Rad / 2f)); // Clamp to respect min/max distance settings to the near surface of the bounds targetDistance = Mathf.Clamp(targetDistance, m_MinimumDistance, m_MaximumDistance); // Clamp to respect min/max camera movement float targetDelta = targetDistance - m_CameraDistance; targetDelta = Mathf.Clamp(targetDelta, -m_MaxDollyIn, m_MaxDollyOut); targetDistance = m_CameraDistance + targetDelta; } } // Work in camera-local space Vector3 camPosWorld = m_PreviousCameraPosition; Quaternion localToWorld = curState.RawOrientation; Quaternion worldToLocal = Quaternion.Inverse(localToWorld); Vector3 cameraPos = worldToLocal * camPosWorld; Vector3 targetPos = (worldToLocal * TrackedPoint) - cameraPos; // Move along camera z Vector3 cameraOffset = Vector3.zero; float cameraMin = Mathf.Max(kMinimumCameraDistance, targetDistance - m_DeadZoneDepth / 2); float cameraMax = Mathf.Max(cameraMin, targetDistance + m_DeadZoneDepth / 2); if (targetPos.z < cameraMin) { cameraOffset.z = targetPos.z - cameraMin; } if (targetPos.z > cameraMax) { cameraOffset.z = targetPos.z - cameraMax; } // Move along the XY plane float screenSize = curState.Lens.Orthographic ? curState.Lens.OrthographicSize : Mathf.Tan(0.5f * curState.Lens.FieldOfView * Mathf.Deg2Rad) * (targetPos.z - cameraOffset.z); Rect softGuideOrtho = ScreenToOrtho(SoftGuideRect, screenSize, curState.Lens.Aspect); if (deltaTime < 0) { // No damping or hard bounds, just snap to central bounds, skipping the soft zone Rect rect = softGuideOrtho; if (m_CenterOnActivate) { rect = new Rect(rect.center, Vector2.zero); // Force to center } cameraOffset += OrthoOffsetToScreenBounds(targetPos, rect); } else { // Move it through the soft zone cameraOffset += OrthoOffsetToScreenBounds(targetPos, softGuideOrtho); // Find where it intersects the hard zone Vector3 hard = Vector3.zero; if (!m_UnlimitedSoftZone) { Rect hardGuideOrtho = ScreenToOrtho(HardGuideRect, screenSize, curState.Lens.Aspect); hard = OrthoOffsetToScreenBounds(targetPos, hardGuideOrtho); float t = Mathf.Max(hard.x / (cameraOffset.x + Epsilon), hard.y / (cameraOffset.y + Epsilon)); hard = cameraOffset * t; } // Apply damping, but only to the portion of the move that's inside the hard zone cameraOffset = hard + Damper.Damp( cameraOffset - hard, new Vector3(m_XDamping, m_YDamping, m_ZDamping), deltaTime); } curState.RawPosition = m_PreviousCameraPosition = localToWorld * (cameraPos + cameraOffset); // Adjust lens for group framing if (isGroupFraming) { if (isOrthographic) { targetHeight = Mathf.Clamp(targetHeight, m_MinimumOrthoSize, m_MaximumOrthoSize); // ApplyDamping if (deltaTime >= 0) { targetHeight = m_prevFOV + Damper.Damp(targetHeight - m_prevFOV, m_ZDamping, deltaTime); } m_prevFOV = targetHeight; LensSettings lens = curState.Lens; lens.OrthographicSize = Mathf.Clamp(targetHeight / 2, m_MinimumOrthoSize, m_MaximumOrthoSize); curState.Lens = lens; } else if (m_AdjustmentMode != AdjustmentMode.DollyOnly) { var localTarget = Quaternion.Inverse(curState.RawOrientation) * (followTargetPosition - curState.RawPosition); float nearBoundsDistance = localTarget.z; float targetFOV = 179; if (nearBoundsDistance > Epsilon) { targetFOV = 2f * Mathf.Atan(targetHeight / (2 * nearBoundsDistance)) * Mathf.Rad2Deg; } targetFOV = Mathf.Clamp(targetFOV, m_MinimumFOV, m_MaximumFOV); // ApplyDamping if (deltaTime >= 0 && m_prevFOV != 0) { targetFOV = m_prevFOV + Damper.Damp(targetFOV - m_prevFOV, m_ZDamping, deltaTime); } m_prevFOV = targetFOV; LensSettings lens = curState.Lens; lens.FieldOfView = targetFOV; curState.Lens = lens; } } }
/// <summary>Applies the composer rules and orients the camera accordingly</summary> /// <param name="curState">The current camera state</param> /// <param name="deltaTime">Used for calculating damping. If less than /// zero, then target will snap to the center of the dead zone.</param> public override void MutateCameraState(ref CameraState curState, float deltaTime) { // Can't do anything without a group to look at CinemachineTargetGroup group = LookAtTargetGroup; if (group == null) { base.MutateCameraState(ref curState, deltaTime); return; } if (!IsValid || !curState.HasLookAt) { m_prevTargetHeight = 0; m_prevCameraOffset = Vector3.zero; return; } bool canMoveCamera = !curState.Lens.Orthographic && m_AdjustmentMode != AdjustmentMode.ZoomOnly; // Get the bounding box from camera's POV in view space Vector3 observerPosition = curState.RawPosition; BoundingSphere s = group.Sphere; Vector3 groupCenter = s.position; Vector3 currentOffset = groupCenter - observerPosition; float currentDistance = currentOffset.magnitude; if (currentDistance < Epsilon) { return; // navel-gazing, get outa here } Vector3 fwd = currentOffset / currentDistance; LastBoundsMatrix = Matrix4x4.TRS(observerPosition, Quaternion.LookRotation(fwd, curState.ReferenceUp), Vector3.one); Bounds b; if (curState.Lens.Orthographic) { b = group.GetViewSpaceBoundingBox(LastBoundsMatrix); Vector3 sizeDelta = new Vector3(b.center.x, b.center.y, 0); b.size += sizeDelta.Abs() * 2; b.center = new Vector3(0, 0, b.center.z); LastBounds = b; } else { if (canMoveCamera) { // Get an upper bound on the distance b = group.GetViewSpaceBoundingBox(LastBoundsMatrix); groupCenter = LastBoundsMatrix.MultiplyPoint3x4(b.center); // Now try to get closer float distance = GetTargetHeight(b) / (2f * Mathf.Tan(curState.Lens.FieldOfView * Mathf.Deg2Rad / 2f)); Vector3 nearCenter = b.center; nearCenter.z -= b.extents.z; nearCenter = LastBoundsMatrix.MultiplyPoint3x4(nearCenter); Vector3 newFwd = (groupCenter - nearCenter).normalized; if (!newFwd.AlmostZero()) { fwd = newFwd; } observerPosition = nearCenter - (fwd * distance); LastBoundsMatrix = Matrix4x4.TRS(observerPosition, Quaternion.LookRotation(fwd, curState.ReferenceUp), Vector3.one); } b = GetScreenSpaceGroupBoundingBox(group, LastBoundsMatrix, out fwd); LastBoundsMatrix = Matrix4x4.TRS(observerPosition, Quaternion.LookRotation(fwd, curState.ReferenceUp), Vector3.one); LastBounds = b; groupCenter = LastBoundsMatrix.MultiplyPoint3x4(b.center); currentOffset = groupCenter - curState.RawPosition; currentDistance = currentOffset.magnitude; } // Adjust bounds for framing size Vector3 extents = b.extents / m_GroupFramingSize; extents.z = Mathf.Min(b.extents.z, extents.z); b.extents = extents; // Apply damping float targetHeight = GetTargetHeight(b); if (deltaTime >= 0) { float delta = targetHeight - m_prevTargetHeight; delta = Damper.Damp(delta, m_FrameDamping, deltaTime); targetHeight = m_prevTargetHeight + delta; } m_prevTargetHeight = targetHeight; // Move the camera if (canMoveCamera) { // What distance would be needed to get the target height, at the current FOV float depth = b.extents.z; float d = (groupCenter - observerPosition).magnitude; float nearTargetHeight = targetHeight * (d - depth) / d; float targetDistance = nearTargetHeight / (2f * Mathf.Tan(curState.Lens.FieldOfView * Mathf.Deg2Rad / 2f)); // Clamp to respect min/max distance settings to the near surface of the bounds float cameraDistance = targetDistance; cameraDistance = Mathf.Clamp(cameraDistance, currentDistance - m_MaxDollyIn, currentDistance + m_MaxDollyOut); cameraDistance -= depth; cameraDistance = Mathf.Clamp(cameraDistance, m_MinimumDistance, m_MaximumDistance); cameraDistance += depth; // Apply Vector3 newCamOffset = (groupCenter - (fwd * (cameraDistance + depth))) - curState.RawPosition; if (deltaTime >= 0) { Vector3 delta = newCamOffset - m_prevCameraOffset; delta = Damper.Damp(delta, m_FrameDamping, deltaTime); newCamOffset = m_prevCameraOffset + delta; } m_prevCameraOffset = newCamOffset; curState.PositionCorrection += newCamOffset; } // Apply zoom if (curState.Lens.Orthographic || m_AdjustmentMode != AdjustmentMode.DollyOnly) { float nearBoundsDistance = (groupCenter - curState.CorrectedPosition).magnitude; float currentFOV = 179; if (nearBoundsDistance > Epsilon) { currentFOV = 2f * Mathf.Atan(targetHeight / (2 * nearBoundsDistance)) * Mathf.Rad2Deg; } LensSettings lens = curState.Lens; lens.FieldOfView = Mathf.Clamp(currentFOV, m_MinimumFOV, m_MaximumFOV); lens.OrthographicSize = Mathf.Clamp(targetHeight / 2, m_MinimumOrthoSize, m_MaximumOrthoSize); curState.Lens = lens; } // Now compose normally curState.ReferenceLookAt = GetLookAtPointAndSetTrackedPoint(groupCenter); base.MutateCameraState(ref curState, deltaTime); }
/// <summary>Applies the composer rules and orients the camera accordingly</summary> /// <param name="curState">The current camera state</param> /// <param name="deltaTime">Used for calculating damping. If less than /// zero, then target will snap to the center of the dead zone.</param> public override void MutateCameraState(ref CameraState curState, float deltaTime) { // Can't do anything without a group to look at CinemachineTargetGroup group = LookAtTargetGroup; if (group == null) { base.MutateCameraState(ref curState, deltaTime); return; } if (!IsValid || !curState.HasLookAt) { m_prevFramingDistance = 0; m_prevFOV = 0; return; } bool isOrthographic = curState.Lens.Orthographic; bool canMoveCamera = !isOrthographic && m_AdjustmentMode != AdjustmentMode.ZoomOnly; // Get the bounding box from camera's POV in view space Vector3 up = curState.ReferenceUp; var cameraPos = curState.RawPosition; BoundingSphere s = group.Sphere; Vector3 groupCenter = s.position; Vector3 fwd = groupCenter - cameraPos; float d = fwd.magnitude; if (d < Epsilon) { return; // navel-gazing, get outa here } // Approximate looking at the group center fwd /= d; LastBoundsMatrix = Matrix4x4.TRS( cameraPos, Quaternion.LookRotation(fwd, up), Vector3.one); // Correction for the actual center Bounds b; if (isOrthographic) { b = group.GetViewSpaceBoundingBox(LastBoundsMatrix); groupCenter = LastBoundsMatrix.MultiplyPoint3x4(b.center); fwd = (groupCenter - cameraPos).normalized; LastBoundsMatrix = Matrix4x4.TRS(cameraPos, Quaternion.LookRotation(fwd, up), Vector3.one); b = group.GetViewSpaceBoundingBox(LastBoundsMatrix); LastBounds = b; } else { b = GetScreenSpaceGroupBoundingBox(group, LastBoundsMatrix, out fwd); LastBoundsMatrix = Matrix4x4.TRS(cameraPos, Quaternion.LookRotation(fwd, up), Vector3.one); LastBounds = b; groupCenter = cameraPos + fwd * b.center.z; fwd = (groupCenter - cameraPos).normalized; } // Adjust bounds for framing size, and get target height float boundsDepth = b.extents.z; float targetHeight = GetTargetHeight(b.size / m_GroupFramingSize); if (isOrthographic) { targetHeight = Mathf.Clamp(targetHeight, m_MinimumOrthoSize, m_MaximumOrthoSize); // ApplyDamping if (deltaTime >= 0) { targetHeight = m_prevFOV + Damper.Damp(targetHeight - m_prevFOV, m_FrameDamping, deltaTime); } m_prevFOV = targetHeight; LensSettings lens = curState.Lens; lens.OrthographicSize = Mathf.Clamp(targetHeight / 2, m_MinimumOrthoSize, m_MaximumOrthoSize); curState.Lens = lens; } else { // Adjust height for perspective - we want the height at the near surface float z = b.center.z; if (z > boundsDepth) { targetHeight = Mathf.Lerp(0, targetHeight, (z - boundsDepth) / z); } // Move the camera if (canMoveCamera) { // What distance from near edge would be needed to get the adjusted // target height, at the current FOV float targetDistance = boundsDepth + targetHeight / (2f * Mathf.Tan(curState.Lens.FieldOfView * Mathf.Deg2Rad / 2f)); // Clamp to respect min/max distance settings to the near surface of the bounds targetDistance = Mathf.Clamp( targetDistance, boundsDepth + m_MinimumDistance, boundsDepth + m_MaximumDistance); // Clamp to respect min/max camera movement float targetDelta = targetDistance - Vector3.Distance(curState.RawPosition, groupCenter); targetDelta = Mathf.Clamp(targetDelta, -m_MaxDollyIn, m_MaxDollyOut); // ApplyDamping if (deltaTime >= 0) { float delta = targetDelta - m_prevFramingDistance; delta = Damper.Damp(delta, m_FrameDamping, deltaTime); targetDelta = m_prevFramingDistance + delta; } m_prevFramingDistance = targetDelta; curState.PositionCorrection -= fwd * targetDelta; cameraPos -= fwd * targetDelta; } // Apply zoom if (m_AdjustmentMode != AdjustmentMode.DollyOnly) { float nearBoundsDistance = (groupCenter - cameraPos).magnitude - boundsDepth; float targetFOV = 179; if (nearBoundsDistance > Epsilon) { targetFOV = 2f * Mathf.Atan(targetHeight / (2 * nearBoundsDistance)) * Mathf.Rad2Deg; } targetFOV = Mathf.Clamp(targetFOV, m_MinimumFOV, m_MaximumFOV); // ApplyDamping if (deltaTime >= 0 && m_prevFOV != 0) { targetFOV = m_prevFOV + Damper.Damp(targetFOV - m_prevFOV, m_FrameDamping, deltaTime); } m_prevFOV = targetFOV; LensSettings lens = curState.Lens; lens.FieldOfView = targetFOV; curState.Lens = lens; } } // Now compose normally curState.ReferenceLookAt = GetLookAtPointAndSetTrackedPoint(groupCenter); base.MutateCameraState(ref curState, deltaTime); }
/// <summary>Applies the composer rules and orients the camera accordingly</summary> /// <param name="state">The current camera state</param> /// <param name="deltaTime">Used for calculating damping. If less than /// zero, then target will snap to the center of the dead zone.</param> public override void MutateCameraState(ref CameraState curState, float deltaTime) { // Can't do anything without a group to look at CinemachineTargetGroup group = TargetGroup; if (group == null) { base.MutateCameraState(ref curState, deltaTime); return; } if (!IsValid || !curState.HasLookAt) { m_prevTargetHeight = 0; return; } // The following line shouldn't be necessary. You can try enabling it as a // last resort if you're getting inexplicable jitter. That can sometimes come // about because the group's target members are not animated in a consistent way. //group.LateUpdate(); // Make sure the group's position is fully updated. curState.ReferenceLookAt = group.transform.position; Vector3 lookAtPosition = GetTrackedPoint(curState.ReferenceLookAt); Vector3 currentOffset = lookAtPosition - curState.RawPosition; float currentDistance = currentOffset.magnitude; if (currentDistance < Epsilon) { return; // navel-gazing, get outa here } //UnityEngine.Profiling.Profiler.BeginSample("CinemachineGroupComposer.MutateCameraState"); // Get the camera axis Vector3 fwd = currentOffset.AlmostZero() ? Vector3.forward : currentOffset.normalized; // Get the bounding box from that POV in view space, and find its width Bounds bounds = group.BoundingBox; m_lastBoundsMatrix = Matrix4x4.TRS( bounds.center - (fwd * bounds.extents.magnitude), Quaternion.LookRotation(fwd, curState.ReferenceUp), Vector3.one); m_LastBounds = group.GetViewSpaceBoundingBox(m_lastBoundsMatrix); float targetHeight = GetTargetHeight(m_LastBounds); Vector3 targetPos = m_lastBoundsMatrix.MultiplyPoint3x4(m_LastBounds.center); // Apply damping if (deltaTime >= 0) { float delta = targetHeight - m_prevTargetHeight; delta = Damper.Damp(delta, m_FrameDamping, deltaTime); targetHeight = m_prevTargetHeight + delta; } m_prevTargetHeight = targetHeight; // Move the camera if (!curState.Lens.Orthographic && m_AdjustmentMode != AdjustmentMode.ZoomOnly) { // What distance would be needed to get the target height, at the current FOV float currentFOV = curState.Lens.FieldOfView; float targetDistance = targetHeight / (2f * Mathf.Tan(currentFOV * Mathf.Deg2Rad / 2f)); // target the near surface of the bounding box float cameraDistance = targetDistance + m_LastBounds.extents.z; // Clamp to respect min/max distance settings cameraDistance = Mathf.Clamp( cameraDistance, currentDistance - m_MaxDollyIn, currentDistance + m_MaxDollyOut); cameraDistance = Mathf.Clamp(cameraDistance, m_MinimumDistance, m_MaximumDistance); // Apply curState.PositionCorrection += targetPos - fwd * cameraDistance - curState.RawPosition; } // Apply zoom if (curState.Lens.Orthographic || m_AdjustmentMode != AdjustmentMode.DollyOnly) { float nearBoundsDistance = (lookAtPosition - curState.CorrectedPosition).magnitude - m_LastBounds.extents.z; float currentFOV = 179; if (nearBoundsDistance > Epsilon) { currentFOV = 2f * Mathf.Atan(targetHeight / (2 * nearBoundsDistance)) * Mathf.Rad2Deg; } LensSettings lens = curState.Lens; lens.FieldOfView = Mathf.Clamp(currentFOV, m_MinimumFOV, m_MaximumFOV); lens.OrthographicSize = Mathf.Clamp(targetHeight / 2, m_MinimumOrthoSize, m_MaximumOrthoSize); curState.Lens = lens; } // Now compose normally base.MutateCameraState(ref curState, deltaTime); //UnityEngine.Profiling.Profiler.EndSample(); }
// Start is called before the first frame update void Start() { actuallyFollowing = GetComponent <Cinemachine.CinemachineTargetGroup>(); actuallyFollowing.AddMember(GameObject.Find("Character").transform, 2, 4.5f); }
/// <summary>Positions the virtual camera according to the transposer rules.</summary> /// <param name="curState">The current camera state</param> /// <param name="deltaTime">Used for damping. If less than 0, no damping is done.</param> public override void MutateCameraState(ref CameraState curState, float deltaTime) { if (deltaTime < 0) m_PreviousCameraPosition = curState.RawPosition + (curState.RawOrientation * Vector3.back) * m_CameraDistance; if (!IsValid) return; //UnityEngine.Profiling.Profiler.BeginSample("CinemachineFramingTransposer.MutateCameraState"); Vector3 camPosWorld = m_PreviousCameraPosition; curState.ReferenceLookAt = FollowTarget.position; // Work in camera-local space Quaternion localToWorld = curState.RawOrientation; Quaternion worldToLocal = Quaternion.Inverse(localToWorld); Vector3 cameraPos = worldToLocal * camPosWorld; Vector3 targetPos = (worldToLocal * curState.ReferenceLookAt) - cameraPos; // Move along camera z Vector3 cameraOffset = Vector3.zero; float cameraMin = Mathf.Max(kMinimumCameraDistance, m_CameraDistance - m_DeadZoneDepth/2); float cameraMax = Mathf.Max(cameraMin, m_CameraDistance + m_DeadZoneDepth/2); if (targetPos.z < cameraMin) cameraOffset.z = targetPos.z - cameraMin; if (targetPos.z > cameraMax) cameraOffset.z = targetPos.z - cameraMax; // Adjust for group framing CinemachineTargetGroup group = TargetGroup; if (group != null && m_GroupFramingMode != FramingMode.None) cameraOffset.z += AdjustCameraDepthAndLensForGroupFraming( group, targetPos.z - cameraOffset.z, ref curState, deltaTime); // Move along the XY plane targetPos.z -= cameraOffset.z; float screenSize = curState.Lens.Orthographic ? curState.Lens.OrthographicSize : Mathf.Tan(0.5f * curState.Lens.FieldOfView * Mathf.Deg2Rad) * targetPos.z; Rect softGuideOrtho = ScreenToOrtho(SoftGuideRect, screenSize, curState.Lens.Aspect); if (deltaTime < 0) { // No damping or hard bounds, just snap to central bounds, skipping the soft zone Rect rect = new Rect(softGuideOrtho.center, Vector2.zero); // Force to center cameraOffset += OrthoOffsetToScreenBounds(targetPos, rect); } else { // Move it through the soft zone cameraOffset += OrthoOffsetToScreenBounds(targetPos, softGuideOrtho); // Find where it intersects the hard zone Vector3 hard = Vector3.zero; if (!m_UnlimitedSoftZone) { Rect hardGuideOrtho = ScreenToOrtho(HardGuideRect, screenSize, curState.Lens.Aspect); hard = OrthoOffsetToScreenBounds(targetPos, hardGuideOrtho); float t = Mathf.Max(hard.x / (cameraOffset.x + Epsilon), hard.y / (cameraOffset.y + Epsilon)); hard = cameraOffset * t; } // Apply damping, but only to the portion of the move that's inside the hard zone cameraOffset = hard + Damper.Damp( cameraOffset - hard, new Vector3(m_XDamping, m_YDamping, m_ZDamping), deltaTime); } curState.RawPosition = m_PreviousCameraPosition = localToWorld * (cameraPos + cameraOffset); //UnityEngine.Profiling.Profiler.EndSample(); }
/// <summary> /// Initialize the instance if not created /// </summary> private void Awake() { // Check if instance already exists if (instance == null) { // if not set it to this instance = this; } // If instance exists and is not this else if (instance != this) { // Destroy old GameManager Destroy(instance.gameObject); instance = this; } // Sets this to not be destroyed when reloading scene //DontDestroyOnLoad(gameObject); if (m_EnableLoadingScreen && m_BlackCanvas) { Color newColor = m_BlackCanvas.GetComponent <Image>().color; newColor.a = 1.0f; m_BlackCanvas.GetComponent <Image>().color = newColor; } m_HingeRopePlayers = GameObject.Find("HingeRope"); // Initializes an empty game object that tracks the // camera Y angle for player movement direction cameraAngle = new GameObject("GetsCameraYAngle"); cameraAngle.AddComponent <CameraAngle>(); // Set up grandma and baby input controllers m_GrandmaObj = GameObject.Find("Grandma"); m_BBcatObj = GameObject.Find("BbCat"); m_RopeObj = GameObject.Find("Obi Rope"); InputController babyInput = m_BBcatObj.GetComponent <InputController>(); InputController gmaInput = m_GrandmaObj.GetComponent <InputController>(); PickupController gmaPickup = m_GrandmaObj.GetComponent <PickupController>(); gmaInput.grandma = babyInput.grandma = gmaInput; gmaInput.baby = babyInput.baby = babyInput; gmaInput.gmaPickupCont = babyInput.gmaPickupCont = gmaPickup; // Get camera m_Camera = GameObject.Find("Main Camera"); // Get camera holder m_CameraHolder = GameObject.Find("TargetGroupFollow"); // Update camera tracking targetGroup = m_CameraHolder.GetComponent <Cinemachine.CinemachineTargetGroup>(); targetGroup.m_Targets[0].target = m_GrandmaObj.transform; targetGroup.m_Targets[1].target = m_BBcatObj.transform; if (m_PuzzleCameras) { foreach (Transform child in m_PuzzleCameras.transform) { child.gameObject.GetComponent <PuzzleCameraCine>().Reset(m_GrandmaObj, m_BBcatObj); } } else { Debug.Log("NO PUZZLE CAMERAS"); } // Update level start positions // TODO: find a better way to get all level start points, instead of get manually level1StartPoint = GameObject.Find("Level1 start point"); level2StartPoint = GameObject.Find("Level2 start point"); level3StartPoint = GameObject.Find("Level3 start point"); level4StartPoint = GameObject.Find("Level4 start point"); level5StartPoint = GameObject.Find("Level5 start point"); level6StartPoint = GameObject.Find("Level6 start point"); level7StartPoint = GameObject.Find("Level7 start point"); level8StartPoint = GameObject.Find("Level8 start point"); level9StartPoint = GameObject.Find("Level9 start point"); level10StartPoint = GameObject.Find("Level10 start point"); level11StartPoint = GameObject.Find("Level11 start point"); // Update pause menu m_PauseMenu = GameObject.Find("PauseMenu"); Debug.Log("players set"); if (m_PauseMenu) { m_PauseMenu.SetActive(false); } m_Player0 = ReInput.players.GetPlayer(0); m_Player1 = ReInput.players.GetPlayer(1); // Find UI element if (GameObject.Find("UIElementPlaceHolder")) { m_UIElementPlaceHolder = GameObject.Find("UIElementPlaceHolder"); } }
void Start() { m_group = GetComponent <CinemachineTargetGroup>(); }
Vector3 AdjustCameraPositionAndLensForGroupFraming( CinemachineTargetGroup group, float initialZ, ref CameraState curState, float deltaTime) { Vector3 cameraOffset = Vector3.zero; bool canMoveCameraInZ = !curState.Lens.Orthographic && m_AdjustmentMode != AdjustmentMode.ZoomOnly; // Work in camera-local space Vector3 fwd = curState.RawOrientation * Vector3.forward; Vector3 cameraWorldStartPos = TrackedPoint - (fwd * initialZ); LastBoundsMatrix = Matrix4x4.TRS(cameraWorldStartPos, curState.RawOrientation, Vector3.one); // Get the bounding box from camera's direction in view space Bounds b = group.GetViewSpaceBoundingBox(LastBoundsMatrix); LastBounds = b; // Recenter the camera in x-y, don't touch the depth cameraOffset = b.center; cameraOffset.z = 0; float firstApproxCameraOffsetZ = 0; if (!curState.Lens.Orthographic) { // Now get a more refined bounding box in screen space if (canMoveCameraInZ) { float newZ = GetPositionForNearBounds( b, GetTargetHeight(b), curState.Lens.FieldOfView, false); firstApproxCameraOffsetZ = Mathf.Clamp(newZ, -m_MaxDollyOut, m_MaxDollyIn); cameraOffset.z = firstApproxCameraOffsetZ; } Vector3 worldObserverPos = LastBoundsMatrix.MultiplyPoint3x4(cameraOffset); Vector3 localPosAdustmentXY; b = GetScreenSpaceGroupBoundingBox( group, ref worldObserverPos, curState.RawOrientation, out localPosAdustmentXY); cameraOffset += localPosAdustmentXY; // worldObserverPos has been adjusted LastBoundsMatrix = Matrix4x4.TRS(worldObserverPos, curState.RawOrientation, Vector3.one); LastBounds = b; } // Bring it back to local space b.center += cameraOffset; cameraOffset.z = 0; // Adjust bounds for framing size Vector3 extents = b.extents / m_GroupFramingSize; extents.z = Mathf.Min(b.extents.z, extents.z); b.extents = extents; // Apply damping float targetHeight = GetTargetHeight(b); if (deltaTime >= 0) { float delta = targetHeight - m_prevTargetHeight; delta = Damper.Damp(delta, m_ZDamping, deltaTime); targetHeight = m_prevTargetHeight + delta; } m_prevTargetHeight = targetHeight; // Move the camera in Z if (canMoveCameraInZ) { float newZ = GetPositionForNearBounds( new Bounds(b.center - new Vector3(0, 0, firstApproxCameraOffsetZ), b.size), targetHeight, curState.Lens.FieldOfView, true); newZ += firstApproxCameraOffsetZ; cameraOffset.z = Mathf.Clamp(newZ, -m_MaxDollyOut, m_MaxDollyIn); } // Apply zoom if (curState.Lens.Orthographic || m_AdjustmentMode != AdjustmentMode.DollyOnly) { float targetDistance = b.center.z - cameraOffset.z; float currentFOV = 179; if (targetDistance > Epsilon) { currentFOV = 2f * Mathf.Atan(targetHeight / (2 * targetDistance)) * Mathf.Rad2Deg; } LensSettings lens = curState.Lens; lens.FieldOfView = Mathf.Clamp(currentFOV, m_MinimumFOV, m_MaximumFOV); lens.OrthographicSize = Mathf.Clamp(targetHeight / 2, m_MinimumOrthoSize, m_MaximumOrthoSize); curState.Lens = lens; } return(cameraOffset); }
/// <summary>Positions the virtual camera according to the transposer rules.</summary> /// <param name="curState">The current camera state</param> /// <param name="deltaTime">Used for damping. If 0 or less, no damping is done.</param> public virtual void MutateCameraState(ref CameraState curState, float deltaTime) { if (deltaTime <= 0) { m_PreviousCameraPosition = curState.RawPosition + (curState.RawOrientation * Vector3.back) * m_CameraDistance; } if (!IsValid) { return; } //UnityEngine.Profiling.Profiler.BeginSample("CinemachineFramingTransposer.MutateCameraState"); Vector3 camPosWorld = m_PreviousCameraPosition; curState.ReferenceLookAt = VirtualCamera.Follow.position; // Work in camera-local space Quaternion localToWorld = curState.RawOrientation; Quaternion worldToLocal = Quaternion.Inverse(localToWorld); Vector3 cameraPos = worldToLocal * camPosWorld; Vector3 targetPos = (worldToLocal * curState.ReferenceLookAt) - cameraPos; // Move along camera z Vector3 cameraOffset = Vector3.zero; float cameraMin = Mathf.Max(kMinimumCameraDistance, m_CameraDistance - m_DistanceDeadZoneSize / 2); float cameraMax = Mathf.Max(cameraMin, m_CameraDistance + m_DistanceDeadZoneSize / 2); if (targetPos.z < cameraMin) { cameraOffset.z = targetPos.z - cameraMin; } if (targetPos.z > cameraMax) { cameraOffset.z = targetPos.z - cameraMax; } if (deltaTime > 0 && Mathf.Abs(cameraOffset.z) > UnityVectorExtensions.Epsilon) { cameraOffset.z *= deltaTime / Mathf.Max(m_ZDamping * kDampingScale, deltaTime); } // Adjust for group framing CinemachineTargetGroup group = TargetGroup; if (group != null) { cameraOffset.z += AdjustCameraDepthAndLensForGroupFraming( group, targetPos.z - cameraOffset.z, ref curState, deltaTime); } targetPos.z -= cameraOffset.z; // Move along the XY plane float screenSize = curState.Lens.Orthographic ? curState.Lens.OrthographicSize : Mathf.Tan(0.5f * curState.Lens.FieldOfView * Mathf.Deg2Rad) * targetPos.z; Rect softGuideOrtho = ScreenToOrtho(SoftGuideRect, screenSize, curState.Lens.Aspect); if (deltaTime <= 0) { // No damping, just snap to central bounds, skipping the soft zone Rect rect = new Rect(softGuideOrtho.center, Vector2.zero); // Force to center cameraOffset += OrthoOffsetToScreenBounds(targetPos, rect, 0); } else { // First force the previous position into the hard bounds, no damping Rect hardGuideOrtho = ScreenToOrtho(HardGuideRect, screenSize, curState.Lens.Aspect); cameraOffset += OrthoOffsetToScreenBounds(targetPos, hardGuideOrtho, 0); targetPos.x -= cameraOffset.x; targetPos.y -= cameraOffset.y; // Now move it through the soft zone, with damping cameraOffset += OrthoOffsetToScreenBounds(targetPos, softGuideOrtho, deltaTime); } curState.RawPosition = m_PreviousCameraPosition = localToWorld * (cameraPos + cameraOffset); //UnityEngine.Profiling.Profiler.EndSample(); }
/// <summary>Applies the composer rules and orients the camera accordingly</summary> /// <param name="state">The current camera state</param> /// <param name="statePrevFrame">The camera state on the previous frame (unused)</param> /// <param name="deltaTime">Used for calculating damping. If less than /// or equal to zero, then target will snap to the center of the dead zone.</param> /// <returns>curState with RawOrientation applied</returns> public override CameraState MutateCameraState( CameraState state, CameraState statePrevFrame, float deltaTime) { if (!IsValid || !state.HasLookAt) { return(state); } // Can't do anything without a group to look at CinemachineTargetGroup group = VirtualCamera.LookAt.GetComponent <CinemachineTargetGroup>(); if (group == null) { return(base.MutateCameraState(state, statePrevFrame, deltaTime)); } group.Update(); // Make sure the group's position is fully updated. state.ReferenceLookAt = group.transform.position; Vector3 lookAtPosition = GetTrackedPoint(state.ReferenceLookAt); Vector3 currentOffset = lookAtPosition - state.CorrectedPosition; float currentDistance = currentOffset.magnitude; if (currentDistance < UnityVectorExtensions.Epsilon) { return(state); // navel-gazing, get outa here } // Get the camera axis Vector3 fwd = currentOffset.AlmostZero() ? Vector3.forward : currentOffset.normalized; // Get the bounding box from that POV in view space, and find its width Bounds bounds = group.BoundingBox; m_lastBoundsMatrix = Matrix4x4.TRS( bounds.center - (fwd * bounds.extents.magnitude), Quaternion.LookRotation(fwd, state.ReferenceUp), Vector3.one); m_LastBounds = group.GetViewSpaceBoundingBox(m_lastBoundsMatrix); float targetHeight = GetTargetHeight(m_LastBounds); Vector3 targetPos = m_lastBoundsMatrix.MultiplyPoint3x4(m_LastBounds.center); // Apply damping if (deltaTime > 0 && m_FrameDamping > 0) { float delta = targetHeight - m_prevTargetHeight; delta *= deltaTime / Mathf.Max(m_FrameDamping * kHumanReadableDampingScale, deltaTime); targetHeight = m_prevTargetHeight + delta; } m_prevTargetHeight = targetHeight; // Move the camera if (!state.Lens.Orthographic && m_AdjustmentMode != AdjustmentMode.ZoomOnly) { // What distance would be needed to get the target height, at the current FOV float currentFOV = state.Lens.FieldOfView; float targetDistance = targetHeight / (2f * Mathf.Tan(currentFOV * Mathf.Deg2Rad / 2f)); // target the near surface of the bounding box float cameraDistance = targetDistance + m_LastBounds.extents.z; // Clamp to respect min/max distance settings cameraDistance = Mathf.Clamp( cameraDistance, currentDistance - m_MaxDollyIn, currentDistance + m_MaxDollyOut); cameraDistance = Mathf.Clamp(cameraDistance, m_MinimumDistance, m_MaximumDistance); // Apply state.PositionCorrection += targetPos - fwd * cameraDistance - state.CorrectedPosition; } // Apply zoom if (state.Lens.Orthographic || m_AdjustmentMode != AdjustmentMode.DollyOnly) { float nearBoundsDistance = (lookAtPosition - state.CorrectedPosition).magnitude - m_LastBounds.extents.z; float currentFOV = 179; if (nearBoundsDistance > UnityVectorExtensions.Epsilon) { currentFOV = 2f * Mathf.Atan(targetHeight / (2 * nearBoundsDistance)) * Mathf.Rad2Deg; } LensSettings lens = state.Lens; lens.FieldOfView = Mathf.Clamp(currentFOV, m_MinimumFOV, m_MaximumFOV); lens.OrthographicSize = targetHeight / 2; state.Lens = lens; } // Now compose normally return(base.MutateCameraState(state, statePrevFrame, deltaTime)); }