Need camera to follow player, but not the player's rotation.

So I'm building a simple platform game (think something like Mario, prince of persia, take your pick etc). The camera follows the player through the level, simply by being a child of the player's object.

The problem is that I made my character turn back and forth. I.E. if you are facing right and hit the left key, the character object is turned 180 degrees. That works great, except that the camera (being a child of the the Player) also turns 180 degrees!

Is there a way I can lock the camera's rotation, or just have it follow the player's movement on the X and Y axis, without taking the player's rotation?

I can think of some bizarre solutions that might work, but I'm betting there is a cleaner, more efficient solution then for example un-parenting the player from the camera before a flip, and then re-parenting the player to the camera afterward.

Thanks for all your help, having a blast with Unity :)

Here ya go!
This is probably as simple as it can get!
Un-Parent the Camera from the Player, And attach this script to the camera.
Then simply drag you character into the script’s target slot.

var target : Transform;
var distance : Float;
function Update(){

    transform.position.z = target.position.z -distance;
    transform.position.y = target.position.y;
    transform.position.x = target.position.x;

}

Have Fun!
-Navi

Easiest way would be to unparent the camera. And throw something similar to the following in your update.

int DistanceAway = 10;
Vector3 PlayerPOS = GameObject.Find("Player").transform.transform.position;
GameObject.Find("MainCamera").transform.position = new Vector3(PlayerPOS.x, PlayerPOS.y, PlayerPOS.z - DistanceAway);

This will keep the camera bound the the players X and Y coordinates while placing the camera 10 meters from the player. Then all you have to do is the the cameras rotation in the editor. That or for the rotation use .LookAt(target); with the player being the target.

var camTarget:Transform;
function Start () {

}

function Update () {

transform.LookAt(camTarget);

}

Hey!

Take a look at the 2d platformer tutorial: here and check out the script on the camera

good luck

cheers!

Put this on the camera:

 function LateUpdate() 
 {  
 camera.transform.rotation=Quaternion.Euler(Vector3(90, 0, 0));  // 90 degress on the X axis - change appropriately
 }

It forces the rotation. I dont know if this is the best way of doing this but works.

I did something similar said by unfoundfate. The code that is attached to the camera goes like this:-

var Stone : GameObject;

function Update()
{
    transform.position.y= Stone.transform.position.y; 
// in this case I only needed to care about the height
}

this was attached to the camera, now drag and drop the gameobject from Hierarchy(or prefab) to the Stone in Inspector panel. This worked!

Just put this script on your Main Camera. Set the cameraOrientationVector to how far from your character you want it to be. And tilt the camera in scene view for the angle.

 using UnityEngine;
        using System.Collections;
        
        public class CameraScript : MonoBehaviour 
        {
        	Transform playerTransform;
        	
        	Vector3 cameraOrientationVector = new Vector3 (0, 15, -10f);
        	

void Start () 
	{
		
		
		
		playerTransform = GameObject.Find ("Player").transform;
	}
        	
        void LateUpdate () 
        	{
        		
        		transform.position = playerTransform.position + cameraOrientationVector;
        		
        	}
        }

public Camera PlayerCamera;
public GameObject Spawn;

void Update() {
Vector3 CamPos = new Vector3(player.transform.position.x,player.transform.position.y,0);
camera.transform.position = CamPos;
}

this code will “parent” the camera to the players x and y position, but allows you to control the Z pos and rotation yourself.

Sorry to be a complete noob.

I’ve Un-parented the camera from the player, then created a new Js script and pasted the code Navigatron gave above then dropped the script onto the camera.

However, I get the following error. “Assets/Standard Assets/Character Controllers/Sources/Scripts/transform.js(5,16): BCE0018: The name ‘Float’ does not denote a valid type (‘not found’).”

And no target slot is created.

I just had great luck by implementing the following code in C#, follows player transform but not rotation. Note it requires the object to be followed to be tagged as “Player”, still new to Unity and not sure how to reference directly:

