HLAPI simple 2 player game

So I’m making a simple 2 player game following this guide: https://docs.unity3d.com/Manual/UNetSetup.html but instead of 3d shooting game I’m making 2d top-down game.

One of players is on the bottom of the screen and shoots up and the second player is on top of the screen and should shoot down. However I can’t figure out how do I make the second player shoot down. I tried to check if player is not a server and apply negative speed to its bullets but it doesn’t seem to work.

There’s a picture of what I’m working on for better understanding:
alt text

Here is my code:

Script attached to player - PlayerScript.cs:

using UnityEngine;
using UnityEngine.Networking;

public class PlayerScript : NetworkBehaviour {
    public float speed = 5.0f;
    public GameObject projectilePrefab;
    public int rpm = 120;

    private float lastTimeFired = 0;
    private float timeBtwnShots;

	void Start () {
        timeBtwnShots = 60.0f / rpm;
	}

    public override void OnStartLocalPlayer() {
        GetComponent<SpriteRenderer>().color = Color.black;
        if (isServer) transform.Translate(new Vector2(0, -3));
        else {
            transform.Translate(new Vector2(0, 3));
            transform.RotateAround(transform.position, Vector3.back, 180);
        }
    }

    void Update () {
        if (!isLocalPlayer) return;

	    if(Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
            gameObject.transform.Translate(new Vector2(-speed * Time.deltaTime, 0));
        else if(Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
            gameObject.transform.Translate(new Vector2(speed * Time.deltaTime, 0));

        if(Input.GetKey(KeyCode.Space)) {
            CmdFire();
        }
    }

    [Command]
    void CmdFire() {
        if (Time.time - lastTimeFired > timeBtwnShots) {
            GameObject g = Instantiate(projectilePrefab, transform.position + new Vector3(0, 0.5f, 0), Quaternion.identity) as GameObject;
            g.transform.parent = gameObject.transform;
            lastTimeFired = Time.time;
            NetworkServer.Spawn(g);
            Destroy(g, 3.0f);
        }
    }
}

Script attached to fired projectiles - ProjectileScript.cs:

using UnityEngine;

public class ProjectileScript : MonoBehaviour {
    public float speed = 5.0f;
	
    void Start() {
        if (transform.parent.gameObject.GetComponent<PlayerScript>().isServer == false)
            speed *= -1;
    }

    void Update () {
        transform.Translate(new Vector2(0, 1) * speed * Time.deltaTime);
	}
}

I want client to shoot down. I thought this line in ProjectileScript.cs would make it:
if (transform.parent.gameObject.GetComponent<PlayerScript>().isServer == false) speed *= -1;, but it doesn’t work.

BTW I’ve noticed a strange thing with g.transform.parent = gameObject.transform; line: sometimes it just doesn’t work… Projectiles spawn without parent in objects hierarchy.

Ok, so After reading on the Unity manual I noticed what I was doing wrong. Now my project looks like that:

  • My NetworkManager game object has custom Network Manager Script:

    using UnityEngine;
    

    using UnityEngine.Networking;

    public class CustomNetworkMgr : NetworkManager {
    public Vector3 positionUpper;
    public Vector3 positionLower;

     public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId) {
         Vector3 position;
         Quaternion rotation;
         if (numPlayers == 0) {
             position = positionLower;
             rotation = Quaternion.identity;
         } else {
             position = positionUpper;
             rotation = Quaternion.Euler(0, 0, 180);
         }
         GameObject player = (GameObject)Instantiate(playerPrefab, position, rotation);
         NetworkServer.AddPlayerForConnection(conn, player, playerControllerId);
     }
    

    }

As you can see I’m assigning players positions in OnServerAddPlayer.

  • PlayerScript changes include:

    • adding [SyncVar] private bool shootDown = false;

    • changing OnStartLocalPlayer to just:

      public override void OnStartLocalPlayer() {
      GetComponent().color = Color.black;
      }

    • In CmdFire after instantiating player object: if(shootDown) g.GetComponent<ProjectileScript>().speed *= -1;

  • In ProjectileScript I made speed variable a [SyncVar]

That’s it! Now players shoot projectiles as intended.
Gif showing how it’s working now