0
votes

This is the script i'm using attached to the Main Camera. I can rotate the camera 360 degrees. But the character(ThirdPersonController) is keep standing idle facing same position all the time.

I want to make that when i rotate the camera that also the character will rotate.

And a problem i have is i can rotate the came to the ground level a bit under it. How can i limit the camera rotation to the ground/terrain level ? This is a screenshot what i mean the camera is under the terrain/character:

Screenshot

And this is the script code: I tried to add this line to rotate the character with the camera but it's not doing it, it does nothing.

transform.rotation = Quaternion.RotateTowards(transform.rotation, rotation, rotationSpeed);

The script:

using UnityEngine;
using System.Collections;

[AddComponentMenu("Camera-Control/Mouse Orbit with zoom")]
public class MouseOrbitImproved : MonoBehaviour
{

    public Transform target;
    public float distance = 5.0f;
    public float xSpeed = 120.0f;
    public float ySpeed = 120.0f;

    public float yMinLimit = -20f;
    public float yMaxLimit = 80f;

    public float distanceMin = .5f;
    public float distanceMax = 15f;

    private Rigidbody rigidbody;

    float x = 0.0f;
    float y = 0.0f;

    public float rotationSpeed = 5f;

    // Use this for initialization
    void Start()
    {
        Vector3 angles = transform.eulerAngles;
        x = angles.y;
        y = angles.x;

        rigidbody = GetComponent<Rigidbody>();

        // Make the rigid body not change rotation
        if (rigidbody != null)
        {
            rigidbody.freezeRotation = true;
        }
    }

    void LateUpdate()
    {
        if (target)
        {
            x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
            y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;

            y = ClampAngle(y, yMinLimit, yMaxLimit);

            Quaternion rotation = Quaternion.Euler(y, x, 0);

            distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);

            RaycastHit hit;
            if (Physics.Linecast(target.position, transform.position, out hit))
            {
                distance -= hit.distance;
            }
            Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
            Vector3 position = rotation * negDistance + target.position;

            transform.rotation = rotation;
            transform.position = position;

            transform.rotation = Quaternion.RotateTowards(transform.rotation, rotation, rotationSpeed);
        }
    }

    public static float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360F)
            angle += 360F;
        if (angle > 360F)
            angle -= 360F;
        return Mathf.Clamp(angle, min, max);
    }
}

I created a new small clean script that should rotate the character according to the camera rotation. The above script is attached to the Main Camera.

Now i have the ThirdPersonController and i have a script already attached to it:

using UnityEngine;
using System.Collections;

public class ClickToMove : MonoBehaviour
{
    public int speed = 5; // Determines how quickly object moves towards position
    public float rotationSpeed = 5f;

    private Vector3 targetPosition;
    private Animator _animator;
    private Vector3 destination;
    private Quaternion targetRotation;

    void Start()
    {
        _animator = GetComponent<Animator>();
        _animator.CrossFade("Idle", 0);
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Mouse0))
        {
            _animator.CrossFade("Walk", 0);
            Plane playerPlane = new Plane(Vector3.up, transform.position);
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            float hitdist = 0.0f;

            if (playerPlane.Raycast(ray, out hitdist))
            {
                Vector3 targetPoint = ray.GetPoint(hitdist);
                targetPosition = ray.GetPoint(hitdist);
                targetRotation = Quaternion.LookRotation(targetPoint - transform.position);
                destination = targetPosition;
            }
        }

        transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotationSpeed);

        if ((transform.position - destination).magnitude < 0.7f)
        {
            _animator.CrossFade("Idle", 0);
        }
    }
}

This script is working fine. Also the script above that rotate the camera. But once i attach to the ThirdPersonController the new small script that should rotate the character so first it's not rotating the character and second it's making the character to walk on forward the whole ClickToMove script is not working good.

using UnityEngine;
using System.Collections;

public class RotateCharacterToCamera : MonoBehaviour {

    void Update () {

        Vector3 characterPosition = transform.position;
        Vector3 cameraPosition = Camera.main.transform.position;
        Vector3 delta = new Vector3(characterPosition.x - characterPosition.x, 0.0f, characterPosition.z - characterPosition.z);
        transform.LookAt(delta);

    }
}
1

1 Answers

0
votes

I guess simply adjusting the yMinLimit value to 0 or less should be enough to limit your camera vertical angle.

About your character rotation, you should have a small script on him that calls something like :

Vector3 characterPosition = transform.position;
Vector3 cameraPosition = Camera.main.transform.position;
Vector3 delta = new Vector3(characterPosition.x - characterPosition.x, 0.0f, characterPosition.z - characterPosition.z);
transform.LookAt(delta);

I set the y value of delta vector to 0 so only the "horizontal" orientation of the camera will be considered.