Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Third Party Simulating Rigidbody2D Addforce with Photon PUN 2

Discussion in 'Multiplayer' started by Mikaeloo, Mar 6, 2023.

  1. Mikaeloo

    Mikaeloo

    Joined:
    Apr 5, 2020
    Posts:
    1
    Hello everyone,

    I've been creating a prototype of a game using ragdolls that are based on the physics of Unity. Here's my movement script (please note that I'm not a dev at all)

    Code (CSharp):
    1.   void Start()
    2.     {
    3.         anim = gameObject.GetComponent<Animator>();
    4.         view = GetComponent<PhotonView>();
    5.     }
    6.  
    7.     void Update()
    8.     {
    9.         if (view.IsMine)
    10.         {
    11.             // GroundCheck
    12.             isOnGround = Physics2D.OverlapCircle(playerPosition.position, positionRadius, ground);
    13.  
    14.             //Jump
    15.             if (Input.GetKeyDown(KeyCode.Space) && isOnGround == true)
    16.             {
    17.                 isOnGround = false;
    18.                 playerRb[2].AddForce(new Vector2(-.1f, 1) * jumpForce * 1000 * Time.fixedDeltaTime);
    19.             }
    20.  
    21.             //Shoot Balance
    22.             if (Input.GetKey(KeyCode.Space) == true)
    23.             {
    24.                 isShooting = true;
    25.                 playerRb[0].MoveRotation(Mathf.LerpAngle(playerRb[0].rotation, bodyTargetRotation, normalForce * Time.fixedDeltaTime));
    26.                 playerRb[1].MoveRotation(Mathf.LerpAngle(playerRb[1].rotation, normalTargetRotation, normalForce * Time.fixedDeltaTime));
    27.                 playerRb[2].MoveRotation(Mathf.LerpAngle(playerRb[2].rotation, bodyTargetRotation, shootForce * Time.fixedDeltaTime));
    28.                 playerRb[3].MoveRotation(Mathf.LerpAngle(playerRb[3].rotation, shootTargetRotation, shootForce * Time.fixedDeltaTime));
    29.             }
    30.  
    31.             //Normal Balance
    32.             else
    33.             {
    34.                 isShooting = false;
    35.                 playerRb[0].MoveRotation(Mathf.LerpAngle(playerRb[0].rotation, normalTargetRotation, normalForce * Time.fixedDeltaTime));
    36.                 playerRb[1].MoveRotation(Mathf.LerpAngle(playerRb[1].rotation, walkRightTargetRotation, 25 * Time.fixedDeltaTime));
    37.                 playerRb[2].MoveRotation(Mathf.LerpAngle(playerRb[2].rotation, normalTargetRotation, normalForce * Time.fixedDeltaTime));
    38.                 playerRb[3].MoveRotation(Mathf.LerpAngle(playerRb[3].rotation, walkLeftTargetRotation, 25 * Time.fixedDeltaTime));
    39.             }
    40.  
    41.             //Horizontal Movement
    42.             if (Input.GetAxis("Horizontal") != 0 && isShooting == false)
    43.             {
    44.                 if (Input.GetAxis("Horizontal") > 0)
    45.                 {
    46.                     bodyTargetRotation = 30;
    47.                     shootTargetRotation = 120;
    48.                     normalTargetRotation = 10;
    49.                     globalTransform.localScale = new Vector3(-1, 1, 1);
    50.                     anim.Play("WalkRight");
    51.                     playerRb[2].AddForce(Vector2.right * speed * 10 * Time.fixedDeltaTime);
    52.                 }
    53.                 if (Input.GetAxis("Horizontal") < 0)
    54.                 {
    55.                     bodyTargetRotation = -30;
    56.                     shootTargetRotation = -120;
    57.                     normalTargetRotation = -10;
    58.                     globalTransform.localScale = new Vector3(1, 1, 1);
    59.                     anim.Play("WalkLeft");
    60.                     playerRb[2].AddForce(Vector2.left * speed * 10 * Time.fixedDeltaTime);
    61.                 }
    62.             }
    63.             else
    64.             {
    65.                 normalTargetRotation = 0;
    66.                 anim.Play("playeranimator");
    67.             }
    68.         }
    69.     }
    The thing is that I wanted to make this multiplayer, so I started to look up some tutorials and eventually find Photon PUN 2 for easy multiplayer setup, I try it out and it worked great for the most part. I can connect to a room and join another player, BUT there is a problem with my player movement script.

    The balance script doesn't seem to be synchronized and the other player on both screen will always be a full ragdoll with no balance whatsoever. The position is still synchronized on both players so you can see the ragdoll kind of moving itself but there is no animation nor real interesting physics.

    Player 1 view :
    upload_2023-3-6_10-7-50.png


    Player 2 view :
    upload_2023-3-6_10-8-33.png

    I am using Photon Rigibody 2D View on my player prefab, I tried to used Photon Transform Classic View before but it wasn't working well at all...

    Does anyone have some kind of solution about this ? :(
     
  2. tobiass

    tobiass

    Joined:
    Apr 7, 2009
    Posts:
    3,062
    The PhotonRigibody2DView is good to sync rigidbodies. It syncs position, velocity and such to approximate where remote players are and go. However, the physical simulation is only done on the controller of the rigidbody and everyone else shows the remote players with IsKinematic.
    I guess, this causes the issues here.

    Networked games must deal with lag. Even if you send updates 60x per second any input will take some time to arrive on the other's clients. The physics worlds of all clients will differ and if movement and input arrives late, you can not integrate that well into the other's physical world.
    This makes using ragdolls for gameplay really challenging. Remote players are never up to date within the local physics world which would move the character immediately (not with a delay).

    PUN is not a good basis for this as it has a low update frequency and does not take care of the physics simulation either.
    Fusion might be a better base. It would sync your input and the server / host simulates the world. That state is sent to everyone (and clients basically just have to agree to what they got).