Beispiel #1
0
    /**
     * This is the optimal camera position that the camera moves towards
     */
    public Vector3 GetCameraDesiredPosition(float lookHorizontal, float lookVertical)
    {
        if (target == null)
        {
            return(lastCameraTargetPosition);
        }

        if (cameraType == ChaseCameraType.StayBehind)
        {
            Vector3 rotation = target.transform.rotation.eulerAngles;
            idealSpherical.polar = -rotation.y * Mathf.Deg2Rad - (Mathf.PI * 0.5f);
            if (lookHorizontalSpringDamped)
            {
                lookHorizontalActual = Damping.SpringDamping(lookHorizontalActual, lookHorizontal, ref lookHorizontalVelocity,
                                                             lookHorizontalSpringStiffness, lookHorizontalSpringDamping);
                idealSpherical.polar += lookHorizontalActual * (Mathf.PI * 0.99f);
            }
            if (lookVerticalSpringDamped)
            {
                lookVerticalActual = Damping.SpringDamping(lookVerticalActual, lookVertical, ref lookVerticalVelocity,
                                                           lookVerticalSpringStiffness, lookVerticalSpringDamping);

                idealSpherical.elevation = Mathf.Clamp(cameraPitch + lookVerticalActual * Mathf.PI, -Mathf.PI * 0.45f, Mathf.PI * 0.45f);
            }
            Quaternion q = Quaternion.FromToRotation(transform.TransformDirection(Vector3.up), target.position);
            transform.rotation = q * transform.rotation;
        }
        else
        {
            if (cameraType == ChaseCameraType.LooseAllowMovementUnderCamera)
            {
                Vector3 displacement = transform.position - target.position;
                if (displacement.sqrMagnitude < distance * distance)
                {
                    return(lastCameraTargetPosition);
                }
            }
            idealSpherical.polar = Mathf.Atan2(transform.position.z - target.position.z,
                                               transform.position.x - target.position.x);
        }
        Vector3 direction = idealSpherical.ToCartesian();

        lastCameraTargetPosition = target.position + direction;
        if (virtualCameraCollisionTest)
        {
            raycastCounter++;
            if (raycastCounter > 2)
            {
                raycastCounter = 0;
            }
            raycastResult[raycastCounter] = Physics.Raycast(target.position + raycastOffset[raycastCounter], direction, distance);

            RaycastHit[] hitInfo = Physics.SphereCastAll(target.position, virtualCameraCollisionRadius, direction, distance);

            float newCameraDistance = distance;
            bool  partialOcclusion  = !raycastResult[0] || !raycastResult[1] || !raycastResult[2];
            // allow partially occluded object if hit distance is less than 25% of pref. distance
            if (hitInfo.Length > 0)
            {
                for (int i = 0; i < hitInfo.Length; i++)
                {
                    bool partiallyOcclusionDistance = hitInfo[i].distance < distance * 0.25f;
                    if (!partiallyOcclusionDistance || !partialOcclusion)
                    {
                        newCameraDistance = hitInfo[i].distance;
                        break;
                    }
                }
            }

            float currentDistance = idealSpherical.radius;
            if (newCameraDistance < currentDistance ||
                newCameraDistance - currentDistance <= Mathf.Epsilon)              // don't damp if target is reached
            {
                idealSpherical.radius = newCameraDistance;
                vccMoveBackVelocity   = 0;
            }
            else
            {
                idealSpherical.radius = Damping.SpringDamping(idealSpherical.radius, newCameraDistance, ref vccMoveBackVelocity, vccMoveBackSpringStiffness, vccMoveBackSpringDamping);
            }

            // if distance was updated, then recalculate position
            if (currentDistance != idealSpherical.radius)
            {
                direction = idealSpherical.ToCartesian();
                lastCameraTargetPosition = target.position + direction;
            }
        }
        return(lastCameraTargetPosition);
    }
Beispiel #2
0
 // Start is called before the first frame update
 void Start()
 {
     sphericalCoordinates = new SphericalCoordinates(cam.position);
     cam.position         = sphericalCoordinates.ToCartesian() + pivot.position;
 }
Beispiel #3
0
 public void SetCamera()
 {
     cam.position = sphericalCoordinates.ToCartesian() + pivot.position; cam.LookAt(pivot);
 }