Force a rotation in character controller

Hey there,
I’ve got a simple FPS-like project. I’m using a modified character controller (this one by Ben Esposito) which should be quite the same as the standard FPS controller: a character controller component, a movement script, a mouselook for the X axis in the main gameobject, another mouselook for the Y axis in the camera.

My problem: I’ve got a simple teleport function that should teleport you to a checkpoint location. What I would like is to teleport the controller and have its forward direction aligned with the checkpoint forward (so that you basically start from the new checkpoint by looking to the direction I want.

So I’ve implemented a simple resetplayer method on my main script that the teleport routine can call, by passing the checkpoint transform.

Here is the bit of code for this part:

public void resetPlayer (Transform place) {
        transform.position=place.position;
        Screen.lockCursor=false;
        transform.rotation = place.rotation;
        Screen.lockCursor=true;
    }

(the lockCursor calls are an attempt to overcome my problem).

The problem is that the teleport works correctly, but the rotation is still the one I had before teleporting. Basically the Mouselook routine takes over and rotates my player back to where the mouse was pointing. Is there a way to “reset” the mouse position, so I’ll start turned the right way? Here is the code of the Mouselook function, just for checking what it does (pretty standard, I figure):

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MouseLook : MonoBehaviour
{
    public enum RotationAxes { MouseX = 1, MouseY = 2 }
    public RotationAxes axes = RotationAxes.MouseX;
    public bool invertY = false;
   
    public float sensitivityX = 10F;
    public float sensitivityY = 9F;
    public float minimumX = -360F;
    public float maximumX = 360F;
    public float minimumY = -85F;
    public float maximumY = 85F;
    float rotationX = 0F;
    float rotationY = 0F;
    private List<float> rotArrayX = new List<float>();
    float rotAverageX = 0F;   
    private List<float> rotArrayY = new List<float>();
    float rotAverageY = 0F;
    public float framesOfSmoothing = 5;
    Quaternion originalRotation;
   
    void Start ()
    {           
        if (rigidbody)
        {
            rigidbody.freezeRotation = true;
        }
       
        originalRotation = transform.localRotation;
    }
    void Update ()
    {
        if (axes == RotationAxes.MouseX)
        {           
            rotAverageX = 0f;
            rotationX += Input.GetAxis("Mouse X") * sensitivityX * Time.timeScale;
            rotArrayX.Add(rotationX);
            if (rotArrayX.Count >= framesOfSmoothing)
            {
                rotArrayX.RemoveAt(0);
            }
            for(int i = 0; i < rotArrayX.Count; i++)
            {
                rotAverageX += rotArrayX[i];
            }
            rotAverageX /= rotArrayX.Count;
            rotAverageX = ClampAngle(rotAverageX, minimumX, maximumX);
            Quaternion xQuaternion = Quaternion.AngleAxis (rotAverageX, Vector3.up);
            transform.localRotation = originalRotation * xQuaternion;           
        }
        else
        {           
            rotAverageY = 0f;
             float invertFlag = 1f;
             if( invertY )
             {
                 invertFlag = -1f;
             }
            rotationY += Input.GetAxis("Mouse Y") * sensitivityY * invertFlag * Time.timeScale;
           
            rotationY = Mathf.Clamp(rotationY, minimumY, maximumY);
    
            rotArrayY.Add(rotationY);
            if (rotArrayY.Count >= framesOfSmoothing)
            {
                rotArrayY.RemoveAt(0);
            }
            for(int j = 0; j < rotArrayY.Count; j++)
            {
                rotAverageY += rotArrayY[j];
            }
            rotAverageY /= rotArrayY.Count;
            Quaternion yQuaternion = Quaternion.AngleAxis (rotAverageY, Vector3.left);
            transform.localRotation = originalRotation * yQuaternion;
        }
    }
   
    public void SetSensitivity(float s)
    {
        sensitivityX = s;
        sensitivityY = s;
    }
    public static float ClampAngle (float angle, float min, float max)
    {
        angle = angle % 360;
        if ((angle >= -360F) && (angle <= 360F)) {
            if (angle < -360F) {
                angle += 360F;
            }
            if (angle > 360F) {
                angle -= 360F;
            }           
        }
        return Mathf.Clamp (angle, min, max);
    }
}

Hello,

myPlayer.rotation = myPlace.rotation should work. In that cas, i will prefer to use a :
myPlayer.transform.LookAt (myPlace.transform.forward);

But the result depends ont the setting of gameObjects. If “place” is a child of another object, it can have a “0” rotation. In that case you need the place.parent rotation. (That’s a totally guess, your issue can come from elsewhere : ) )

If your mouselook script is interfering, disable it until the teleportation is finished.

Make a public method in your Mouse Look with 2 float parameters (x and y rotations), and assign those parameters to rotationX and rotationY. Then call that function in resetPlayer, passing the desired euler x and y rotations.

Also do rotArrayX.Clear() and rotArrayY.Clear() in the new function.

I’ve tried adding a method in my MouseLook (since all the other solutions don’t appear to be working – the Mouselook keeps memory of your rotation, so disabling and then enabling it back doesn’t work).

The method works like this:

public void RotationReset(float rX, float rY) {
        rotArrayX.Clear ();
        rotArrayY.Clear ();
        rotationX=rX;
        rotationY=rY;
    }

And I call it from the resetplayer method like this:

public void resetPlayer (Transform place) {
        transform.position=place.position;
        mouselook.RotationReset(place.localRotation.eulerAngles.x, place.localRotation.eulerAngles.y);
    }

I’m using localRotation since the checkpoints are children of another object. Now, if I debug place.localRotation.EulerAngles I obtain the correct values. But the player object when teleported is rotated at 0,0,0 no matter what.

What I’m doing wrong?

Ok, got it. I was switching X and Y angles (since mouseX is actually a rotation on the Y axis)