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 });
    }
Esempio n. 3
0
 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);
 }