2
\$\begingroup\$

I'm currently building a game called "Drones! Attack!", and I needed a drone controller that the player can use. It's currently very simple and only supports a small amount of actions, such as:

  • Basic movement (forward, backward, left, right, up, down)
  • FPS camera control
  • Camera scoping (e.g, changing the FOV from a higher value to a lower value to get a "zoomed" effect.

There are a fair amount of things I'm wondering:

  • Should these three scripts be combined into one main PlayerController.cs file?
  • Is there a way to clean up the keyboard input checking in PlayerMovementController.FixedUpdate while making sure that things such as strafing still work?
  • Is there a way that the camera zooming code can be shortened? It feels unnecessarily long.

PlayerCameraController.cs

using UnityEngine;

namespace DronesAttack
{
    public class PlayerCameraController : MonoBehaviour
    {
        public float HorizontalSensitivity = 3.5f;
        public float VerticalSensitivity = 3.5f;
        public int VerticalInversion = -1;

        private float xRotation = 0.0f;
        private float yRotation = 0.0f;

        public void Start()
        {
            Cursor.lockState = CursorLockMode.Locked;
        }

        public void FixedUpdate()
        {
            this.xRotation += this.VerticalInversion * this.VerticalSensitivity * Input.GetAxis("Mouse Y");
            this.yRotation += this.HorizontalSensitivity * Input.GetAxis("Mouse X");

            this.transform.eulerAngles = new Vector3(this.xRotation, this.yRotation, 0);
        }
    }
}

PlayerMovementController.cs

using UnityEngine;
using System.Collections.Generic;

namespace DronesAttack
{
    public class PlayerMovementController : MonoBehaviour
    {
        public float ForwardMovementSpeed = 0.25f;
        public float SideMovementSpeed = 0.1f;
        public float VerticalMovementSpeed = 0.125f;

        private Dictionary<string, KeyCode> movementKeyBindings = new Dictionary<string, KeyCode>()
        {
            { "FORWARD", KeyCode.W },
            { "BACKWARD", KeyCode.S },
            { "LEFT", KeyCode.A },
            { "RIGHT", KeyCode.D },
            { "UP", KeyCode.Space },
            { "DOWN", KeyCode.LeftShift }
        };

        public void FixedUpdate()
        {
            if(Input.GetKey(this.movementKeyBindings["FORWARD"]))
            {
                this.transform.position += new Vector3(
                    this.transform.forward.x * this.ForwardMovementSpeed, 
                    0, 
                    this.transform.forward.z * this.ForwardMovementSpeed
                );
            }

            if(Input.GetKey(this.movementKeyBindings["BACKWARD"]))
            {
                this.transform.position += new Vector3(
                    this.transform.forward.x * (-this.ForwardMovementSpeed / 1.95f),
                    0,
                    this.transform.forward.z * (-this.ForwardMovementSpeed / 1.95f)
                );
            }

            if(Input.GetKey(this.movementKeyBindings["LEFT"]))
            {
                this.transform.Translate(Vector3.left * this.SideMovementSpeed);
            }

            if(Input.GetKey(this.movementKeyBindings["RIGHT"]))
            {
                this.transform.Translate(Vector3.right * this.SideMovementSpeed);
            }

            if(Input.GetKey(this.movementKeyBindings["UP"]))
            {
                this.transform.Translate(Vector3.up * this.VerticalMovementSpeed);
            }

            if(Input.GetKey(this.movementKeyBindings["DOWN"]))
            {
                this.transform.Translate(Vector3.down * this.VerticalMovementSpeed);
            }
        }
    }
}

PlayerZoomCamera.cs

using UnityEngine;

namespace DronesAttack
{
    public class PlayerZoomCamera : MonoBehaviour
    {
        public float StandardFOV = 62.5f;
        public float ReducedFOV = 32.5f;

        private bool isCameraZoomed = false;
        private int zoomButton = 1;
        private Camera playerCamera;

        public void Start()
        {
            this.playerCamera = GetComponent<Camera>();
        }

        public void Update()
        {
            if(Input.GetMouseButtonDown(this.zoomButton) && !this.isCameraZoomed)
            {
                this.playerCamera.fieldOfView = this.ReducedFOV;
                this.isCameraZoomed = true;
            }
            else if(Input.GetMouseButtonDown(this.zoomButton) && this.isCameraZoomed)
            {
                this.playerCamera.fieldOfView = this.StandardFOV;
                this.isCameraZoomed = false;
            }
        }
    }
}
\$\endgroup\$
  • 2
    \$\begingroup\$ Is there a reason why you force "FORWARD", "BACKWARD", etc to be those specific buttons, rather than doing that thing with the settings, which lets the user choose which buttons do what? (if you understand what I'm trying to say). \$\endgroup\$ – SirPython Mar 14 '16 at 19:29
  • \$\begingroup\$ @SirPython I'm planning on adding a system that allows for changeable settings. I simply have the dictionary there to allow for changeable settings to be implemented. \$\endgroup\$ – Ethan Bierlein Mar 14 '16 at 19:38
2
\$\begingroup\$

Should these three scripts be combined into one main PlayerController.cs file?

It all depends on what you want to do with it, so basically how your project is organised. It could be worth separating input, making a new class handling input and just calling proper functions in other (camera, player) classes.

If you leave it as it is, it seems that PlayerZoomCamera.cs and PlayerCameraController.cs should be merged together.

Is there a way to clean up the keyboard input checking in PlayerMovementController.FixedUpdate while making sure that things such as strafing still work?

If you can't press forward/backward, left/right at the same time you could add some "else if's".

You can clean up every class by:

  • removing this., which is currently placed before variables,
  • removing public from Start() and Update() functions, unless you need to call them from other scripts
  • remove private when declaring variables, as they are private by default

Is there a way that the camera zooming code can be shortened? It feels unnecessarily long.

void Update()
{
    if( Input.GetMouseButtonDown( zoomButton ) )
    {
        isCameraZoomed = !isCameraZoomed;
        playerCamera.fieldOfView = ( isCameraZoomed ? ReducedFOV : StandardFOV );
    }
}

I'd also suggest making some changes in PlayerCameraController.cs

private float xRotation = 0.0f;
private float yRotation = 0.0f;

to

Vector3 newRotation = new Vector3();

then instead of

this.transform.eulerAngles = new Vector3(this.xRotation, this.yRotation, 0);
this.xRotation += this.VerticalInversion * this.VerticalSensitivity * Input.GetAxis("Mouse Y");
this.yRotation += this.HorizontalSensitivity * Input.GetAxis("Mouse X");

you can just write

newRotation.x += VerticalInversion * VerticalSensitivity * Input.GetAxis("Mouse Y");
newRotation.y += HorizontalSensitivity * Input.GetAxis("Mouse X");
transform.eulerAngles = newRotation;

Which is a nice and clean way of changing transform position and rotation.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.