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); }
/// <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; } curState.ReferenceLookAt = GetLookAtPointAndSetTrackedPoint(group.transform.position); Vector3 currentOffset = TrackedPoint - 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 = (TrackedPoint - 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(); }