Script help player controller
I have a player controller that allows for the player to walk around inside the curved surface of a cylinder. It works pretty well, however every time the player controller resets it's position to be upright relative to the curved surface, it's not a smooth transition, it kind of snaps into place. There is a variable that controls rotation and when I put it down low the rotation of the player as they move around the cylinder is smooth and looks how I want it to be.
Problem is when rotation is low it also effects the ability to turn the player controller, so you can look up and down but you can't look side to side. There is another variable that controls camera rotation but it doesn't seem to work. I can put rotation low and camera rotation high and I still can't look around freely.
Here is the script, i'm not sure why it's not working. I need the smooth rotation as the player controller stays upright as it walks around the curved surface, but not being able to look around is a downer. IT does work in tandem with a smaller script that goes on the object it sticks too, that all works fine, I just need to be able to look around with the rotation variable low.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
public class PlayerController : MonoBehaviour
{
public Rigidbody playerRigidbody;
public Transform groundChecker;
public Transform playerCamera;
public StickyGround stickyGround;
[Header("Movement Related")]
public float moveSpeed = 5f;
public float jumpHeight = 2f;
public float relativeRotationSpeed = 15f;
public float relativeCameraRotationSpeed = 35f;
public float groundDistance = 0.2f;
public float cameraSensitivity = 2f;
public Vector2 verticalCameraLimits = Vector2.zero;
private Vector3 verticalMovement;
private Vector3 horizontalMovement;
private Vector3 stickyMovement;
private float cameraXInput;
private float cameraYInput;
private Vector3 movementInput;
private Quaternion relativeRotation;
private Quaternion cameraRelativeRotation;
private bool hasJumped = false;
private bool isGrounded = false;
// Start is called before the first frame update
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
relativeRotation = transform.localRotation;
cameraRelativeRotation = playerCamera.localRotation;
}
// Update is called once per frame
void Update()
{
// Grounded check
isGrounded = Physics.CheckSphere(groundChecker.position, groundDistance, stickyGround.groundLayer, QueryTriggerInteraction.Ignore);
// Camera Input check
cameraYInput = CrossPlatformInputManager.GetAxis("Mouse X") * cameraSensitivity;
cameraXInput = CrossPlatformInputManager.GetAxis("Mouse Y") * cameraSensitivity;
// Movement Input Check
movementInput = transform.right * Input.GetAxis("Horizontal") + transform.forward * Input.GetAxis("Vertical");
// Jump Input check
if (!hasJumped)
{
hasJumped = Input.GetButtonDown("Jump");
}
}
private void FixedUpdate()
{
// Sticky Ground Rotations
RaycastHit hit;
if (Physics.Raycast(transform.position, -transform.up, out hit, 10f, stickyGround.groundLayer))
{
relativeRotation = Quaternion.LookRotation(Vector3.Cross(transform.right, hit.normal), hit.normal);
}
relativeRotation *= Quaternion.Euler(0f, cameraYInput, 0f);
transform.localRotation = Quaternion.Slerp(transform.localRotation, relativeRotation, relativeRotationSpeed * Time.deltaTime);
// Change relative gravity
Physics.gravity = -transform.up * Physics.gravity.magnitude;
// Jump Movement
if (isGrounded && hasJumped)
{
playerRigidbody.AddForce(transform.up * Mathf.Sqrt(jumpHeight * -2f * -9.81f), ForceMode.VelocityChange);
hasJumped = false;
}
// Sticky Movement
if (isGrounded)
{
movementInput += stickyGround.GetRotationDirection(transform);
//Debug.DrawRay(transform.position, stickyGround.GetRotationDirection(transform),Color.cyan,2f);
}
// Player Movement
playerRigidbody.MovePosition(playerRigidbody.position + movementInput * moveSpeed * Time.fixedDeltaTime);
Debug.DrawRay(transform.position, -transform.up, Color.red, 1f);
//Debug.DrawRay(transform.position, transform.right, Color.green, 1f);
Debug.DrawRay(transform.position, transform.forward, Color.yellow, 1f);
}
private void LateUpdate()
{
// Camera Relative Rotation
cameraRelativeRotation *= Quaternion.Euler(-cameraXInput, 0f, 0f);
cameraRelativeRotation = ClampRotationAroundXAxis(cameraRelativeRotation);
playerCamera.localRotation = Quaternion.Slerp(playerCamera.localRotation, cameraRelativeRotation, relativeCameraRotationSpeed * Time.deltaTime);
}
Quaternion ClampRotationAroundXAxis(Quaternion q)
{
q.x /= q.w;
q.y /= q.w;
q.z /= q.w;
q.w = 1.0f;
float angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan(q.x);
angleX = Mathf.Clamp(angleX, verticalCameraLimits.x, verticalCameraLimits.y);
q.x = Mathf.Tan(0.5f * Mathf.Deg2Rad * angleX);
return q;
}
}