Hey there,
I have been working on a game using a first person controller. After using charactercontroller for a while, I switched to a Rigidbody character controller for in-air movement functions that were easier with rigidbodies. However, this created a new issue.
I have a few teleporters, essentially just adding a given value to the players position. This makes the player teleport to different places. However, an issue came up where the player was teleported under the map. After some debugging I found out this was due to the player coordinates, mainly the y-value, changing when the camera was rotated using the mouse. I have no clue why or how this happens, but freezing the y movement in the rigidbody component helped. A different thread recommended fixing the center of mass, which kind of helped after placing the center of mass to (0, 10, 0), because the y position would only switch between 0, -9.1… and +9.1… The location values change, without the player position changing visibly. This makes the player teleport to -9.1 under the map when going through a teleporter.
Added some screenshots here:
As you can see, here the y value of the player position is 0.
And after just rotating the camera a bit, suddenly the y value jumped to -9.5… without the player visibly moving.
Relevant code:
[Header("Script References")]
[SerializeField] private gc gcscript; // groundcheck script
[Space]
[Header("Object/Component References")]
[SerializeField] private Transform pb; // player capsule body
[SerializeField] private Transform ch; // Player Camera Holder Transform
[SerializeField] private Transform c; // Player Camera Transform
[SerializeField] private Rigidbody rb; // Player Rigidbody
[Space]
[Header("Character Movement Properties")]
[SerializeField] private float nSpeed; // Normal speed
[SerializeField] private float cSpeed; // crouch speed
[SerializeField] private float crSpeed; // crawl speed
[SerializeField] private float sSpeed; // sprint speed
[SerializeField] private float aSpeed; // in-air speed
[SerializeField] private float jForce; // jump force
[Space]
[Header("Camera Properties")]
[SerializeField] private float sens; // Sensitivity
[SerializeField] private float clamp = 85f; // maximum/minimum rotation of camera
[SerializeField] private float scms; // Smooth Camera Movement Speed
void Start()
{
calcSpeed = nSpeed; // Set calculated speed to normal speed
Cursor.lockState = CursorLockMode.Locked; //lock cursor
rb.centerOfMass = new Vector3(0, 10, 0);
} // call on script start, set standard values for vars, lock cursor
private void EarlyUpdate() // first call, get non-movement inputs and calculations
{
g = gcscript.g; // set ground bool equal to groundcheck ground bool variable
}
void Update() // second call, calculate and execute movement and camera input, player physics
{
EarlyUpdate(); // Call EarlyUpdate function
pmInput = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical")); // Get player input (WASD keys)
cInput = new Vector2(Input.GetAxis("Mouse X") * sens * Time.deltaTime, Input.GetAxis("Mouse Y") * sens * Time.deltaTime); // Get Mouse Input (Mouse movement)
Movement(); // call function for player movement
Cam(); // call function for camera movement
}
private void Movement() // move player and jump
{
Vector3 MoveVector = transform.TransformDirection(pmInput) * calcSpeed; // calculate movement
rb.velocity = new Vector3(MoveVector.x, rb.velocity.y, MoveVector.z); // move player
if(Input.GetButtonDown("Jump") && g && (stat == 0 || stat == 3)) // if jump key defined in input manager is pressed AND player is grounded AND playerstatus is either walking or sprinting
{
rb.AddForce(Vector3.up * jForce, ForceMode.Impulse); // Add instantaneous force up
}
}
private void Cam() // calculate camera and player rotation
{
xRot -= cInput.y; // Calculate vertical input
xRot = Mathf.Clamp(xRot, -clamp, clamp); //clamp camera rotation
ch.transform.localRotation = Quaternion.Euler(xRot, 0f, 0f); //rotate camera based on mouse
transform.Rotate(new Vector3(0, cInput.x, 0)); //rotate player body based on mouse
}
Notes: This is not the full code. The code also has functions for view bobbing, crouching/crawling, calculating the speed of the character based on the playerstatus sprinting, walking, crouching or crawling, smooth camera movement and player scale modding for crouching and crawling, and other stuff. These have no influence or relevance to the problem and this code, except for a few references in if statements. I can provide the full code if needed, though it won’t make much difference.
Any help will be much appreciated
Cheers, Euranium