HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Generic FPS movement controller with Xbox One controller support

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
genericwithcontrollermovementonefpsxboxsupport

Problem

I'm currently working on an FPS shooter game and I needed a generic movement controller that supported both keyboard and Xbox One controller input. My main goal in designing this controller was to address two common issues that occurred in previous FPS controllers I've designed, which are:

  • Diagonal movement (strafing) caused the player to move about twice as fast when a keyboard setup was being used.



  • Jumping in a setting with a low ceiling caused the player to 'stick' to said ceiling.



Here's the code:

```
using UnityEngine;
using System.Collections;

///
/// This class is responsible for controlling the players movement.
///
[RequireComponent(typeof(CharacterController))]
public class CharacterMovementController : MonoBehaviour
{
public bool UseController;
public Vector3 JumpSpeed;
public Vector3 GravitySpeed;
public Vector2 MovementSpeed;
public Vector2 CameraRotationSpeed;
public Vector2 CameraRotationConstraints;

public CharacterController CharacterController { get; set; }
public Vector3 MovementVector { get; set; }
public float VerticalRotation { get; set; }

///
/// Rotate the player.
///
public void Rotate()
{
if(this.UseController)
{
this.transform.Rotate(new Vector3(0.0f, Input.GetAxis("Xbox Look X"), 0.0f) this.CameraRotationSpeed.x Time.deltaTime);
this.VerticalRotation += Input.GetAxis("Xbox Look Y") this.CameraRotationSpeed.y Time.deltaTime;
this.VerticalRotation = Mathf.Clamp(this.VerticalRotation, this.CameraRotationConstraints.x, this.CameraRotationConstraints.y);

Camera.main.transform.eulerAngles = new Vector3(
-this.VerticalRotation,
Camera.main.transform.eulerAngles.y,
Camera.main.transform.eulerAngles.z
);
}

else
{
this.transform.Rotate(new Vector3(0.0f, Input.GetAxis("Mouse X"), 0.0f) * this.CameraRotationSpeed.

Solution

Rotate()

In this method the only difference between the if branches are the getting of the X and Y location. It would be enough to place getting these in the branches and therefor you could remove some of the duplicated code but it would be much better just assigning the string's, which are needed, to two variables like so

var xKey = "Mouse X";
var yKey = "Mouse Y";
if(this.UseController)
{
    xKey = "Xbox Look X";
    yKey = "Xbox Look Y";
}
this.transform.Rotate(new Vector3(0.0f, Input.GetAxis(xKey), 0.0f) * this.CameraRotationSpeed.x * Time.deltaTime);
this.VerticalRotation += Input.GetAxis(yKey) * this.CameraRotationSpeed.y * Time.deltaTime;
this.VerticalRotation = Mathf.Clamp(this.VerticalRotation, this.CameraRotationConstraints.x, this.CameraRotationConstraints.y);

Camera.main.transform.eulerAngles = new Vector3(
    -this.VerticalRotation,
    Camera.main.transform.eulerAngles.y,
    Camera.main.transform.eulerAngles.z
    );

Code Snippets

var xKey = "Mouse X";
var yKey = "Mouse Y";
if(this.UseController)
{
    xKey = "Xbox Look X";
    yKey = "Xbox Look Y";
}
this.transform.Rotate(new Vector3(0.0f, Input.GetAxis(xKey), 0.0f) * this.CameraRotationSpeed.x * Time.deltaTime);
this.VerticalRotation += Input.GetAxis(yKey) * this.CameraRotationSpeed.y * Time.deltaTime;
this.VerticalRotation = Mathf.Clamp(this.VerticalRotation, this.CameraRotationConstraints.x, this.CameraRotationConstraints.y);

Camera.main.transform.eulerAngles = new Vector3(
    -this.VerticalRotation,
    Camera.main.transform.eulerAngles.y,
    Camera.main.transform.eulerAngles.z
    );

Context

StackExchange Code Review Q#163397, answer score: 3

Revisions (0)

No revisions yet.