- After following the Unity Networking Tutorial series I came out with problems…
- The problem I need help with is that the host could shoot but also shot for all players, yet the clients could not shoot at all. If the [command] part was removed, all players could shoot locally but their bullets were not spawned on the network.
- So my question is, what would be a correct way to shoot a bullet on a network so that each player can shoot its own bullets and have them spawned for all players?
- After looking around for others who asked the same question a different way and doing research for this, I found that others from YEARS ago also did not get an answer and I was still lost. While doing this I was still looking at my own simple project and making edits here and there until I found a working solution on my own!
- I’ll go ahead and post what worked for me here so others have a chance to find it. I had to put the “if” statement directly in “Update” so that when the “function” was called, it was only called for the localplayer and was not being called every frame unless it found input.
- Post also contains Jumping, Fire Rate, VeryBasicCameraControl and RigidbodyMovement.
My Solution
using UnityEngine;
using UnityEngine.Networking;
public class PlayerController : NetworkBehaviour
{
private KeyCode Forward = KeyCode.W;
private KeyCode Backward = KeyCode.S;
private KeyCode StrafeRight = KeyCode.D;
private KeyCode StrafeLeft = KeyCode.A;
private KeyCode Jump = KeyCode.Space;
private KeyCode Shoot = KeyCode.Mouse0;
public Rigidbody rb;
public GameObject bulletPrefab;
private GameObject mainCamera;
private Vector3 mainCameraOffset = new Vector3(1.5f,2.5f,-5);
public Transform shootTran;
public RectTransform healthBar;
private float speed = 20f;
private float turnSpeed = 100f;
private float jumpingSpeed = 100f;
private float speedMax = 20f;
[SyncVar(hook = "HealthBar")]public float health = 100f;
private float healthMax = 100f;
private bool canJump = false;
private bool canShoot = true;
void Start()
{
if (!isLocalPlayer)
{
return;
}
mainCamera = GameObject.FindWithTag("MainCamera");
mainCamera.transform.parent = gameObject.transform;
mainCamera.transform.position = mainCameraOffset;
}
void Update()
{
if (!isLocalPlayer)
{
return;
}
StatClamp();
GroundCheck();
Move();
Rotate();
DoJump();
if (canShoot == true && Input.GetKey(Shoot))
{
canShoot = false;
CmdDoShoot();
StartCoroutine(cooldownShoot());
}
}
public override void OnStartLocalPlayer()
{
GetComponent<MeshRenderer>().material.color = Color.blue;
}
public void TakeDamage(int amount)
{
if (!isServer)
return;
health -= amount;
if (health <= 0)
{
Debug.Log("Knocked Out!");
}
}
void StatClamp()
{
rb.velocity = Vector3.ClampMagnitude(rb.velocity, speedMax);
Mathf.Clamp(health,0,healthMax);
}
void HealthBar(float health)
{
healthBar.sizeDelta = new Vector2(health, healthBar.sizeDelta.y);
}
void GroundCheck()
{
RaycastHit hit;
if (Physics.Raycast(transform.position,Vector3.down,out hit,2f))
{
//HIT
canJump = true;
}
else
{
//MISS
canJump = false;
}
}
void Move()
{
if (Input.GetKey(Forward))
{
rb.AddForce(transform.forward * speed * Time.deltaTime, ForceMode.Impulse);
}
if (Input.GetKey(Backward))
{
rb.AddForce(transform.forward * -speed * Time.deltaTime, ForceMode.Impulse);
}
if (Input.GetKey(StrafeRight))
{
rb.AddForce(transform.right * speed * Time.deltaTime, ForceMode.Impulse);
}
if (Input.GetKey(StrafeLeft))
{
rb.AddForce(transform.right * -speed * Time.deltaTime, ForceMode.Impulse);
}
}
void Rotate()
{
transform.Rotate(0,turnSpeed * Input.GetAxis("Mouse X") * Time.deltaTime,0);
}
void DoJump()
{
if (canJump == true)
{
if (Input.GetKey(Jump))
{
rb.AddForce(transform.up * jumpingSpeed * Time.deltaTime, ForceMode.Impulse);
}
}
}
[Command]
void CmdDoShoot()
{
var bullet = (GameObject)Instantiate(bulletPrefab,shootTran.position,shootTran.rotation);
bullet.GetComponent<Rigidbody>().velocity = bullet.transform.forward * 300;
Destroy(bullet, 0.3f);
NetworkServer.Spawn(bullet);
}
IEnumerator cooldownShoot()
{
//Fire Rate is 10 Rounds Per Second.
yield return new WaitForSeconds(0.1f);
canShoot = true;
StopCoroutine(cooldownShoot());
}
}
Cheers!