Gamedev: Keeping Characters Upright

You gotta walk the walk and since we’re not trying to simulate a drunk walk here, I’ve been putting some work into making a character controller with walk/strafe on the left stick and look on the right stick, as is custom in these here gamin’ parts.

Success! We’re upright and working!

It wasn’t a quick and easy thing. I did a lot of searching and nobody else seems to have had the answer to what I wanted. This is what it looked like before.

Well, the first reply (2nd tweet here) is what it looks like.

I’m not sure why WordPress wants to embed both of them but only for the second tweet. Thanks for breaking my embed, WP!

Anyhoo, I hope this helps someone as I didn’t easily find the answer when I looked.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerCharacterController : MonoBehaviour
{

	public float moveSpeed = 10f;
	public float rotationRate = 10.0f;
	public float jumpForce = 20.0f;
	public CharacterController controller;
	public float gravityScale = 1.0f;
	public Vector3 moveDirection;

	private string moveInputAxis = "Vertical";
	private string strafeInputAxis = "Horizontal";
	private string lookHorizontalAxis = "Mouse X";
	private string lookVerticalAxis = "Mouse Y";
	private float currentJumpForce;
	private bool isJumping = false;

	void Start()
	{
		controller = GetComponent<CharacterController>();
	}

	void Update()
	{
		float moveAxis = Input.GetAxis(moveInputAxis);
		float strafeAxis = Input.GetAxis(strafeInputAxis);

		ApplyInput(moveAxis, strafeAxis);
	}

	private void ApplyInput(float moveInput, float turnInput)
	{
		Move(moveInput, turnInput);
		moveDirection.y = moveDirection.y + (Physics.gravity.y * gravityScale);
		Jump();
		MouseLook();

		controller.Move(moveDirection * Time.deltaTime);
	}

	private void Move(float moveInput, float strafeInput)
	{
		// moveDirection = new Vector3(-turnInput * rotationRate, 0.0f, -moveInput * moveSpeed);
		Transform characterTransform = controller.GetComponent<Transform>();
		moveDirection = characterTransform.forward;
		Debug.DrawRay(characterTransform.position, moveDirection, Color.red);
		moveDirection.x = (characterTransform.forward * moveInput).x + (characterTransform.right * strafeInput).x;
		moveDirection.y = (characterTransform.forward * moveInput).y + (characterTransform.right * strafeInput).y;
		moveDirection.z = (characterTransform.forward * moveInput).z + (characterTransform.right * strafeInput).z;
		moveDirection *= moveSpeed;
		Debug.DrawRay(characterTransform.position, characterTransform.right * strafeInput * moveSpeed, Color.yellow);
		Debug.DrawRay(characterTransform.position, characterTransform.forward * moveInput * moveSpeed, Color.blue);
	}

	private void Jump()
	{
		if(!controller.isGrounded && isJumping) {
			Vector3 force = Vector3.up * jumpForce;
			moveDirection.y = --currentJumpForce;
		} else if(isJumping)
		{
			isJumping = false;
		}
		if (Input.GetButtonDown("Jump") && controller.isGrounded)
		{
			Debug.Log("Jumping!");
			currentJumpForce = jumpForce;
			Vector3 force = Vector3.up * jumpForce;
			moveDirection.y = currentJumpForce;
			isJumping = true;
		}
	}

	private void MouseLook()
	{
		float mouseXInput = Input.GetAxis(lookHorizontalAxis);
		float mouseYInput = -Input.GetAxis(lookVerticalAxis);
		Vector3 lookhere = new Vector3(mouseYInput, mouseXInput, 0);
		transform.Rotate(lookhere);

		// Keep us upright
		Quaternion rot = transform.rotation;
		rot = Quaternion.Euler(rot.eulerAngles.x, rot.eulerAngles.y, 0.0f); //null rotation Z
		transform.rotation = rot;
	}

}

By Lilithe

Dork.