- Home /
Player moves diagonally even when not telling him to
Hello there. I'm working on a simple game, sort of a top-down shooter a la Robotron or Asteroids. I have some code that I adapted from another project where I was following a tutorial series, 3dBuzz's guide on third person movement (stripping out the parts regarding slopes because I won't have any). I'm running Unity3D 4.1.2f1 on Windows 7 SP1 64-bit.
I have an empty game object, named Player, within which I've added a capsule, a camera, and a rectangle to act as the "gun" (but is just a mesh). The camera I've moved to above the player and rotated to face straight down. I've attached a Character Controller to the Player, giving it a capsule collider. I've also attached these three classes, posted below, which provide the movement and such.
What happens is that I can move forward-left, left, backwards-left, and backwards seemingly just fine. Moving foward causes the player to move diagonally forward-left, but not to the same extent as if I was holding both forward and left keys. Forward-right doesn't work at all. Right only works if that's the only key I'm holding down. The other project I got my code from works fine. I've completely deleted and re-done this project with the same code and am getting the same results. Input mappings are still default.
PlayerController.cs
using UnityEngine;
using System.Collections;
/*
* Processing player input
* Motion input (converting into Vector3)
* Initial setup check for camera
* Constant checks for camera existence (if camera doesn't exist, stop working)
*
* Primary Functionality
* - Take in player inputs
* - Create a vector "MoveVector"
* - Forces update() in TP_Motor
*
* Secondary Functionality
* - Housekeeping
* - References:
* Character Controller component
* Instance of this class
* - Initial camera check
* - Continuous camera check (failsafe)
* */
public class PlayerController:MonoBehaviour
{
public static CharacterController CharController; //reference to Character Controller component
public static PlayerController Instance; //instance to self class
public float X_MouseSensitivity = 5.0f;
public float Y_MouseSensitivity = 5.0f;
private float mouseX = 0f;
private float mouseY = 0f;
/*
* Takes place first, for initial setup
* 1. Assign references into static fields
* 2. Performs initial camera check
* */
void Awake()
{
CharController = GetComponent("CharacterController") as CharacterController;
Instance = this;
}//
void Start()
{
mouseX = 0f;
mouseY = 0f;
}//
/*
* Update is called once per frame
* 1. Check to see if main camera still exists, and exits if it doesn't find it (won't take any more input)
* 2. Call GetLocomotionInput(), and get return vector
* 3. Tell TP_Motor to update itself
* */
void Update()
{
if(Camera.mainCamera == null)
{
return;
}
GetLocomotionInput();
PlayerMotor.Instance.UpdateMotor();
}//
/*
* 1. Create variable to store dead space
* 2. Zero-out the move vector
* 3a. Make sure vertical motion is outside dead space. If so, apply vertical axis input to Z-axis of move vector.
* 3b. Make sure horizontal motion is outside dead space. If so, apply horizontal axis input to X-axis of move vector.
*
* */
void GetLocomotionInput()
{
var deadZone = 0.1f;
//get mouse axis input
//mouseX += Input.GetAxis("Mouse X") * X_MouseSensitivity;
//mouseY -= Input.GetAxis("Mouse Y") * Y_MouseSensitivity;
PlayerMotor.Instance.VerticalVelocity = PlayerMotor.Instance.MoveVector.y;
PlayerMotor.Instance.MoveVector = Vector3.zero;
if(Input.GetAxis("Vertical") > deadZone || Input.GetAxis("Vertical") < -deadZone)
{
PlayerMotor.Instance.MoveVector += new Vector3(0, 0, Input.GetAxis("Vertical"));
}
if(Input.GetAxis("Horizontal") > deadZone || Input.GetAxis("Horizontal") < -deadZone)
{
PlayerMotor.Instance.MoveVector += new Vector3(Input.GetAxis("Horizontal"), 0, 0);
}
Debug.Log("Horizontal: "+Input.GetAxis("Horizontal")+", Vertical: "+Input.GetAxis("Vertical"));
Debug.Log("MoveVector x: "+PlayerMotor.Instance.MoveVector.x+", y: "+PlayerMotor.Instance.MoveVector.y+", z: "+PlayerMotor.Instance.MoveVector.z);
PlayerAnimator.Instance.DetermineCurrentMoveDirection();
}//
}
PlayerMotor.cs
using UnityEngine;
using System.Collections;
/*
* Process motion data from TP_Controller into world-space motion
* Character rotation (relative to mouse - mouse's position defines character's rotation)
*
* Primary Functionality
* - Apply MoveVector as world-space motion
* 1. Convert MoveVector to a vector in world space, relative to character rotation
* 2. Normalize vector to between 0 and 1
* 3. Multiply vector by user-set move speed to increase magnitude
* 4. Convert move speed from units per update to units per second using Time.DeltaTime()
* 5. Move the character by the finalized MoveVector
* 6. Apply motion
*
* Secondary Functionality
* - If moving, rotate character to face same direction as the mouse's position
* */
public class PlayerMotor:MonoBehaviour
{
public static PlayerMotor Instance; //instance to self class
public float ForwardSpeed = 10.0f; //multiplier for the normalized vector
public float BackwardSpeed = 2.0f;
public float StrafingSpeed = 5.0f;
public float RollSpeed = 6f; //to add dodge-rolling later
public float Gravity = 21f;
public float TerminalVelocity = 20f;
public Vector3 MoveVector{ get; set; } //vector that is accessed by PlayerController and is processed by PlayerMotor
public float VerticalVelocity{ get; set; }
/*
* Takes place first, for initial setup
* 1. Assign reference for instance
* */
void Awake()
{
Instance = this;
}//
/*
* Called by PlayerController
* 1. Call RotateCharacterToMouse()
* 2. Call ProcessMotion()
* */
public void UpdateMotor()
{
RotateCharacterToMouse();
ProcessMotion();
}//
/*
* Align character towards mouse by modifying character's rotation
* */
void RotateCharacterToMouse()
{
//transform.rotation = Quaternion.Euler(transform.eulerAngles.x, Camera.mainCamera.transform.eulerAngles.y, transform.eulerAngles.z);
}//
float MoveSpeed()
{
var moveSpeed = 0f;
switch(PlayerAnimator.Instance.MoveDirection)
{
case PlayerAnimator.Direction.Stationary:
moveSpeed = 0;
break;
case PlayerAnimator.Direction.Forward:
moveSpeed = ForwardSpeed;
break;
case PlayerAnimator.Direction.Backward:
moveSpeed = BackwardSpeed;
break;
case PlayerAnimator.Direction.Left:
moveSpeed = StrafingSpeed;
break;
case PlayerAnimator.Direction.LeftForward:
moveSpeed = ForwardSpeed;
break;
case PlayerAnimator.Direction.LeftBackward:
moveSpeed = BackwardSpeed;
break;
case PlayerAnimator.Direction.Right:
moveSpeed = StrafingSpeed;
break;
case PlayerAnimator.Direction.RightForward:
moveSpeed = ForwardSpeed;
break;
case PlayerAnimator.Direction.RightBackward:
moveSpeed = BackwardSpeed;
break;
}
/*
* //convert to dodge-rolling
if(slideDirection.magnitude > 0)
{
moveSpeed = SlideSpeed;
}
*/
return moveSpeed;
}//
void ApplyGravity()
{
//Make sure we're not exceeding terminal velocity
if(MoveVector.y > -TerminalVelocity)
{
MoveVector = new Vector3(MoveVector.x, MoveVector.y - Gravity * Time.deltaTime, MoveVector.z);
}
//Check to see if character is grounded
if(PlayerController.CharController.isGrounded && MoveVector.y < -1)
{
MoveVector = new Vector3(MoveVector.x, -1, MoveVector.z);
}
}//
/*
* Calls TransformDirection()
* 1. Converts MoveVector to world-space relative to character's orientation
* 2. Check to see if MoveVector's magnitude > 1, and normalizes if so
* 3. Multiply MoveVector by moveSpeed
* 4. Multiply MoveVector by DeltaTime
* 5. Call a built-in function (Move) to move the character
* */
void ProcessMotion()
{
//Transform MoveVector into world-space relative to character's transformation
MoveVector = transform.TransformDirection(MoveVector);
//Normalize MoveVector if magnitude > 1
if(MoveVector.magnitude > 1)
{
MoveVector = Vector3.Normalize(MoveVector);
}
//Apply dodging if applicable
//ApplyDodge();
//Multiply normalized MoveVector by moveSpeed
MoveVector *= MoveSpeed();
//Reapply vertical velocity to MoveVector.y
MoveVector = new Vector3(MoveVector.x, VerticalVelocity, MoveVector.z);
ApplyGravity();
//Move the character in world-space
PlayerController.CharController.Move(MoveVector * Time.deltaTime);
}//
}
PlayerAnimator.cs - Not really used yet, but is referenced
using UnityEngine;
using System.Collections;
public class PlayerAnimator:MonoBehaviour
{
public static PlayerAnimator Instance;
public enum Direction
{
Stationary, Forward, Backward, Left, Right, LeftForward, LeftBackward, RightForward, RightBackward
}
public Direction MoveDirection{ get; set; } //Property to hold the current Direction state
// Use this for initialization
void Awake()
{
Instance = this;
}//
// Update is called once per frame
void Update()
{
}//
public void DetermineCurrentMoveDirection()
{
var forward = false;
var backward = false;
var left = false;
var right = false;
if(PlayerMotor.Instance.MoveVector.z > 0)
{
forward = true;
}
if(PlayerMotor.Instance.MoveVector.z < 0)
{
backward = true;
}
if(PlayerMotor.Instance.MoveVector.x > 0)
{
right = true;
}
if(PlayerMotor.Instance.MoveVector.x < 0)
{
left = true;
}
if(forward)
{
if(left)
{
MoveDirection = Direction.LeftForward;
Debug.Log("forward/left - MoveDirection: "+MoveDirection+", Direction.LeftForward: "+Direction.LeftForward);
}else if(right){
MoveDirection = Direction.RightForward;
Debug.Log("forward/right - MoveDirection: "+MoveDirection+", Direction.RightForward: "+Direction.RightForward);
}else{
MoveDirection = Direction.Forward;
Debug.Log("forward/none - MoveDirection: "+MoveDirection+", Direction.Forward: "+Direction.Forward);
}
}else if(backward){
if(left)
{
MoveDirection = Direction.LeftBackward;
Debug.Log("backward/left - MoveDirection: "+MoveDirection+", Direction.LeftBackward: "+Direction.LeftBackward);
}else if(right){
MoveDirection = Direction.RightBackward;
Debug.Log("backward/right - MoveDirection: "+MoveDirection+", Direction.RightBackward: "+Direction.RightBackward);
}else{
MoveDirection = Direction.Backward;
Debug.Log("backward/none - MoveDirection: "+MoveDirection+", Direction.Backward: "+Direction.Backward);
}
}else if(left){
MoveDirection = Direction.Left;
Debug.Log("left - MoveDirection: "+MoveDirection+", Direction.Left: "+Direction.Left);
}else if(right){
MoveDirection = Direction.Right;
Debug.Log("right - MoveDirection: "+MoveDirection+", Direction.Right: "+Direction.Right);
}else{
MoveDirection = Direction.Stationary;
Debug.Log("stationary - MoveDirection: "+MoveDirection+", Direction.Stationary: "+Direction.Stationary);
}
}//
}
Finally, here's a screenshot of my game, for some perspective.
Does anyone see what I could be doing wrong? I've looked at other posts about diagonal movement, such as this one about removing diagonal movement, but overall I'm not seeing any differences basic functionality.
Your answer
Follow this Question
Related Questions
Npc Movement 0 Answers
How to get our character controller script to make our player move? 1 Answer
using MoveObject to perform 2 translations at the same time 1 Answer
fixed distance for Vector3.moveTowards ? 1 Answer
3D Character Controller slowing down the higher the slope angle (both up and down) 1 Answer