Daily Musings

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);

		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,;
		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,;

	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)
			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);

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

Daily Musings

Tenk Werz

I’ve been working hard over the past month, using NaNoWriMo combined with a Trello board as a goal tracking mechanism. The goal? I made a game, of course!

Tenk Werz is a 3/4 perspective artillery game. The goal of this exercise was to re-create one of the originals. Tank Wars for DOS.

I started vlogging around the same time as I started this project, so my vlogs were mostly about the process of developing Tenk Werz and what I did to keep myself going.

All in all it’s been fun, and I hope you give the game a try on!