Ugh, getting a camera to rotate around the player and pan up/down

Basically I have been working on a camera for like a week…getting nowhere but atleast learning more about how unity works. ;o

Basically I want my camera to pan up/down when the user holds down the mouse3 button (mousewheel) based on the difference of the mouse Y position between frames (I don’t know any other way).

Second, I want the user to actually rotate around the player itself based on the x axis of the mouse…I really don’t know how to go about doing this.

using UnityEngine;
using System.Collections;

public class myView : MonoBehaviour {

    public Transform myCam, playerObj;
    //public Vector3 camPos, camHeight, target, mouseWorld;
    public float mouseX, mouseY, prevMouseX, prevMouseY, xDiff, yDiff;

	void Start () {

        prevMouseX = Input.mousePosition.x * Input.GetAxis("Mouse X");
        prevMouseY = Input.mousePosition.y * Input.GetAxis("Mouse Y");
        mouseX = 0;
        mouseY = 0;
	
	}
	
	void Update () {

        //myCam.LookAt(playerObj.position);
        mouseX = Input.mousePosition.x * Input.GetAxis("Mouse X");
        mouseY = Input.mousePosition.y * Input.GetAxis("Mouse Y");
        xDiff = mouseX - prevMouseX;
        yDiff = mouseY - prevMouseY;

        if (Input.GetMouseButton(2)  yDiff != 0)
        {
            //supposed to be pan up/pan down....doesn't work.
            myCam.RotateAround(Vector3.right, yDiff * 0.009f);
        }

        if (Input.GetMouseButton(2)  xDiff != 0)
        {
            //ok I don't really know what to do here. I want to rotate around the player object itself
            //pretty sure this isn't right though  D:
            myCam.Rotate(playerObj.position, xDiff * 0.009f);
        }


        prevMouseX = mouseX;
        prevMouseY = mouseY;
	}
}

To use the script, I just put it on a camera, dragged that same camera to the “myCam” slot, dragged my player object (a square) to the "playerObj spot. Can someone check this code out or atleast give me some pointers on what to do? :stuck_out_tongue:

        if (Input.GetMouseButton(2)  xDiff != 0)
        {
            myCam.RotateAround(playerObj.position, Vector3.up, 180 * Input.GetAxis("Mouse X") * Time.deltaTime);
        }

        if (Input.GetMouseButton(2)  xDiff != 0)
        {
            myCam.RotateAroundLocal(Vector3.right, 5 * Time.deltaTime * Input.GetAxis("Mouse Y"));
        }

Ok I just tried this…it seems to work. Just need to tweak it a bit.

using UnityEngine;
using System.Collections;

public class myView : MonoBehaviour {

    public Transform myCam, playerObj;
    //public Vector3 camPos, camHeight, target, mouseWorld;
    public float mouseX, mouseY, prevMouseX, prevMouseY, xDiff, yDiff, mouseScroll;

	void Start () {

        prevMouseX = Input.mousePosition.x * Input.GetAxis("Mouse X");
        prevMouseY = Input.mousePosition.y * Input.GetAxis("Mouse Y");
        mouseX = 0;
        mouseY = 0;
	
	}
	
	void Update () {

        mouseScroll = Input.GetAxis("Mouse ScrollWheel");
        mouseX = Input.mousePosition.x * Input.GetAxis("Mouse X");
        mouseY = Input.mousePosition.y * Input.GetAxis("Mouse Y");
        xDiff = mouseX - prevMouseX;
        yDiff = mouseY - prevMouseY;

      
        if (Input.GetMouseButton(2)  xDiff != 0)
        {
            myCam.RotateAround(playerObj.position, Vector3.up, 250* Input.GetAxis("Mouse X") * Time.deltaTime);
        }

        //doesn't work
        if (Input.GetMouseButton(2)  yDiff != 0)
        {
            myCam.RotateAroundLocal(Vector3.right, 5 * Time.deltaTime * Input.GetAxis("Mouse Y"));
        }

        if (mouseScroll != 0)
        {
            myCam.Translate(Vector3.forward * 350 * Time.deltaTime * Input.GetAxis("Mouse ScrollWheel"));
        }

        myCam.LookAt(playerObj.position);
        prevMouseX = mouseX;
        prevMouseY = mouseY;
	}
}

Hey this here seems to work pretty much how I want it. The only thing is that it won’t pan up/down because “myCam.LookAt(is locking the view)”.

How can I lock the rotation of certain axes? w/o using LookAt()?

If you want it to pan up and down, you’d probably just want y mouse movement to move the camera up and down its y axis (and continue to LookAt() the player), not RotateAroundLocal its x axis?

I used the wrong term, sorry about that. Basically, I do want it to rotate around it’s local X. On its current position I want it to move up/down on its local X…kinda like bending your hand at the wrist.

Ok nm I did want it to pan up/down. But look at this code here. Check out the pan part. I commented where it is. It doesn’t do anything…I still think it’s because of the LookAt() function.

using UnityEngine;
using System.Collections;

public class myView : MonoBehaviour {

