Skip to content

Instantly share code, notes, and snippets.

@gekidoslair
Last active July 12, 2023 03:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gekidoslair/053b31be5718bead684c492f7ea4c540 to your computer and use it in GitHub Desktop.
Save gekidoslair/053b31be5718bead684c492f7ea4c540 to your computer and use it in GitHub Desktop.
Camera-relative character movement controller. Does not handle animation, but has some comments where you'd want to add the hooks
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace PixelWizards.GameSystem.Controllers
{
// the data model for the character controller. I like to keep vars like this in a separate class to organize them
// and keep the main controller script as clean as possible.
// because it is set to be serializable, these vars are exposed in the editor (except where noted) when you attach
// the CharController component to your character
[System.Serializable]
public class CharacterData
{
public float walkSpeed = 1.0f;
public float runSpeed = 6f;
public float slowDownModifier = 10f;
public float moveThreshold = 0.1f;
public float desiredSpeed = 0f;
public float currentSpeed = 0f;
public float jumpSpeed = 8.0f;
public float gravity = 20.0f;
public Vector3 moveDirection = Vector3.zero;
[HideInInspector]
public Vector3 lastDirection = Vector3.zero;
public Camera mainCamera;
[HideInInspector]
public Vector3 forward;
[HideInInspector]
public Vector3 right;
public float h;
public float v;
public float moveSpeed = 0f;
public bool isMoving = false;
}
// the actual monobehaviour that you attach to your character.
public class CharController : MonoBehaviour
{
// set up the data model.
public CharacterData model = new CharacterData();
private CharacterController controller;
// public AnimController animController; // hook up animation controls if desired
private void Start()
{
// animController = GetComponent<AnimController>();
controller = GetComponent<CharacterController>();
// automagically find the main camera in the scene
model.mainCamera = Camera.main;
}
private void ResetInput()
{
model.isMoving = false;
}
private void Update()
{
ResetInput();
// save where we were going last frame so we can lerp
model.lastDirection = model.moveDirection;
if (controller.isGrounded)
{
// camera-relative movement
model.forward = model.mainCamera.transform.TransformDirection(Vector3.forward);
model.forward.y = 0;
model.forward = model.forward.normalized;
model.right = new Vector3(model.forward.z, 0, -model.forward.x);
// grab input
model.h = Input.GetAxis("Horizontal");
model.v = Input.GetAxis("Vertical");
// figure out which direction we're going
model.moveDirection = (model.h*model.right + model.v*model.forward).normalized;
// apply move speed - add run / other move modes and apply their movement speed in a similar manner
model.desiredSpeed = model.walkSpeed;
model.moveDirection *= Mathf.Lerp(model.currentSpeed, model.desiredSpeed, Time.deltaTime);
}
// apply gravity
var gravity = model.gravity*(Time.deltaTime*50); // multiply delta time by magic # to get gravity working properly. wee
// apply gravity
model.moveDirection.y -= gravity;
// Actually do the move
controller.Move(model.moveDirection * Time.deltaTime);
// look the way we are moving (rotates to face direction)
model.moveDirection.y = 0f;
model.currentSpeed = model.moveDirection.magnitude;
if (model.currentSpeed > model.moveThreshold)
{
// tell the animation system how fast we are going
//animController.SetMoveSpeed( model.currentSpeed);
transform.rotation = Quaternion.LookRotation(model.moveDirection);
}
else
{
// tell the animation system that we've stopped
//animController.SetMoveSpeed(0f);
}
}
}
}
@gekidoslair
Copy link
Author

A very basic camera-relative character controller that will rotate to face towards the direction the character is moving.

Every time I have to build one of these I can't find a good sample to start from, so here you go.

You can see the comments where you can communicate with a separate component (dubbed AnimController) to set variables for mecanim etc to control animation blends etc.

@gekidoslair
Copy link
Author

fixed the 'getcomponent' and variable creation in Update

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment