Reducing appearance of lag in location sensitive game

I've been stumped on this one for a little while. I'm making a top-down game that for this discussion you can just think of it as a bullet hell type game (with fewer bullets).

I've got random room joining working and everything (very) basic appears to be functional (ie: shooting, moving and rotation). However, when one player quickly rotates and shoots during the rotation the shot can go in wildly different directions for each player. I mean, as much as a 60 degree difference in shot direction.

I started with a player prefab using an empty game object in front to instantiate shots from. This works wonderfully, except that (from what I can guess) when Player 1 shoots he shoots, for Player 2, where ever his ship is oriented on Player 2s screen, rather than where he is shooting from on his screen. I do have the ship movement set to "unreliable". Setting this to reliable and compressed reduces the error amount for shooting, but makes the movement considerably less fluid. By and large I've mostly copied the tutorials letter for letter for player movement.

I thought this was a problem with Lerping the rotation, but even after removing the lerp it kind of did its own thing.


While writing this out I had the idea to manually try to update the location (immediately before creating the shot) but that seemed fruitless as well. How have other people gone about doing similar things?

firing the bullet
[code2=csharp][RPC]
private void Fire1(float speed, float damage)
{
netChar.correctPlayerRot = transform.rotation;
GameObject normalShot = Instantiate(bullPref, startSpot.transform.position, Quaternion.identity) as GameObject;
normalShot.GetComponent<Bullet>().speed = (startSpot.transform.forward * speed) + (startSpot.transform.forward*currVel*3);
normalShot.GetComponent<Bullet>().on = true;
normalShot.GetComponent<Bullet>().damage = damage;
normalShot.GetComponent<Bullet>().owner = photonID;

}[/code2]

Photonview for movement
[code2=csharp]if(!photonView.isMine)
{
transform.position = Vector3.Lerp (transform.position, this.correctPlayerPos, Time.deltaTime*20);
transform.rotation = Quaternion.Lerp (transform.rotation, this.correctPlayerRot, Time.deltaTime*20);

}[/code2]

Comments

  • I juste interpolate the position of the current player and doing my hit test according to this.
    That's not authorative, but as Photon can't reproduice player's position on the server side, the choices are limited : https://developer.valvesoftware.com/wik ... mpensation

    Lag_compensation.jpg
  • I think my problem may have been misunderstood. My problem isn't with shooting at anything specific, or even hitting anything (That's not even implemented).

    Right now I have each client instantiate each shot locally (this isn't a raycast, it's actually a sphere to be avoided) and from there I hope to have all the logic done client side. However, when the local player shoots every one else in the room has a different destination for the shot. This only happens when I'm rotating the ship and shoot quickly during the rotation--the remote players don't seem to have the same location as the local player so they locally instantiate the shot in the wrong position.
  • So you make some interpolation of the rotation (let's say about 100ms back in time) like in this exemple : http://wiki.unity3d.com/index.php/Netwo ... ition_Sync but when you have a quick rotation, you are not satisfied by the result.

    Did you manage the rotation with the appropriate lerping ?
    http://docs.unity3d.com/Documentation/S ... Angle.html
    http://docs.unity3d.com/Documentation/S ... .Lerp.html

    Did you clamp correctly your rotation ?
    [code2=csharp]if (angle < -360)
    angle += 360;
    if (angle > 360)
    angle -= 360;[/code2]

    Your game is fast enough to handle quick rotation (ie your FPS > PhotonNetwork.sendRateOnSerialize -default to 10-) ?

    Did you reproduce your interpolation on the shot as well (ie don't shot prior 100ms back in time) ?
  • For perfect synchronized shots, simply add a float to your Fire RPC that represents the angle at which the shot was fired.