void Update() { float mouseY = Input.GetAxis("Mouse Y"); float mouseX = Input.GetAxis("Mouse X"); CameraPitchAngle += mouseY * InputSensitivity * Time.deltaTime; CameraPitchAngle = Mathf.Clamp(CameraPitchAngle, CameraPitchAngleMin, CameraPitchAngleMax); if (FollowedObject.transform.position != targetLastPosition) { Vector3 direction = FollowedObject.transform.position - targetLastPosition; Vector2 newDir2d = new Vector2(direction.x, direction.z).normalized; dir2d = Vector2.Lerp(dir2d, newDir2d, AimingBlendFactor); } Vector3 cameraPosition = new Vector3(-dir2d.x, Mathf.Sin(CameraPitchAngle * Mathf.Deg2Rad), -dir2d.y) * Distance; CameraDesc cameraDesc = new CameraDesc(); cameraDesc.view = Camera.main.cameraToWorldMatrix; cameraDesc.projection = Camera.main.projectionMatrix; cameraDesc.nearClipPlane = Camera.main.nearClipPlane; cameraDesc.fieldOfView = Camera.main.fieldOfView; cameraDesc.aspect = Camera.main.aspect; cameraDesc.position = FollowedObject.transform.position + cameraPosition; cameraDesc.view = Matrix4x4.LookAt(Camera.main.transform.position, FollowedObject.transform.position, Vector3.up); Vector3 surfaceNormal; var frustrumPoints = ExtractFrustrumNearPlanePoints(cameraDesc); float distance = GetMinimumCollisionDistanceFromTarget(frustrumPoints, out surfaceNormal); float adjustedDistance; if (distance != -1) { adjustedDistance = distance; } else { adjustedDistance = Distance; } cameraPosition = new Vector3(-dir2d.x, Mathf.Sin(CameraPitchAngle * Mathf.Deg2Rad), -dir2d.y) * adjustedDistance; float e = Mathf.Tan(Camera.main.fieldOfView * Mathf.Deg2Rad); Vector3 offsetFromSurface = surfaceNormal * e * Camera.main.nearClipPlane; transform.position = FollowedObject.transform.position + cameraPosition + offsetFromSurface; transform.LookAt(FollowedObject.transform); targetLastPosition = FollowedObject.transform.position; }
Vector3[] ExtractFrustrumNearPlanePoints(CameraDesc camera) { float zn = camera.nearClipPlane; float fovRadians = Mathf.Deg2Rad * camera.fieldOfView; float e = Mathf.Tan(fovRadians * 0.5f); Vector4 axisX = camera.view.GetColumn(0); Vector4 axisY = camera.view.GetColumn(1); Vector4 axisZ = camera.view.GetColumn(2); Vector3 nearCenter = axisZ * zn; float nearExtX = e * zn; float nearExtY = nearExtX / camera.aspect; Vector4 cameraPos = camera.position; Vector4 BL = cameraPos + axisX * -nearExtX + axisY * -nearExtY + axisZ * zn; Vector4 BR = cameraPos + axisX * nearExtX + axisY * -nearExtY + axisZ * zn; Vector4 TR = cameraPos + axisX * nearExtX + axisY * nearExtY + axisZ * zn; Vector4 TL = cameraPos + axisX * -nearExtX + axisY * nearExtY + axisZ * zn; return(new Vector3[] { BL, BR, TR, TL }); }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(CameraDesc obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }