3

I don't usually post here but it has taken me hours now trying to figure this out and I've searched the net already but couldn't find the answer. I'm wishing someone might be able to assist me here. I'm a newbie and this is the first time I'm trying to combine two types of Third Person Camera Control that follows the Players movement in Unity C#:

  1. Camera Snaps to a pre-defined Position and Rotation as the Player Moves (No Mouse Look)
  2. Mouse Look activates when a Mouse Button is held down and so the Camera rotates according to Mouse movement whether the Player's Position is changing or not

It almost works except that I cannot seem to reset the Mouse Look to its first ever pre-defined setting. After the Player releases the Mouse Button, the code for #1 kicks in and so the Camera seem to go back to its default view. But doing further Mouse Looks, I noticed the Camera always returns to the last position & rotation it was deactivated. I need it to go back to the original pre-defined position & rotation even before the Player activates his first Mouse Look so its not too disorienting for the Player.

I tried several codes but couldn't get it to work so I removed non working lines and just posted those that I think are applicable ones. Please refer to my code below. Would appreciate it if someone can help me. Thanks in advance!

Edit: Updated the code to have two methods of controlling the Camera and added suggested code to reset the currentX & Y values. Comment/uncomment each of the method call to test. But I still have the problem of not being able to smooth out the zooming of the mouse look.

Final Edit: I have again updated the code below, cleaned it up, and included the suggested changes. Code should now be fully working and has no jitters. Thanks for the assistance! :-)

Last Final Edit: Added "Field of View Zooming" by Mouse Wheel and so have completed the code.

using UnityEngine;
using System.Collections;

public class PlayerViewController : MonoBehaviour {

    // General Vars
    public Transform targetFollow;
    private bool lookAround = false;

    // For SmoothDampFollow
    public Vector3 followDefaultDistance = new Vector3 (0f, 12.0f, -20f);
    public float followDistanceDamp = 0.2f;
    public Vector3 followVelocity = Vector3.one;

    // For Camera Orbit
    public float orbitDistance = 20.0f;
    public float orbitDamp = 5.0f;
    private const float angleMinY = 7.0f;
    private const float angleMaxY = 50.0f;    
    private float currentX = 7.0f;
    private float currentY = 50.0f;

    // For Zooming Field Of View
    public float FOVmin = 50.0f;
    public float FOVmax = 100.0f;
    public float mouseWheelSpeed = 5.0f;

    void Update () {

        if (Input.GetMouseButtonDown (1)) {

            currentX = transform.eulerAngles.y;
            currentY = transform.eulerAngles.x;

        }

        if (Input.GetMouseButton (1)) {

            lookAround = true;

        } else {

            lookAround = false;

        }

        ZoomFOV ();

    }

    void FixedUpdate () {

        if (lookAround) {

            CameraOrbit ();

        } else {

            SmoothDampFollow ();

        }

    }

    void ZoomFOV () {

        if (Input.GetAxis ("Mouse ScrollWheel") > 0) {

            GetComponent<Camera> ().fieldOfView =  GetComponent<Camera> ().fieldOfView - mouseWheelSpeed;

            if (GetComponent<Camera> ().fieldOfView <= FOVmin) { GetComponent<Camera> ().fieldOfView = FOVmin; }

        } else if (Input.GetAxis ("Mouse ScrollWheel") < 0) {

            GetComponent<Camera> ().fieldOfView = GetComponent<Camera> ().fieldOfView + mouseWheelSpeed;

            if (GetComponent<Camera> ().fieldOfView >= FOVmax) { GetComponent<Camera> ().fieldOfView = FOVmax; }

        }

    }

    void SmoothDampFollow () {

        if (!targetFollow) {

            return;

        } else {

            Vector3 wantedPosition = targetFollow.position + (targetFollow.rotation * followDefaultDistance);
            transform.position = Vector3.SmoothDamp (transform.position, wantedPosition, ref followVelocity, followDistanceDamp);
            transform.LookAt (targetFollow, targetFollow.up);

        }

    }

