Well, i didnt mess with character movement since a long time. But here i found some of my old and very messy code if it helps.
It wont work straight away, you need to delete refferences to Core class and might need to do some more deleting here and there. This is just for your refference.
CharController.cs
using UnityEngine;
using System.Collections;
[System.Serializable]
public class CharController_Motion {
//Public Variables
//Walking
public float walkSpeed = 2.0f;
public float runSpeed = 4.0f;
public float slideSpeed = 5.0f;
//Jumping
public float jumpHeight = 1.0f;
public int jumpTimerDelay = 15;
//Falling
public float maxFallDistance = 15.0f;
//Others
public float gravity = 20.0f;
//Private Variables
internal int jumpTimer;
internal bool isFalling = false;
internal float fallBegin = 0.0f;
internal float fallEnd = 0.0f;
internal float fallDistance = 0.0f;
internal Vector3 direction = Vector3.zero;
internal Vector3 hitPoint = Vector3.zero;
}
[System.Serializable]
public class CharController_Physics {
//Public Variables
public float pushPower = 2.0f;
public LayerMask pushLayers = -1;
}
[System.Serializable]
public class CharController_InputManager {
//Private Variables
internal Vector3 direction = Vector3.zero;
internal Quaternion rotation = Quaternion.identity;
internal bool run = false;
internal bool jump = false;
internal bool crouch = false;
}
[AddComponentMenu ("Aubergine/Character/CharController")]
[RequireComponent (typeof (CharacterController))]
public class CharController : MonoBehaviour {
//Class declerations
public CharController_Motion cc_Motion = new CharController_Motion();
public CharController_Physics cc_Physics = new CharController_Physics();
public CharController_InputManager cc_InputManager = new CharController_InputManager();
//Internal Variables
internal Transform trs;
internal CharacterController cc;
internal Rigidbody rbd;
internal float ccHeight;
//Private Variables
private Vector3 moveDirection;
private float moveSpeed, jumpSpeed;
private CollisionFlags collFlags;
private Vector3 groundNormal;
void Awake () {
//Get Components
trs = GetComponent<Transform>();
cc = GetComponent<CharacterController>();
rbd = GetComponent<Rigidbody>();
if (rbd) rbd.freezeRotation = true;
}
void Start () {
//Init class declerations
cc_Motion.jumpTimer = cc_Motion.jumpTimerDelay;
//Init private variables
moveDirection = Vector3.zero;
moveSpeed = cc_Motion.walkSpeed;
jumpSpeed = cc_Motion.jumpHeight;
collFlags = CollisionFlags.None;
groundNormal = Vector3.zero;
ccHeight = cc.height;
//ccCenter = cc.center;
}
void FixedUpdate () {
if (Core.App.paused)
return;
//Rotation
trs.rotation = cc_InputManager.rotation;
//Motion
if (cc.isGrounded) {
//Get world direction and speed of motion
moveDirection = trs.TransformDirection (cc_InputManager.direction);
moveSpeed = cc_InputManager.run ? cc_Motion.runSpeed : cc_Motion.walkSpeed;
moveDirection *= moveSpeed;
//Push down to ground for consistent isGrounded check
float groundPush = Mathf.Max(cc.stepOffset, new Vector3(moveDirection.x, 0, moveDirection.z).magnitude);
moveDirection -= groundPush * Vector3.up;
//Slide down hills
if (Is_TooSteep ()) {
Vector3 slopeDirection = new Vector3 (groundNormal.x, 0.0f, groundNormal.z).normalized;
//Vector3 projectedDirection = Vector3.Project(moveDirection, slopeDirection);
//moveDirection = (slopeDirection + projectedDirection + (moveDirection - projectedDirection)) * cc_Motion.slideSpeed;
moveDirection += slopeDirection * cc_Motion.slideSpeed;
//moveDirection.y -= cc_Motion.gravity * Time.deltaTime;
}
//Crouching
if (cc_InputManager.crouch cc_Motion.jumpTimer > 0) {
if (cc.height != ccHeight * 0.5f) {
cc.height = ccHeight * 0.5f;
cc.center = new Vector3(0.0f, 0.5f, 0.0f);
}
}
else {
if (cc.height != ccHeight) {
cc.height = ccHeight;
cc.center = new Vector3(0.0f, 1.0f, 0.0f);
}
}
//Jumping
if (cc_InputManager.jump cc_Motion.jumpTimer >= cc_Motion.jumpTimerDelay !Is_TouchingCeiling ()) {
//Dont crouch in air
if (cc.height != ccHeight) {
cc.height = ccHeight;
cc.center = new Vector3(0.0f, 1.0f, 0.0f);
}
//Keep jumping
cc_Motion.jumpTimer = 0;
jumpSpeed = cc_InputManager.crouch ? cc_Motion.jumpHeight * 2.0f : cc_Motion.jumpHeight;
moveDirection.y = Mathf.Sqrt (2.0f * jumpSpeed * cc_Motion.gravity);
}
else {
cc_Motion.jumpTimer++;
cc_Motion.jumpTimer = Mathf.Clamp (cc_Motion.jumpTimer, 0, cc_Motion.jumpTimerDelay);
}
//Falling
if (cc_Motion.isFalling) {
cc_Motion.isFalling = false;
cc_Motion.fallDistance = cc_Motion.fallBegin - trs.position.y;
if (cc_Motion.fallDistance > cc_Motion.maxFallDistance)
SendMessage("ApplyDamage", 10);
//ApplyFallDamage (cc_Motion.fallDistance);
}
}
else {
if (Is_TouchingCeiling ()) {
moveDirection.y -= cc_Motion.gravity * Time.deltaTime;
}
//Get fall begin position
if (!cc_Motion.isFalling) {
cc_Motion.isFalling = true;
cc_Motion.fallBegin = trs.position.y;
}
//Apply gravity
moveDirection.y -= cc_Motion.gravity * Time.deltaTime;
}
//Move the character
collFlags = cc.Move (moveDirection * Time.deltaTime);
}
void OnControllerColliderHit (ControllerColliderHit hit) {
if (Core.App.paused)
return;
//Check hit body info
groundNormal = (hit.collider.GetType() == (typeof (BoxCollider)) ? Vector3.up : hit.normal);
cc_Motion.hitPoint = hit.point;
//Pushing rigidbodies
Rigidbody hitBody = hit.collider.attachedRigidbody;
if (hitBody == null || hitBody.isKinematic) return;
LayerMask hitBodyLayerMask = 1 << hitBody.gameObject.layer;
if ((hitBodyLayerMask cc_Physics.pushLayers.value) == 0) return;
if (hit.moveDirection.y < -0.3f) return;
Vector3 pushDirection = new Vector3 (hit.moveDirection.x, 0.0f, hit.moveDirection.z);
hitBody.velocity = pushDirection * cc_Physics.pushPower;
}
private bool Is_TooSteep () {
return (groundNormal.y <= Mathf.Cos (cc.slopeLimit * Mathf.Deg2Rad));
}
private bool Is_TouchingCeiling () {
return (collFlags CollisionFlags.Above) != 0;
}
private void ApplyFallDamage (float fallDistance) {
Debug.Log ("Fall distance: " + fallDistance);
}
}
CharInput.cs
using UnityEngine;
using System.Collections;
[AddComponentMenu ("Aubergine/Character/CharInput")]
[RequireComponent (typeof (CharController))]
[RequireComponent (typeof (CharInteractor))]
public class CharInput : MonoBehaviour {
//Public Variables
public Transform fpsCamera;
public float cameraMaxHeadAngle = 80.0f;
public float mouseSensitivity = 10.0f;
//Private Variables
private CharController controller;
private CharInteractor interactor;
private CharacterController cc;
private Vector3 direction;
private Quaternion qBody, qCamera;
private float directionLength, xRotation, yRotation;
void Awake () {
controller = GetComponent<CharController>();
interactor = GetComponent<CharInteractor>();
cc = GetComponent<CharacterController>();
direction = Vector3.zero;
qBody = transform.rotation;
qCamera = fpsCamera.localRotation;
directionLength = xRotation = yRotation = 0.0f;
}
void Update () {
if (Core.App.paused)
return;
//Get Direction
direction = new Vector3 (Input.GetAxis ("Strafe"), 0.0f, Input.GetAxis ("Walk"));
if (direction != Vector3.zero) {
directionLength = direction.magnitude;
direction = direction / directionLength;
//Analog joystick stuff
directionLength = Mathf.Min(1, directionLength);
directionLength = directionLength * directionLength;
direction = direction * directionLength;
}
//Get Rotation
xRotation += Input.GetAxis("Mouse X") * mouseSensitivity;
xRotation = AngleWrap(xRotation, -360, 360);
yRotation -= Input.GetAxis("Mouse Y") * mouseSensitivity;
yRotation = AngleWrap(yRotation, -cameraMaxHeadAngle, cameraMaxHeadAngle);
//Pass values to character controller interactor
controller.cc_InputManager.rotation = qBody * Quaternion.AngleAxis (xRotation, Vector3.up);
controller.cc_InputManager.direction = direction;
controller.cc_InputManager.run = Input.GetButton ("Run");
controller.cc_InputManager.jump = Input.GetButton ("Jump");
controller.cc_InputManager.crouch = Input.GetButton ("Crouch");
interactor.interact = Input.GetButton ("Interact");
//Adjust position if crouching
fpsCamera.localPosition = new Vector3 (0.0f, cc.height - 0.1f, 0.0f);
//Rotate Camera Individually
fpsCamera.localRotation = qCamera * Quaternion.AngleAxis (yRotation, Vector3.right);
}
//Wraps angle around
public static float AngleWrap (float v, float min, float max) {
if (v < -360.0f) v += 360.0f;
if (v > 360.0f) v -= 360.0f;
return Mathf.Clamp(v, min, max);
}
}