- Home /
3D Custom Character Controller Movement Directions are going Haywire
I have a player controller script, and it's moving the guy in weird directions when moving and I can't seem to nail the pattern of it's behavior. But it does seem to move sideways after turning 90 degrees, then forward again after another 90 degrees.
Player Script:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (PlayerController))]
public class Player : MonoBehaviour {
private PlayerController controller;
public GameObject mainCamera;
private float mouseX;
private float mouseY;
public float xSensitivity;
public float ySensitivity;
private Vector3 velocity;
public float moveSpeed;
public float jumpForce;
void Start () {
controller = GetComponent <PlayerController> ();
}
void Update () {
if (Input.GetKey (KeyCode.W))
{
velocity.z = moveSpeed;
}
else if (Input.GetKey (KeyCode.S))
{
velocity.z = -moveSpeed;
}
else
{
velocity.z = 0;
}
if (controller.isGrounded)
{
if (Input.GetKey (KeyCode.Space))
{
velocity.y = jumpForce;
}
else
{
velocity.y = 0;
}
}
else
{
velocity.y += Physics.gravity.y * Time.deltaTime;
}
controller.Move (velocity * Time.deltaTime);
mouseX += Input.GetAxisRaw ("Mouse X") * xSensitivity * Time.deltaTime;
transform.rotation = Quaternion.Euler (0, mouseX, 0);
mouseY -= Input.GetAxisRaw ("Mouse Y") * ySensitivity * Time.deltaTime;
mainCamera.transform.localRotation = Quaternion.Euler (mouseY, 0, 0);
}
}
Player Controller Script:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (CapsuleCollider))]
public class PlayerController : MonoBehaviour {
private CapsuleCollider colliderRef;
public float skinWidth;
public int rayCount;
private float raySpacing;
private float left, right, bottom, top, back, front;
public LayerMask layermask;
public bool isGrounded;
void Start () {
colliderRef = GetComponent <CapsuleCollider> ();
UpdateRaycastOrigins ();
CheckForGround ();
}
void Update () {
CheckForGround ();
}
public void Move (Vector3 velocity) {
UpdateRaycastOrigins ();
CalculateRaySpacing ();
CollideHorizontally (ref velocity);
CollideVertically (ref velocity);
ColliderDepthically (ref velocity);
transform.Translate (transform.right * velocity.x + transform.up * velocity.y + transform.forward * velocity.z);
}
void UpdateRaycastOrigins () {
left = colliderRef.bounds.min.x + skinWidth;
right = colliderRef.bounds.max.x - skinWidth;
bottom = colliderRef.bounds.min.y + skinWidth;
top = colliderRef.bounds.max.y - skinWidth;
back = colliderRef.bounds.min.z + skinWidth;
front = colliderRef.bounds.max.z - skinWidth;
}
void CalculateRaySpacing () {
float bodyHeight = colliderRef.height - colliderRef.radius * 2;
raySpacing = (bodyHeight - skinWidth * 2) / (rayCount - 1);
}
void CollideHorizontally (ref Vector3 velocity) {
float direction = Mathf.Sign (velocity.x);
float rayLength = Mathf.Abs (velocity.x) + skinWidth;
for (int x = 0; x < rayCount; x ++)
{
Vector3 rayPos = Vector3.zero;
rayPos.z = (back + front) / 2;
if (direction == -1)
{
rayPos.x = left;
}
else
{
rayPos.x = right;
}
rayPos.y += x * raySpacing;
RaycastHit hit;
if (Physics.Raycast (rayPos, Vector3.right * direction, out hit, rayLength, layermask))
{
velocity.x = (hit.distance - skinWidth) * direction;
rayLength = hit.distance;
}
}
}
void CollideVertically (ref Vector3 velocity) {
float direction = Mathf.Sign (velocity.y);
float rayLength = Mathf.Abs (velocity.y) - skinWidth;
Vector3 rayPos = Vector3.zero;
if (direction == -1)
{
rayPos.y = bottom;
}
else
{
rayPos.y = top;
}
RaycastHit hit;
if (Physics.Raycast (rayPos, Vector3.up * direction, out hit, rayLength, layermask))
{
velocity.y = hit.distance * direction;
rayLength = hit.distance + skinWidth;
}
}
void ColliderDepthically (ref Vector3 velocity) {
float direction = Mathf.Sign (velocity.z);
float rayLength = Mathf.Abs (velocity.z) + skinWidth;
for (int z = 0; z < rayCount; z ++)
{
Vector3 rayPos = Vector3.zero;
rayPos.x = (left + right) / 2;
if (direction == -1)
{
rayPos.z = back;
}
else
{
rayPos.z = front;
}
rayPos.y += z * raySpacing;
RaycastHit hit;
if (Physics.Raycast (rayPos, Vector3.forward * direction, out hit, rayLength, layermask))
{
velocity.z = (hit.distance - skinWidth) * direction;
rayLength = hit.distance;
}
}
}
void CheckForGround () {
Vector3 rayPos = new Vector3 (transform.position.x, bottom, transform.position.z);
RaycastHit hit;
if (Physics.Raycast (rayPos, Vector3.down, out hit, skinWidth, layermask))
{
isGrounded = true;
}
else
{
rayPos = new Vector3 (left, colliderRef.bounds.min.y + colliderRef.radius, back);
if (Physics.Raycast (rayPos, Vector3.down, out hit, colliderRef.radius, layermask))
{
isGrounded = true;
}
else
{
rayPos = new Vector3 (right, colliderRef.bounds.min.y + colliderRef.radius, back);
if (Physics.Raycast (rayPos, Vector3.down, out hit, colliderRef.radius, layermask))
{
isGrounded = true;
}
else
{
rayPos = new Vector3 (left, colliderRef.bounds.min.y + colliderRef.radius, front);
if (Physics.Raycast (rayPos, Vector3.down, out hit, colliderRef.radius, layermask))
{
isGrounded = true;
}
else
{
rayPos = new Vector3 (right, colliderRef.bounds.min.y + colliderRef.radius, front);
if (Physics.Raycast (rayPos, Vector3.down, out hit, colliderRef.radius, layermask))
{
isGrounded = true;
}
else
{
isGrounded = false;
}
}
}
}
}
}
}
I still am having trouble with this, it would be nice to get some help soon :/
Your answer
Follow this Question
Related Questions
3d animation controller 0 Answers
If player is restricted on a value, why does it not "snap" back? 1 Answer
Make controller able to move backwards if mouse button is held down 0 Answers
Stick player (my own rigidbody controller) to the ground when going down the slope 2 Answers
How do I set up my players controller script (How do I change the controls used to move and look) 2 Answers