    void CameraOrbit () {

        if (!targetFollow) {

            return;

        } else {

            currentX += Input.GetAxis ("Mouse X");
            currentY += Input.GetAxis ("Mouse Y");
            currentY = Mathf.Clamp (currentY, angleMinY, angleMaxY);
            Vector3 dir = new Vector3 (0, 0, -orbitDistance);
            Quaternion rotation = Quaternion.Euler (currentY, currentX, 0);
            Vector3 wantedPosition = targetFollow.position + rotation * dir;
            transform.position = Vector3.Lerp (transform.position, wantedPosition, Time.deltaTime * orbitDamp);
            transform.LookAt (targetFollow.position);

        }

    }

}
Brel
  • 43
  • 7

1 Answers1

0

Updated: Try this

void LateUpdate()
{

    if (lookAround)
    {

        currentX += Input.GetAxisRaw("Mouse X");
        currentY += Input.GetAxisRaw("Mouse Y");
        currentY = Mathf.Clamp(currentY, angleMinY, angleMaxY);
        Vector3 dir = new Vector3(0, 0, -distance);
        Quaternion rotation = Quaternion.Euler(currentY, currentX, 0);

        Vector3 wantedPosition = target.position + rotation * dir;
        transform.position = Vector3.Lerp(transform.position, wantedPosition, Time.deltaTime * damping);

        camTransform.LookAt(target.position);

    }
        ...

And

void Update()
{
    // Here
    if (Input.GetMouseButtonDown(1))
    {
        currentX = transform.eulerAngles.y;
        currentY = transform.eulerAngles.x;
    }
    if (Input.GetMouseButton(1))
    { 
        ...

What i've done is i reset the currentX and currentY to their current eulerangle-values on mouse-press in Update(). And i've added a position Lerp to the wanted lookAround position in LateUpdate()

EDIT:

Though I still haven't fixed the smooth zooming of the mouse look when right mouse button is initially held down

Try this change

void CameraOrbit()
{
    currentX += Input.GetAxisRaw("Mouse X");
    currentY += Input.GetAxisRaw("Mouse Y");
    currentY = Mathf.Clamp(currentY, angleMinY, angleMaxY);
    Vector3 dir = new Vector3(0, 0, -distance);
    Quaternion rotation = Quaternion.Euler(currentY, currentX, 0);

    // -->
    Vector3 wantedPosition = target.position + rotation * dir;
    transform.position = Vector3.Lerp(transform.position, wantedPosition, Time.deltaTime * damping);
    // <--

    camTransform.LookAt(target.position);
}
Fredrik Widerberg
  • 3,068
  • 10
  • 30
  • 42
  • Actually, I think it works the first time because the Player has never ever held the Right Mouse Button yet and so the original currentX and currentY private default values set above is taken. I tried resetting currentX and currentY under Updates by adding those same default values when lookAround is false but it still doesn't work after the Player has started moving. – Brel Jun 02 '18 at 08:10
  • Tried the new lines of code and they finally work but the movement became very jittery. Especially noticeable when viewing the sides in mouse look mode while Player is moving. So I stuck with the old code in LateUpdate but used your code for the transform.eulerAngles.x & y in the Update section which now correctly resets the starting view in Mouse look. Another problem now is how to convert the jumpy camera zoom into something smooth when the right Mouse button is held down. Tried using Lerp but cannot end it after it reaches the intended zoom level making the camera jittery. – Brel Jun 02 '18 at 16:51
  • I have modified the code above after doing some more research. I've included two types of Camera Controls just to test out the jitters and segregated these into two methods for clarity: SmoothDampFollow and the previous SmoothFollow. But I discovered placing those codes under FixedUpdate instead of LateUpdate somehow removed the jitters when the Player moves. CameraOrbit does not have any jitters and is quite smooth as before. Though I still haven't fixed the smooth zooming of the mouse look when right mouse button is initially held down. – Brel Jun 02 '18 at 19:15
  • Nice, it worked and no more jitters! I had to return the GetMouseButtonDown code section. Updated the final working code above and cleaned it up a little. I appreciate all the help, thank you very much! – Brel Jun 03 '18 at 14:40
  • Added "Field of View Zooming by Mouse Wheel" and so have completed the code. – Brel Jun 04 '18 at 08:18