- Home /
Trying to get a third person camera to be movable and lock in place when not being moved
I'm new and don't really know what I'm doing working with rotations and the camera. I found a script in a free asset that almost does what I want and I started modifying it. The code below is what I have right now.
I'm trying to get the camera to zoom in and out from the player with the scroll wheel, rotate around the player and up and down by holding down the right mouse button and moving the mouse, and then trying to get the camera to stay locked in place relative to the player when you are not moving the camera IE you have the camera on your right side and turn while running and its still on your right side.
This script works exactly like I want it to now except for one major glitch. If I turn the player at all and then go to move the camera again it will jump to a new position at the first click of the mouse. After that it works just how I want it too until I turn the player again. I'm hoping someone knows an easy way to fix this.
Edit: the camera is a child of the player object and the script is attached to it.
public class ThirdPersonCamera : MonoBehaviour
{
private const float Y_ANGLE_MIN = 0.0f;
private const float Y_ANGLE_MAX = 80.0f;
public Transform lookAt; //this is set in inspecter to the characters head.
public Transform camTransform;
public float distance = 5.0f; //how far away the camara is
private float currentX = 0.0f;
private float currentY = 45.0f;
private float speed = 3f; //speed multiplier for moving camera.
Quaternion rotation;
private void Start()
{
camTransform = transform;
rotation = Quaternion.Euler(currentY, currentX, 0); //get camera in the starting position.
camTransform.position = lookAt.position + rotation * new Vector3(0, 0, -distance);
}
private void Update()
{
distance -= Input.mouseScrollDelta.y * 40 * Time.deltaTime; // mouse scroll to change cameras distance from player.
distance = Mathf.Clamp(distance, 0.7f, 10f); //stop camera from going into player or way far away.
if (Input.GetMouseButton(1)) //try to get the camera to only move while holding down right mouse button.
{
currentX += Input.GetAxis("Mouse X") * speed;
currentY -= Input.GetAxis("Mouse Y") *speed; //- so camera goes the other way
currentY = Mathf.Clamp(currentY, Y_ANGLE_MIN, Y_ANGLE_MAX);
}
}
private void LateUpdate()
{
Vector3 dir = new Vector3(0, 0, -distance);
if (Input.GetMouseButton(1) || Input.mouseScrollDelta.y != 0) //trying to keep the camera locked in place relative to the player when not moving the camera.
{
rotation = Quaternion.Euler(currentY, currentX, 0);
camTransform.position = lookAt.position + rotation * dir;
}
camTransform.LookAt(lookAt.position);
}
}
Answer by CybexGS · Mar 15, 2019 at 10:31 AM
Put this in your Update()
method;
camTransform.position = Vector3.MoveTowards(camTransform.position, camTransform.position + camTransform.forward * Input.mouseScrollDelta.y, 1);
if (Input.GetMouseButton(1))
{
camTransform.RotateAround(lookAt.position, Vector3.up, Input.GetAxis("Mouse X") * speed);
camTransform.RotateAround(lookAt.position, camTransform.right, -Input.GetAxis("Mouse Y") * speed);
}
and you can get rid of the entire LateUpdate()
.
Now, there is no clamping / limits to movement implemented in there yet, but it should otherwise behave the way you want it to.
Thank you for this. The camera jumping no longer happens and it seems like it should work how I want after I put the clamps back in.
You're very welcome. Let me know if you're having trouble with the clamping, the system now is entirely different than before.
I have gotten the distance clamped and don't really care about the y clamp at the moment. There was one issue with the $$anonymous$$ distance clamp where the camera would sometimes jump to the other side of the player but this doesn't need to be fixed as my plan all along has been to move the camera into a first person view once you zoom in past the $$anonymous$$ distance.
I already have it working where it moves the camera into first person after zoo$$anonymous$$g in and goes back to third person when zoo$$anonymous$$g out. Now I just need to figure out the mouse look part of the first person view. I shouldn't need help with that though because I have done it before in tutorials and can just go back to them if I can't figure it out.
Thanks again for your help it would have been awhile before I could have gotten this done on my own.
Answer by Somewittyname · Mar 14, 2019 at 09:05 PM
Thanks for the reply.
This example doesn't seem to work for me. The camera will no longer rotate when I hold down the mouse button and it will still jump to a new position when I hit mouse button after turning the character.
I'm assuming the camTransform.position = lookAt.posistion + rotation * dir; is what is changing the camera's position. Unfortunately I don't understand the math here as it was part of the script before I started modifying it.
What value is multiplying those 2 vectors together intended to give? Why does it only drastically change the position after the character has rotated and then seem to move smoothly? Why doesn't it do the same thing if I hold down the mouse button the entire time (it seems to not jump when moving around then)?
Somehow it seems to be deciding a rotation for the camera vastly different then what it was on the first frame of the click and then it moves the camera to match that rotation and still be the same distance away and looking at the player.
Oh well I guess I'll work on something else for now and figure it out later after I learn some of the math involved. I already bought a Udemy course on math for games and just haven't done it yet.
Yes, you're right. Doesn't work at all. But there is a lot more to it, i think.
What happens, or shall hapen if you release the R$$anonymous$$B? Shall the camera snap back in its original position behind the player or shall the player change the walk direction?
The camera stays in the same place relative to the player and moves with him and looks at him when the R$$anonymous$$B is released which is exactly what I want it to do. If the player turns with R$$anonymous$$B released the camera again moves with the player and stays looking at him at the same angle which is what I want.
If you hold down the R$$anonymous$$B and run in a straight line you can move the mouse around the player and it doesn't change the direction he is running in again as I want it to do.
If you hold down R$$anonymous$$B and turn while running then it changes the angle of the player facing the camera again as intended.
The camera does not snap back to the starting position or to the same position each time it happens. I'm not sure what the logic is that is deciding where it goes. It always stays at the same distance from the player and looks at him though just from a different position.
Playing around with it some more it does look like the camera wants to keep having the blue transform line face in about the same direction each time it happens.
The camera is a child of the Player object, right?
Answer by Cornelis-de-Jager · Mar 14, 2019 at 10:24 PM
Hi, the solution below isn't tested, and doesn't contain rotation restrictions, but give it a try and tell me if it works for you.
[SerializedField]
Transform player;
Transform cam;
Vector3 offsetDir;
float distance;
float camDelay;
float camRotSpeed;
float camScrollSpeed;
void Start () {
cam = Camera.Main.transform;
offsetDir = cam.position - player.position;
}
public FixedUpdate () {
// Function to handle the adjusted camera
HandleAdjustment();
// Function to handle the camera following the player
HandleCameraMovement ();
}
void HandleAdjustment () {
// Change Distance
distance -= Input.mouseScrollDelta.y * camScrollSpeed * Time.deltaTime;
distance = Mathf.Clamp(distance, 0.7f, 10f);
// Dont do anything if the right mouse is not held down
if (!Input.GetKey(KeyCode.MouseButton(1)))
return;
offsetDir += new Vector3(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"), 0) * camRotSpeed * Time.DeltaTime;
}
void HandleCameraMovement () {
var targetLocation = (offsetDir).normalized * distance;
cam.position = Vector3.Lerp (cam.position, targetLocation, camDelay);
cam.LookAt(player.position + new Vector3 (0,player.localScal.y / 2,0));
}
Your answer
Follow this Question
Related Questions
Please Help !, camera rotation 1 Answer
How do I create a camera script like one that would be in a racing game? 0 Answers
Scale Z Axis Movement According to Camera Tilt (Drag Control Camera) 0 Answers
3rd Person Camera inversion 2 Answers
Setting the camera position depending on the position of 2 objects 2 Answers