Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

[Updated] Saving Traffic. Movement Bots.PUN

Discussion in 'Assets and Asset Store' started by Kurtav, Apr 27, 2017.

  1. Kurtav

    Kurtav

    Joined:
    May 24, 2015
    Posts:
    93





    An effective synchronization of large PUN bots number movement.

    Document description: What does the message consist of? Packages, commands, limits, message queues.

    Network gameplay with bots example (based on the package SurvivalShooter (UnityEssentials example))
    -----------------------------------------------------------------
    Link to this package - https://www.assetstore.unity3d.com/en/#!/content/86022
     
  2. TooManySugar

    TooManySugar

    Joined:
    Aug 2, 2015
    Posts:
    864
    Awesome!.

    I followed your advice in your WIP page and managed to reduce the traffic of the tanks by removing the turret and barrel rotation values by syncing the target position the turret follows instead. Further, I was sending position and rotation and only reading rotation in these so the traffic reduction has been big. (when I wrote that code I was total newbie).

    Your asset looks pretty awesome if delivers. It is not only interesting for large number of bots but to brutally increasy the smoothness with lesser elements.

    I think your aproach is based in a direction vector plus a magnitude for velocity.

    I'm using photon 1.66 and in there there is already a vector/velocity data interpolation method. How is your package better to that?.
    CubeExtra.cs-
    CubeInter--> I think this is vector direction but does not rotate so I can´t fully compare.
    CubeLerp.cs---> Terribly wrong for some reasong

    I tried available methods and surprisingly none worked better than my actual approach which is an incorrectly lerped script.

    This one I use for the main body:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class NertworkCharacter : Photon.MonoBehaviour {
    5.  
    6.     public bool sync_pos;
    7.     public bool sync_rot;
    8.  
    9.     //Mainbody
    10.     Vector3 realPosition = Vector3.zero;
    11.     Quaternion realRotation = Quaternion.identity;
    12.  
    13.     PhotonView pV;
    14.     public static bool teleporCall;
    15.     bool teleport = true;
    16.  
    17.     void Start () {
    18.         pV= GetComponent<PhotonView>();
    19.         if (pV==null)
    20.         pV= GetComponentInParent<PhotonView>();  
    21.     }
    22.  
    23.     // Update is called once per frame
    24.     void Update () {
    25.         Debug.Log ("teleporCall" +teleporCall);
    26.  
    27.         if (teleporCall==true)      {    teleport=true;       }
    28.  
    29.         if (pV.isMine) {      }
    30.  
    31.         else {
    32.             if(sync_pos ==true)
    33.             transform.position = Vector3.Lerp (transform.position, realPosition, 0.1f);
    34.  
    35.             if(sync_rot ==true)
    36.             transform.rotation = Quaternion.Lerp(transform.rotation, realRotation,0.1f);                  
    37.         }  
    38.     }
    39.  
    40.     public void OnPhotonSerializeView (PhotonStream stream, PhotonMessageInfo info) {
    41.  
    42.         //este es nuestro jugador. Enviamos nuestra posicion a la red.
    43.         if(stream.isWriting){      
    44.             stream.SendNext (transform.position);
    45.             stream.SendNext (transform.rotation);  
    46.         }
    47.  
    48.         //este es un jugador externo. Recivimos su posicion entre otros parametros.
    49.         else
    50.         {
    51.             realPosition = (Vector3) stream.ReceiveNext ();
    52.             realRotation = (Quaternion) stream.ReceiveNext ();
    53.  
    54.                 // la primera vez no hacemos el lerp sino que ponemos el objecto directamnte en real position
    55.                 if(teleport ==true)
    56.                 {
    57.                 transform.position = realPosition;
    58.                 transform.rotation = realRotation;
    59.                 teleporCall=false;
    60.                 teleport=false;
    61.                 }  
    62.         }
    63.     }
    64. }
    So basically, being my game a tank game, which in the end is a vehicle could benefit of your approach to get a super smooth sync considering the total tanks is about 10 in total?
     
  3. Kurtav

    Kurtav

    Joined:
    May 24, 2015
    Posts:
    93
    I want to discuss this topic in detail in the new free package on my account
    I singled out two transmission movements:

    1)This version of the movement conveys a good quick movement. Lerp draws more points in the segment, at greater distances per second, more points of travel are drawn. BUT the average, a small speed of movement, it passes slowly and can be faster because for such distances draw points of positions can be less.

    For smaller distances, it is better to use the second option.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. [RequireComponent(typeof(PhotonView))]
    4. public class SmoothSyncMovement : Photon.MonoBehaviour, IPunObservable
    5. {
    6.     public float SmoothingDelay = 5;
    7.  
    8.     public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    9.     {
    10.         if (stream.isWriting)
    11.         {
    12.             //We own this player: send the others our data
    13.             stream.SendNext(transform.position);
    14.             stream.SendNext(transform.rotation);
    15.         }
    16.         else
    17.         {
    18.             //Network player, receive data
    19.             correctPlayerPos = (Vector3)stream.ReceiveNext();
    20.             correctPlayerRot = (Quaternion)stream.ReceiveNext();
    21.         }
    22.     }
    23.  
    24.     private Vector3 correctPlayerPos = Vector3.zero; //We lerp towards this
    25.     private Quaternion correctPlayerRot = Quaternion.identity; //We lerp towards this
    26.  
    27.     public void Update()
    28.     {
    29.         if (!photonView.isMine)
    30.         {
    31.             //Update remote player (smooth this, this looks good, at the cost of some accuracy)
    32.             transform.position = Vector3.Lerp(transform.position, correctPlayerPos, Time.deltaTime * SmoothingDelay);
    33.             transform.rotation = Quaternion.Lerp(transform.rotation, correctPlayerRot, Time.deltaTime * SmoothingDelay);
    34.         }
    35.     }
    36.  
    37. }
    2) There is a large divisor of Lerp, and therefore small distances are quickly traversed. BUT the points of collision of objects with such movement form holes.
    In the first variant of motion, such objects will collide at closer points to each other.They will later calculate the collision, and therefore will later be removed

    In the second variant, collision and removal (for example, bullets) occur too quickly.The one who looks at it - removal sees too early. Before the collision

    Code (CSharp):
    1. //
    2. // A (very) simple network interpolation script, using Lerp().
    3. //
    4. // This will lag-behind, compared to the moving cube on the controlling client.
    5. // Actually, we deliberately lag behing a bit more, to avoid stops, if updates arrive late.
    6. //
    7. // This script does not hide loss very well and might stop the local cube.
    8. //
    9.  
    10. using UnityEngine;
    11.  
    12. [RequireComponent(typeof (PhotonView))]
    13. public class CubeLerp : Photon.MonoBehaviour, IPunObservable
    14. {
    15.     private Vector3 latestCorrectPos;
    16.     private Vector3 onUpdatePos;
    17.     private float fraction;
    18.  
    19.  
    20.     public void Start()
    21.     {
    22.         latestCorrectPos = transform.position;
    23.         onUpdatePos = transform.position;
    24.     }
    25.  
    26.  
    27.     public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    28.     {
    29.         if (stream.isWriting)
    30.         {
    31.             Vector3 pos = transform.localPosition;
    32.             Quaternion rot = transform.localRotation;
    33.             stream.Serialize(ref pos);
    34.             stream.Serialize(ref rot);
    35.         }
    36.         else
    37.         {
    38.             // Receive latest state information
    39.             Vector3 pos = Vector3.zero;
    40.             Quaternion rot = Quaternion.identity;
    41.  
    42.             stream.Serialize(ref pos);
    43.             stream.Serialize(ref rot);
    44.  
    45.             latestCorrectPos = pos;                // save this to move towards it in FixedUpdate()
    46.             onUpdatePos = transform.localPosition; // we interpolate from here to latestCorrectPos
    47.             fraction = 0;                          // reset the fraction we alreay moved. see Update()
    48.  
    49.             transform.localRotation = rot;              // this sample doesn't smooth rotation
    50.         }
    51.     }
    52.  
    53.  
    54.     public void Update()
    55.     {
    56.         if (photonView.isMine)
    57.         {
    58.             return;     // if this object is under our control, we don't need to apply received position-updates
    59.         }
    60.  
    61.         // We get 10 updates per sec. Sometimes a few less or one or two more, depending on variation of lag.
    62.         // Due to that we want to reach the correct position in a little over 100ms. We get a new update then.
    63.         // This way, we can usually avoid a stop of our interpolated cube movement.
    64.         //
    65.         // Lerp() gets a fraction value between 0 and 1. This is how far we went from A to B.
    66.         //
    67.         // So in 100 ms, we want to move from our previous position to the latest known.
    68.         // Our fraction variable should reach 1 in 100ms, so we should multiply deltaTime by 10.
    69.         // We want it to take a bit longer, so we multiply with 9 instead!
    70.  
    71.         fraction = fraction + Time.deltaTime * 9;
    72.         transform.localPosition = Vector3.Lerp(onUpdatePos, latestCorrectPos, fraction); // set our pos between A and B
    73.     }
    74. }
     
    Last edited: May 7, 2017
  4. Kurtav

    Kurtav

    Joined:
    May 24, 2015
    Posts:
    93
    Update 1.1
    - Added Reduction dictionaries: reduce the network transfer of bots by two times in bytes
    Fixes :
    - Camera
    - Documentation fixes from Tobias(Senior Programmer PUN)


    Reduces twice the method of transmission of bytes of traffic (the movement of bots)
    This technology can also be used if we transfer many vectors to the RPC and Instantiate.
     
  5. Lable

    Lable

    Joined:
    Feb 10, 2013
    Posts:
    1
    Do you intend on Updating this package anytime soon?
     
  6. Kurtav

    Kurtav

    Joined:
    May 24, 2015
    Posts:
    93
    No . Sorry