Search Unity

only host can shoot?

Discussion in 'Scripting' started by PvTGreg, Mar 22, 2017.

  1. PvTGreg

    PvTGreg

    Joined:
    Jan 29, 2014
    Posts:
    365
    Hi im trying to setup 4 directional shooting for my characters in a multiplayer game
    but only the host can shoot?
    where am i going wrong

    Main movement script
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5.  
    6. public class PlayerMovement : NetworkBehaviour {
    7.     public Vector2 speed = new Vector2(1, 1);
    8.     public GameObject Playercamera;
    9.     private Animator anim;
    10.  
    11.     public int Direction;
    12.  
    13.     public override void OnStartLocalPlayer()
    14.     {
    15.         Playercamera.SetActive(true);
    16.         anim = transform.FindChild("Character").GetComponent<Animator>();
    17.     }
    18.     // Update is called once per frame
    19.     void Update () {
    20.         if (!isLocalPlayer)
    21.             return;
    22.         float inputX = Input.GetAxis("Horizontal");
    23.         float inputY = Input.GetAxis("Vertical");
    24.         // Prepare the movement for each direction
    25.         Vector2 movement = new Vector3(speed.x * inputX, speed.y * inputY, 0);
    26.         movement *= Time.deltaTime;// Makes the movement relative to time
    27.         transform.Translate(movement);// Moves the object
    28.         DirectionCheck();
    29.     }
    30.  
    31.      void DirectionCheck()
    32.     {
    33.         float inputX = Input.GetAxis("Horizontal");
    34.         float inputY = Input.GetAxis("Vertical");
    35.         //Taking the input And figuring out what direction were facing
    36.         if (inputX > 0.2 || inputX < -0.2 || inputY > 0.2 || inputY < -0.2)
    37.         {
    38.             anim.SetBool("Walking", true);
    39.             if (inputX > 0)
    40.             {
    41.                 Direction = 1;
    42.                 anim.SetFloat("InputX", 1f);
    43.                 anim.SetFloat("InputY", 0f);
    44.             }
    45.             else if (inputX < 0)
    46.             {
    47.                 Direction = 2;
    48.                 anim.SetFloat("InputX", -1f);
    49.                 anim.SetFloat("InputY", 0f);
    50.             }
    51.             else if (inputY > 0)
    52.             {
    53.                 Direction = 3;
    54.                 anim.SetFloat("InputY", 1f);
    55.                 anim.SetFloat("InputX", 0f);
    56.             }
    57.             else if (inputY < 0)
    58.             {
    59.                 Direction = 4;
    60.                 anim.SetFloat("InputY", -1f);
    61.                 anim.SetFloat("InputX", 0f);
    62.             }
    63.         }
    64.         else
    65.         {
    66.             anim.SetBool("Walking", false);
    67.         }
    68.     }
    69.  
    70. }
    71.  


    and this is how im doing the shooting
    it appears the direction variable i have does not seem to send or do anything on players other than the host

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5.  
    6. public class Shoot : NetworkBehaviour
    7. {
    8.     public GameObject bulletPrefab;
    9.     public GameObject ProjectileSpawnPointT;
    10.     public GameObject ProjectileSpawnPointB;
    11.     public GameObject ProjectileSpawnPointL;
    12.     public GameObject ProjectileSpawnPointR;
    13.  
    14.     public PlayerMovement pm;
    15.     // Use this for initialization
    16.     void Start () {
    17.        
    18.     }
    19.     public override void OnStartLocalPlayer()
    20.     {
    21.         //pm = GetComponent<PlayerMovement>();
    22.     }
    23.     // Update is called once per frame
    24.     void Update () {
    25.         if (!isLocalPlayer){
    26.             return;
    27.         }
    28.         if (Input.GetKeyDown(KeyCode.Space))
    29.         {
    30.             CmdFire();
    31.         }
    32.     }
    33.     [Command]
    34.     void CmdFire()
    35.     {
    36.         if(pm.Direction == 1)
    37.         {
    38.             var pos = ProjectileSpawnPointR.transform.position;
    39.             var bullet = (GameObject)Instantiate(bulletPrefab, pos, Quaternion.identity);
    40.             bullet.GetComponent<Rigidbody2D>().AddForce(transform.right * 200);
    41.             NetworkServer.Spawn(bullet);
    42.             Destroy(bullet, 2.0f);
    43.         }
    44.         else if (pm.Direction == 2)
    45.         {
    46.             var pos = ProjectileSpawnPointL.transform.position;
    47.             var bullet = (GameObject)Instantiate(bulletPrefab, pos, Quaternion.identity);
    48.             bullet.GetComponent<Rigidbody2D>().AddForce(-transform.right * 200);
    49.             NetworkServer.Spawn(bullet);
    50.             Destroy(bullet, 2.0f);
    51.         }
    52.         else if (pm.Direction == 3)
    53.         {
    54.             var pos = ProjectileSpawnPointT.transform.position;
    55.             var bullet = (GameObject)Instantiate(bulletPrefab, pos, Quaternion.identity);
    56.             bullet.GetComponent<Rigidbody2D>().AddForce(transform.up * 200);
    57.             NetworkServer.Spawn(bullet);
    58.             Destroy(bullet, 2.0f);
    59.         }
    60.         else if (pm.Direction == 4)
    61.         {
    62.             var pos = ProjectileSpawnPointB.transform.position;
    63.             var bullet = (GameObject)Instantiate(bulletPrefab, pos, Quaternion.identity);
    64.             bullet.GetComponent<Rigidbody2D>().AddForce(-transform.up * 200);
    65.             NetworkServer.Spawn(bullet);
    66.             Destroy(bullet, 2.0f);
    67.         }
    68.     }
    69. }
    70.  
     
  2. PvTGreg

    PvTGreg

    Joined:
    Jan 29, 2014
    Posts:
    365
    anyone got any idea?
     
  3. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    Is the 'Shoot' script attached to the player? In my experience, Cmd only works properly when sent from the player object
     
  4. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Commands are called on the host's instance of the GameObject. So you have to pass the direction to the command if it's not synchronized in any way. (Basically, when a client does this it's just using the default value of 0 so nothing happens).
     
  5. PvTGreg

    PvTGreg

    Joined:
    Jan 29, 2014
    Posts:
    365
    is that not what im doing with the
    if(pm.Direction == 1)

    or do i have to instead set a variable in the shoot script when i change direction instead of having other scripts access the player movment
     
  6. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    You're only doing that on the client instance of the script. The host has no idea what value the client is setting it to because it isn't synchronized.

    Try it - debug the value of Direction in both the Command and Update :)
     
  7. PvTGreg

    PvTGreg

    Joined:
    Jan 29, 2014
    Posts:
    365
    I have updated my shoot script to allow me to shoot in any direction. but still on ebverything but the host the actual bullet willl always only go one direction

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5.  
    6. public class Shoot : NetworkBehaviour
    7. {
    8.     public GameObject bulletPrefab;
    9.     public GameObject ProjectileSpawnPointBase;
    10.     public GameObject ProjectileSpawnPoint;
    11.  
    12.     // Use this for initialization
    13.     void Start () {
    14.        
    15.     }
    16.     public override void OnStartLocalPlayer()
    17.     {
    18.      
    19.     }
    20.     void FixedUpdate()
    21.     {
    22.         if (!isLocalPlayer)
    23.         {
    24.             return;
    25.         }
    26.         Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    27.         ProjectileSpawnPointBase.transform.rotation = Quaternion.LookRotation(Vector3.forward, mousePos - transform.position);
    28.     }
    29.     // Update is called once per frame
    30.     void Update () {
    31.         if (!isLocalPlayer){
    32.             return;
    33.         }
    34.         if (Input.GetKeyDown(KeyCode.Space))
    35.         {
    36.             CmdFire();
    37.         }
    38.     }
    39.     [Command]
    40.     void CmdFire()
    41.     {
    42.           var pos = ProjectileSpawnPoint.transform.position;
    43.           var bullet = (GameObject)Instantiate(bulletPrefab, pos, Quaternion.identity);
    44.           bullet.GetComponent<Rigidbody2D>().AddRelativeForce(ProjectileSpawnPoint.transform.up * 200);
    45.           NetworkServer.Spawn(bullet);
    46.           Destroy(bullet, 2.0f);
    47.     }
    48. }
    49.  
     
  8. PvTGreg

    PvTGreg

    Joined:
    Jan 29, 2014
    Posts:
    365
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5.  
    6. public class Shoot : NetworkBehaviour
    7. {
    8.     public GameObject bulletPrefab;
    9.     public GameObject ProjectileSpawnPointBase;
    10.     public GameObject ProjectileSpawnPoint;
    11.  
    12.     // Use this for initialization
    13.     void Start () {
    14.        
    15.     }
    16.     public override void OnStartLocalPlayer()
    17.     {
    18.      
    19.     }
    20.     void FixedUpdate()
    21.     {
    22.      
    23.     }
    24.     // Update is called once per frame
    25.     void Update () {
    26.         if (!isLocalPlayer){
    27.             return;
    28.         }
    29.         if (Input.GetKeyDown(KeyCode.Space))
    30.         {
    31.             Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    32.             ProjectileSpawnPointBase.transform.rotation = Quaternion.LookRotation(Vector3.forward, mousePos - transform.position);
    33.             CmdFire(ProjectileSpawnPoint);
    34.         }
    35.     }
    36.     [Command]
    37.     void CmdFire(GameObject spawnpoint)
    38.     {
    39.         var pos = spawnpoint.transform.position;
    40.         var bullet = (GameObject)Instantiate(bulletPrefab, pos, Quaternion.identity);
    41.         bullet.GetComponent<Rigidbody2D>().AddRelativeForce(spawnpoint.transform.up * 200);
    42.         NetworkServer.Spawn(bullet);
    43.         Destroy(bullet, 2.0f);
    44.     }
    45. }
    46.  


    ok so im now passing in the values to it but now i get this error

    NetworkWriter ProjectilePoint (UnityEngine.GameObject) has no NetworkIdentity
    UnityEngine.Networking.NetworkWriter:Write(GameObject)
    Shoot:CallCmdFire(GameObject)
    Shoot:Update() (at Assets/Scripts/Shoot.cs:33)
     
  9. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    You can't pass non-networked GameObjects around in Commands and RPCs. If all you need is the position, pass a Vector3 instead.
     
  10. PvTGreg

    PvTGreg

    Joined:
    Jan 29, 2014
    Posts:
    365
    i had tried that. but how do i then pass the correct rotation?
     
  11. PvTGreg

    PvTGreg

    Joined:
    Jan 29, 2014
    Posts:
    365
    how would i then get the equivilent to spawnpoint.transform.up
     
  12. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    What about sending 2 Vector3s ? :) 1 for position & 1 for rotation (if you need the rotation, too). :)
     
  13. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    It's just a vector. Pass it to the command as an argument
    Code (csharp):
    1.  
    2. CmdFire(spawnpoint.transform.up);
    3.  
    4. [Command]
    5. void CmdFire(Vector3 spawnPoint)
    6. {
    7.  
    8. }
    9.  
    Why send a Vector3 for rotation when you can send a Quaternion?

    Edit: re-reading everything again. Send two arguments in your Command. One for the position and one for the rotation. Use the transform values from the local player when you're checking input.
     
  14. PvTGreg

    PvTGreg

    Joined:
    Jan 29, 2014
    Posts:
    365
    thankyou ve
    thankyou very much. learnt alot from this.
     
    KelsoMRK likes this.