    public Transform myCam, playerObj;
    //public Vector3 camPos, camHeight, target, mouseWorld;
    public float mouseX, mouseY, prevMouseX, prevMouseY, xDiff, yDiff, mouseScroll;
    public bool isTooClose, isTooFar;
    public float dist;

	void Start () {

        prevMouseX = Input.mousePosition.x * Input.GetAxis("Mouse X");
        prevMouseY = Input.mousePosition.y * Input.GetAxis("Mouse Y");
        mouseX = 0;
        mouseY = 0;
        isTooClose = false;
        isTooFar = false;
	
	}
	
	void Update () {

        mouseScroll = Input.GetAxis("Mouse ScrollWheel");
        mouseX = Input.mousePosition.x * Input.GetAxis("Mouse X");
        mouseY = Input.mousePosition.y * Input.GetAxis("Mouse Y");
        xDiff = mouseX - prevMouseX;
        yDiff = mouseY - prevMouseY;


        //rotate around player
      
        if (Input.GetMouseButton(2)  xDiff != 0)
        {
            myCam.RotateAround(playerObj.position, Vector3.up, 250* Input.GetAxis("Mouse X") * Time.deltaTime);
        }

        //pan up/down .... doesn't work.
        if (Input.GetMouseButton(2)  yDiff != 0)
        {
            myCam.Translate(Vector3.up * Input.GetAxis("Mouse ScrollWheel") * 300, Space.Self);
        }

        //Mouse zoom begin
        if (mouseScroll != 0  isTooClose == false  isTooFar == false)
        {
             if (dist < 4.0f)
            {
                isTooClose = true;
                return;
            }

             if (dist > 22.0f)
             {
                 isTooFar = true;
                 return;
             }

            myCam.Translate(Vector3.forward * 350 * Time.deltaTime * Input.GetAxis("Mouse ScrollWheel"));

        }

        if (mouseScroll != 0  isTooClose == true)
        {
            float temp = Input.GetAxis("Mouse ScrollWheel");

            if (temp < 0)
            {
                myCam.Translate(Vector3.forward * 350 * Time.deltaTime * Input.GetAxis("Mouse ScrollWheel"));
                isTooClose = false;
            }
        }

        if (mouseScroll != 0  isTooFar == true)
        {
            float temp = Input.GetAxis("Mouse ScrollWheel");

            if (temp > 0)
            {
                myCam.Translate(Vector3.forward * 350 * Time.deltaTime * Input.GetAxis("Mouse ScrollWheel"));
                isTooFar = false;
            }
        }
        //Mouse Zoom End

        dist = Vector3.Distance(myCam.position, playerObj.position);

        myCam.LookAt(playerObj.position);
        prevMouseX = mouseX;
        prevMouseY = mouseY;
	}
}

Well it looks like you left the Mouse ScrollWheel thing in there, was that intentional?

No.

Ok it works now.

Ok now the camera goes through the terrain if I go too low on Y. What can I do to make the terrain solid and make the camera collide with it? :sunglasses:

Could probably do something similar to what you’re doing with your mousewheel stuff, except instead of using dist shoot a raycast downward (-Vector3.Up) a unit or so to determine if the camera is very close to the ground.

Nah that’s the thing. My game has canyons and different elevations on the terrain in general. If I do something like this:

if(rayToGroundDist < 5.0f)
return;

if I fall into one of my canyons or simply walk up on a hill, it will “float” or just get messed up. I need a way to detect a collision w/ the terrain mesh and the camera. O-o

I built the terrain w/ the built in terrain editor.

I would do a zoom not a above float. I wrote a full camera a while back and it has a collision test of the distance from the scroll wheel. It places the camera 1 unit from the offending collision so it doesnt show up.

dist=distance;
var hit : RaycastHit;
if(Physics.Raycast(camera.position, currentRotation * -Vector3.forward, hit, distance)){
	dist=(hit.point-camera.position).magnitude - 1;
}

all of it is here:

http://forum.unity3d.com/threads/76973-Car-Veiw-script-problem?p=493081&viewfull=1#post493081

//pan up/down
        if (Input.GetMouseButton(2)  yDiff != 0)
        {
            hit = Physics.Raycast(myCam.position, myCam.up*-1, 2, 0);
            if(hit == true)
            {
                return;
            }
                myCam.Translate(Vector3.up * Input.GetAxis("Mouse Y"));
        }

Tried this…doesn’t work. My terrain is a default terrain made with the terrain editor. It has a terrain collider on it…anything else needed?

if (Input.GetMouseButton(2)  yDiff != 0)
        {
            if (Physics.Raycast(myCam.position, Vector3.up * -1, out hit, 2.0f, 0))
            {
                myCam.Translate(hit.point - myCam.position);
                return;
            }
            
             myCam.Translate(Vector3.up * Input.GetAxis("Mouse Y"));
        }

Ok this doesn’t work either. I put a bool in the test loop…it’s not even detecting the collision.

Back…about to try and get this ray collision detection working again…if anyone has any pointers… O_O

BigMisterB, how exactly do you setup your camera? ;o

I want to see how it works along w/ reading the code.

And also, what is “damping”?

ok nevermind ;o