So I tried adding physical projectiles/bullets with speed and gravity to a simple first person shooter instead of just Raycasting and and using a Command if the client hits something. After a bit of trial and error I figured out that using a projectile with a collider isn't the best way of doing things as the physics aren't calculated fast enough for fast moving objects. So I mad my own bullet physics as shown below.
private float startingVelocity = 50f;
private float gravity = 9.81f;
private Vector3 forwardDirection;
private Vector3 previousPosition;
private Vector3 nextPosition;
private Vector3 movementDirection;
private Vector3 velocity;
void Start ()
{
previousPosition = transform.position;
forwardDirection = transform.forward.normalized;
velocity = forwardDirection*startingVelocity;
}
void Update ()
{
previousPosition = transform.position;
velocity += new Vector3(0f, -1f, 0f)*gravity*Time.deltaTime;
nextPosition = previousPosition + velocity*Time.deltaTime;
transform.position = nextPosition;
Debug.DrawLine(previousPosition, nextPosition, Color.white, 10f);
movementDirection = nextPosition - previousPosition;
if (movementDirection!=Vector3.zero)
{
transform.rotation = Quaternion.LookRotation(movementDirection);
}
CheckImpact(previousPosition, nextPosition);
}
The CheckImpact function essentially just raycasts between the two positions to check if there is a wall or player in the way the projectile should hit. When hitting something, a Command is called and damage is done to the target by the server.
The bullet itself is spawned like this:
[Command]
void CmdShootProjectile(string projectilePath, Vector3 _position, Quaternion _rotation)
{
GameObject projectile = Instantiate(Resources.Load<GameObject>(projectilePath), _position, _rotation);
NetworkServer.Spawn(projectile);
The Client shoots, a Command spawns the bullet on the server and the bullet is then spawned for every client so it can be seen. The problem I am having with this method is that the server calculates whether or not a bullet hits and this doesn't always line up with how it looks like for the player.
How could I efficiently and reliably handle my projectiles? Could I somehow make the client who is actually shooting do the calculating of the bullet and checking if it hits while other clients still being able to see the bullet?
Thanks in advance.
Unfortunately, it's virtually impossible to have a 100% safe and reliable way of doing this. There is, however, quite a bit of research into this (by game companies such as Valve - for Counter Strike - and others).
The current consensus is to indeed have the calculations in the server-side, not on client-side. There pros and cons.
Pros:
Cons:
Personally, I like your approach, and it should be fine for now. As your game progresses, and the need comes for a better system, then you can change it.