I’m having serious trouble seeing the problem in my code that is preventing me from moving forward. I have coded this game to have the turrets on the tanks follow the mouse cursor of the player. The server turret faces the proper direction and it is represented on the client just fine. The client turret does calculate the rotation and fires projectiles in the proper direction, but does not rotate the turret transform. This is essentially the last step in my MVP for this prototype and I just can’t see the problem. I need another set of eyes on the code to help me spot where I’m going wrong. Full disclaimer I am creating this project to teach myself UNET so if you spot a problem, or the problem I am having. I would very much appreciate a brief explanation as to what that problem is. Thank you for any help you can provide! I am including all relevant code below, the player class is basically a test-bed class for everything right now, I fully intend to split this class up into pieces once I have found this solution.
![using UnityEngine;
using UnityEngine.Networking;
public enum Direction
{
NORTH,
EAST,
SOUTH,
WEST
}
// TODO: Client Rotation is not displayed on client, but is displayed on server
public class Player : NetworkBehaviour {
// from tutorial //
[SyncVar]
private Quaternion syncTurretRotation;
[SyncVar]
private float SPEED;
// from tutorial //
private bool moveUp = false; // Allow Movement Booleans
private bool moveDown = false;
private bool moveLeft = false;
private bool moveRight = false;
private bool facingNorth = true; // Facing Direction Booleans
private bool facingSouth = false;
private bool facingWest = false;
private bool facingEast = false;
private Direction direction = Direction.NORTH; // Direction of Next Movement
private float movementSpeed; // The speed the player is currently moving
public GameObject projectile; // The Projectile
private float force = 200.0f; // The force applied to the projectile
private Vector3 turretDir; // The direction the barrel is facing right now
const float NORMAL_SPEED = 0.5f;
private GameObject tankBarrel;
// This method only runs on the local player
// it doesn't run on any other instances of the player
// and it doesn't run on the server
public override void OnStartLocalPlayer()
{
base.OnStartLocalPlayer();
}
void Start ()
{
moveUp = false;
moveDown = false;
moveLeft = false;
moveRight = false;
facingNorth = true;
facingSouth = false;
facingWest = false;
facingEast = false;
direction = Direction.NORTH;
movementSpeed = NORMAL_SPEED;
tankBarrel = GameObject.FindGameObjectWithTag("tankTurret");
}
// Reduce Speed of the tank by a percentage of it's normal speed
[Client]
public void DiminishSpeed(float percent)
{
ReturnToNormalSpeed();
CmdSendSpeedData(movementSpeed *= percent);
}
// Increase speed of the tank by a percentage of its normal speed
[Client]
public void IncreaseSpeed(float percent)
{
ReturnToNormalSpeed();
CmdSendSpeedData(movementSpeed += (movementSpeed * percent));
}
// Return the tank to its normal speed
[Client]
public void ReturnToNormalSpeed()
{
movementSpeed = NORMAL_SPEED;
CmdSendSpeedData(movementSpeed);
}
[Command]
void CmdSendSpeedData(float speed)
{
SPEED = speed;
}
// Switch booleans for determining travel direction
private void ResetFacingDirection(Direction direction)
{
// Determine the last direction that
// the player was facing and reset that
// facing direction boolean.
switch (direction)
{
case Direction.NORTH:
facingNorth = false;
break;
case Direction.EAST:
facingEast = false;
break;
case Direction.SOUTH:
facingSouth = false;
break;
case Direction.WEST:
facingWest = false;
break;
default:
break;
}
}
// Rotate the tank in the direction of movement
private void RotateTank(Direction oldDirection, Direction newDirection)
{
// Determine the direction the player
// was last moving in (oldDirection)
// and rotate the tank in the direction
// the player is now moving in.
/*
* If oldDirection was Direction.NORTH
* and newDirection is Direction.EAST
* rotate the tank to the east from the North;
*
*/
switch (oldDirection)
{
case Direction.NORTH:
switch (newDirection)
{
case Direction.EAST:
// rotate to the east
Rotate(Vector3.forward, -90f);
break;
case Direction.SOUTH:
// rotate to the south
Rotate(Vector3.forward, 180f);
break;
case Direction.WEST:
// rotate to the west
Rotate(Vector3.forward, 90f);
break;
default:
break;
}
break;
case Direction.EAST:
switch (newDirection)
{
case Direction.NORTH:
// rotate to the north
Rotate(Vector3.forward, 90f);
break;
case Direction.SOUTH:
// rotate to the south
Rotate(Vector3.forward, -90f);
break;
case Direction.WEST:
// rotate to the west
Rotate(Vector3.forward, 180f);
break;
default:
break;
}
break;
case Direction.SOUTH:
switch (newDirection)
{
case Direction.EAST:
// rotate to the east
Rotate(Vector3.forward, 90f);
break;
case Direction.NORTH:
// rotate to the north
Rotate(Vector3.forward, 180f);
break;
case Direction.WEST:
// rotate to the west
Rotate(Vector3.forward, -90f);
break;
default:
break;
}
break;
case Direction.WEST:
switch (newDirection)
{
case Direction.EAST:
// rotate to the east
Rotate(Vector3.forward, 180f);
break;
case Direction.SOUTH:
// rotate to the south
Rotate(Vector3.forward, 90f);
break;
case Direction.NORTH:
// rotate to the north
Rotate(Vector3.forward, -90f);
break;
default:
break;
}
break;
default:
break;
}
}
// Process the input from the player
private void Processinput()
{
if (Input.GetKeyDown("w"))
{
// The tank should be facing North now
// if it is not
if (direction != Direction.NORTH)
{
// Determine which way to rotate the tank
RotateTank(direction, Direction.NORTH);
// Reset the facing direction booleans
ResetFacingDirection(direction);
// set the direction of next travel to North
direction = Direction.NORTH;
// set the facing direction boolean
facingNorth = true;
// allow the player to move north
moveUp = true;
}
else
{
moveUp = true;
}
}
if (Input.GetKeyDown("a"))
{
if (direction != Direction.WEST)
{
RotateTank(direction, Direction.WEST);
ResetFacingDirection(direction);
direction = Direction.WEST;
facingWest = true;
moveLeft = true;
}
else
{
moveLeft = true;
}
}
if (Input.GetKeyDown("s"))
{
if (direction != Direction.SOUTH)
{
RotateTank(direction, Direction.SOUTH);
ResetFacingDirection(direction);
direction = Direction.SOUTH;
facingSouth = true;
moveDown = true;
}
else
{
moveDown = true;
}
}
if (Input.GetKeyDown("d"))
{
if (direction != Direction.EAST)
{
RotateTank(direction, Direction.EAST);
ResetFacingDirection(direction);
direction = Direction.EAST;
facingEast = true;
moveRight = true;
}
else
{
moveRight = true;
}
}
// if no keys are pressed the tank should stop moving
// set the movement booleans to reflect this
if (Input.GetKeyUp("w"))
{
moveUp = false;
}
if (Input.GetKeyUp("a"))
{
moveLeft = false;
}
if (Input.GetKeyUp("s"))
{
moveDown = false;
}
if (Input.GetKeyUp("d"))
{
moveRight = false;
}
// Mouse Buttons
if (Input.GetMouseButtonDown(0))
{
CmdCreateProjectile();
}
if (Input.GetMouseButtonUp(0))
{
Debug.Log("You No Fire");
}
}
// Get the direction the tank barrel is currently facing
private Vector3 GetBarrelDirection()
{
return turretDir;
}
[Command]
private void CmdSetBarrelDirection(Vector3 dir)
{
turretDir = dir;
}
[Command]
private void CmdCreateProjectile()
{
GameObject clone;
Debug.Log("Fire 1");
clone = Instantiate(projectile, transform.localPosition + (0.4f * GetBarrelDirection()), Quaternion.identity) as GameObject;
clone.GetComponent<Rigidbody2D>().AddForce(GetBarrelDirection() * force);
// Spawn the bullet on the clients
NetworkServer.Spawn(clone);
}
[Client]
private void RotateBarrel()
{
//// Get the position of the transform in screen coordinates
Vector3 pos = Camera.main.WorldToScreenPoint(tankBarrel.transform.position);
//// Get the direction of the mouse from the transform
Vector3 dir = Vector3.Normalize(Input.mousePosition - pos);
CmdSetBarrelDirection(dir);
//// Get the angle
float angle = Mathf.Atan2(GetBarrelDirection().x, GetBarrelDirection().y) * Mathf.Rad2Deg;
angle *= -1;
//// Rotate the transform to face the mouse cursor
//// on this computer
tankBarrel.transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
CmdProvideRotationsToServer(tankBarrel.transform.rotation);
}
[Command]
void CmdProvideRotationsToServer(Quaternion turretRotation)
{
syncTurretRotation = turretRotation;
}
// Move the tank in the given direction
private void Move(Vector3 direction)
{
transform.localPosition += direction;
}
// Rotate the tank using the given rotation and angle
private void Rotate(Vector3 rotation, float angle)
{
transform.Rotate(rotation, angle);
}
void Update ()
{
if (!isLocalPlayer)
{
return;
}
Processinput();
// Move the tank in the direction the player has chosen
if (moveUp && facingNorth)
{
Move(new Vector3(0f, movementSpeed * Time.deltaTime, 0f));
}
else if (moveLeft && facingWest)
{
Move(new Vector3(-movementSpeed * Time.deltaTime, 0f, 0f));
}
else if(moveDown && facingSouth)
{
Move(new Vector3(0f, -movementSpeed * Time.deltaTime, 0f));
}
else if (moveRight && facingEast)
{
Move(new Vector3(movementSpeed * Time.deltaTime, 0f, 0f));
}
RotateBarrel();
}
}][1]