1
\$\begingroup\$

Setting : Creating my first multiplayer game and running into an odd issue. it's a tank game where players can shoot bullets and kill each other

Problem : When the client shoots while moving, the bullet seems to spawn with a little delay which causes the the player to collide with the bullet.

The issue seems to be that the player itself is local and the bullet is being spawned on the network ( which is causing the delay)

Note: The host player does not have this problem, therefore it's somehow related to networking.

How can I sync the bullet with the client player?

private void Fire(){
    // Set the fired flag so only Fire is only called once.
    m_Fired = true;
    CmdCreateBullets ();
    // Change the clip to the firing clip and play it.
    m_ShootingAudio.clip = m_FireClip;
    m_ShootingAudio.Play ();
    // Reset the launch force.  This is a precaution in case of missing button events.
    m_CurrentLaunchForce = m_MinLaunchForce;
}

[Command]
private void CmdCreateBullets()
{

    GameObject shellInstance = (GameObject)
        Instantiate (m_Shell, m_FireTransform.position, m_FireTransform.rotation) ;
    // Set the shell's velocity to the launch force in the fire position's forward direction.
    shellInstance.GetComponent<Rigidbody>().velocity = m_CurrentLaunchForce * m_FireTransform.forward; 

    NetworkServer.Spawn (shellInstance);

}
\$\endgroup\$
0
\$\begingroup\$

I solved it the following way. if someone can look over to confirm my answer, it would be nice.

private void Fire(){
    // Set the fired flag so only Fire is only called once.
    m_Fired = true;
    CmdCreateBullets ();
    // Change the clip to the firing clip and play it.
    m_ShootingAudio.clip = m_FireClip;
    m_ShootingAudio.Play ();
    // Reset the launch force.  This is a precaution in case of missing button events.
    m_CurrentLaunchForce = m_MinLaunchForce;
}

[Command]
private void CmdCreateBullets()
{
    RpclocalBullet ();
}

[ClientRpc]
private void RpclocalBullet(){
    GameObject shellInstance = (GameObject)
        Instantiate (m_Shell, m_FireTransform.position, m_FireTransform.rotation) ;
    // Set the shell's velocity to the launch force in the fire position's forward direction.
    shellInstance.GetComponent<Rigidbody>().velocity = 25f * m_FireTransform.forward; 
}
\$\endgroup\$
2
\$\begingroup\$

Syncing physics simulations can be complex. Where are you doing the collision test? On the server? On both clients? On only the client who shot the bullet? If the collision test is on the client, look at Collision Layers: http://docs.unity3d.com/Manual/LayerBasedCollision.html This would allow you to place the local player on a different layer to remote opponents, so it could not collide with the bullet.

Alternatively look at triggers with a custom validity check: http://docs.unity3d.com/ScriptReference/Collider.OnTriggerEnter.html So when a bullet hit a tank it would be able to check to see if it had hit a valid target. Note that triggers don't act like rigid bodies in the scene, so they would go right trough a tank if they did not decide they were hitting something valid.

Regarding syncing the physics itself, it is usually achieved by having a single authoritative simulation, and doing periodic (ie not every frame) updates that synchronize the local client simulations to the remote one. This can be either client to client (you decide which client is authoritative, and sync the others to that one) or sever to client (there is a single authoritative simulation on the server and all the clients sync to it.) In either case, the local simulation continues on its own between syncs. That is why you see things jumping around in laggy online games, because the local simulation has gotten too far out of sync with the authoritative simulation and the update is noticeably different.

Hope that gives you some ideas.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.