public class CameraMovement : MonoBehaviour
{
private Transform player;
private Vector3 relCameraPos;

void Awake()
{
	player = GameObject.FindGameObjectWithTag("Player").transform;
	relCameraPos = player.position-transform.position;
}
void Update()
{
	transform.position = player.position-relCameraPos;
}

}

I just ran into this same problem and this is how I solved it…

I have a character and I have a CLOSEUP camera locked to it, facing the character. It activates and deactivates as I swap cameras around to different shots. This CLOSEUP camera is looking directly at the character to get a reaction shot and is perfect except when the character rotates. Then you get the weird GoPro-on-a-Flex-Clamp-facing-me effect, which I do not want. When I am getting a reaction shot and the character turns, I want the camera to remain steady.

I tried the scripts above but they became too cumbersome trying to figure out the right way to rotate & such as this character is moving and looking in all sorts of directions.

So, what I did was duplicate the parented camera (CAM 1) and unparented the dup (CAM 2). I then deactivated CAM 1 but left is attached to the parent so that it worked exactly as before. This camera (CAM 1) stays deactivated throughout the scene.

I then attached a script to CAM 2 so that it has a reference to CAM 1 and OnEnable (not Update), it updates it’s position and rotation to match the reference CAM 2…

public class CameraLocs : MonoBehaviour {

[SerializeField] private Transform cam1;


// Use this for initialization
void Start () {
	
}

// Update is called once per frame
void Update () {
	
}

void OnEnable() {
	
	if (target) {
		transform.position = cam1.position;
		transform.rotation = cam1.rotation;
	}
	
}

}

Note that this is done OnEnable, so CAM 1 continues on it’s swinging way but CAM 2 remains fixed in the location where it was when it turned on. It then is turned off, character moves, turned on, updates to face the character again. No problems.

Easy. And as far as I know, there’s not much or any cost to having the extra deactivated camera hanging about. No worse than my trying to calculate the new position and rotation; and I assume the Unity people can do that a whole lot better than I can. (If I am wrong about this, please let me know. Thanks)

This setup may be more complex, but you could create an anchor to follow the object’s position, and then add a camera object as a child of the anchor with an offset.

For the anchor, you’d have the code:

public Transform target;
private Transform myTransform; //So we're not using GameObject.GetComponent() every frame

void Update(){
     myTransform.position = target.position;
}

You make the camera a child of the anchor, and then change its position and rotation in the Inspector window until you get the view you want.

This last part may be overkill, but you can additionally position empty game objects into the character as target transforms for the camera anchor to center on.

This setup uses more game objects, but it gives more control to the camera system. The anchor can act as a pivot that follows the target (and rotates, if you give it that functionality). It takes care of transformations in world space. The camera’s local transform values won’t be affected by the anchor’s. This makes it easier to do cool things with the camera in local space, like panning or zooming via script, because you don’t have to worry about where the camera is in world space. There probably are some limitations to this setup, but I’m not sure what they are.

private GameObject player;
private Camera mainCamera;
private float zdistance = 3;
private float ydistance = 5;

void Start()
{
    player = GameObject.FindGameObjectWithTag("Player");
    mainCamera = GetComponent<Camera>();
}

void LateUpdate()
{
    mainCamera.transform.position = new Vector3(player.transform.position.x, (player.transform.position.y + ydistance), (player.transform.position.z - zdistance));
}

P.S. it has to be late update or it spazzes out

years later i feel dumb af reading this.

[SerializeField] private GameObject player;

private void Start()
{
    
}

private void Update()
{
    transform.position = new Vector3(player.transform.position.x, 10.0f,player.transform.position.z);
}

public GameObject Cam;
public float distance;

void Update()
{
transform.position = new Vector3(Cam.transform.position.x, Cam.transform.position.y, distance)

}

Or put it in FixedUpdate if it seems jittery.