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

Third Party Photon - Players go through each other

Discussion in 'Multiplayer' started by Kozaki2, Feb 5, 2020.

  1. Kozaki2

    Kozaki2

    Joined:
    Apr 8, 2019
    Posts:
    47
    Hi, players in my game have Character Controller component attached. I am using OnCotrollerColliderHit to detect collision and it works well only if one of the players is not moving - then collision is detected correctly, but when two players are moving then they go pass through each other.
    I think there might be a problem with position synchronization but I don't know what I can do.
    Code (CSharp):
    1. public class PlayerController : MonoBehaviour, IPunObservable
    2. {
    3.     public float speed = 5;
    4.    
    5.     private VariableJoystick variableJoystick;
    6.  
    7.     private CharacterController characterController;
    8.  
    9.     private Vector3 _networkPosition;
    10.  
    11.     private Quaternion _networkRotation;
    12.  
    13.     private Vector3 _movement;
    14.  
    15.     private PhotonView photonView;
    16.  
    17.     private float vSpeed = 0;
    18.    
    19.     private float gravity = 9.8f;
    20.  
    21.     public void Awake()
    22.     {
    23.         photonView = GetComponent<PhotonView>();
    24.         characterController = GetComponent<CharacterController>();
    25.         variableJoystick = FindObjectOfType<VariableJoystick>();
    26.     }
    27.  
    28.     public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    29.     {
    30.         if (stream.IsWriting)
    31.         {
    32.             stream.SendNext(transform.position);
    33.             stream.SendNext(transform.rotation);
    34.         }
    35.         else
    36.         {
    37.             _networkPosition = (Vector3) stream.ReceiveNext();
    38.             _networkRotation = (Quaternion) stream.ReceiveNext();
    39.  
    40.             float lag = Mathf.Abs((float) (PhotonNetwork.Time - info.SentServerTime));
    41.             _networkPosition += (_movement * lag);
    42.         }
    43.     }
    44.  
    45.     public void Update()
    46.     {
    47.         if (!photonView.IsMine)
    48.         {
    49.             transform.position = Vector3.MoveTowards(transform.position, _networkPosition, Time.deltaTime * speed);
    50.             transform.rotation = Quaternion.RotateTowards(transform.rotation, _networkRotation, Time.deltaTime * 100);
    51.             return;
    52.         }
    53.        
    54.         SetRotation();
    55.         SetMovement();
    56.     }
    57.  
    58.     [PunRPC]
    59.     public void AddBounceForce(Vector3 pushDir)
    60.     {
    61.         characterController.SimpleMove(pushDir * 10.0f);
    62.     }
    63.  
    64.     public void OnControllerColliderHit(ControllerColliderHit hit)
    65.     {
    66.         if (!photonView.IsMine)
    67.         {
    68.             return;
    69.         }
    70.        
    71.         if (hit.gameObject.CompareTag("Player"))
    72.         {
    73.             Vector3 pushDir = new Vector3(hit.moveDirection.x, 0, hit.moveDirection.z);
    74.             PhotonView otherPhotonView = hit.gameObject.GetComponent<PhotonView>();
    75.             otherPhotonView.RPC("AddBounceForce", otherPhotonView.Owner, pushDir);
    76.         }
    77.     }
    78.     private void SetRotation()
    79.     {
    80.         if (variableJoystick.Horizontal != 0) {
    81.             transform.Rotate(new Vector3(0.0f, variableJoystick.Horizontal, 0.0f));
    82.         }
    83.     }
    84.  
    85.     private void SetMovement()
    86.     {
    87.         Vector3 oldPosition = transform.position;
    88.         if (characterController.isGrounded) {
    89.             vSpeed = 0;
    90.         }
    91.  
    92.         Vector3 direction = transform.forward * variableJoystick.Vertical;
    93.         direction *= speed;
    94.         vSpeed -= gravity * Time.deltaTime;
    95.         direction.y = vSpeed;
    96.        
    97.         characterController.Move(direction * Time.deltaTime);
    98.  
    99.         _movement = transform.position - oldPosition;
    100.     }
    101. }
     
  2. voncarp

    voncarp

    Joined:
    Jan 3, 2012
    Posts:
    187
    I would check the layers of of the local player and all the client players. If they are on the same layer, there is a good chance that the physics is disabled resulting in no collision detection.
     
  3. tobiass

    tobiass

    Joined:
    Apr 7, 2009
    Posts:
    3,018
    PUN's networking approach is not perfectly suitable for physical interaction of characters, as each user is authoritative of the own character and gets updates of the other characters with some delay. This is typically enough to put the physics off and trigger weird reactions.

    What do you expect to achieve?
     
  4. arnaucastillomur

    arnaucastillomur

    Joined:
    May 16, 2020
    Posts:
    1
    I have a really really simple solution for all of you that face the problem that the players go through each other when they both move at the same time and only if one of the players is standing still then the collision works well.

    My characters are balls. I have put 5 sphere colliders on each ball, each one smaller than the initial one, all on the same gameObject (I have not created children gameObjects, really important). The original has a radius of 1 (this is as big as the ball), the others have 0.9, 0.8 0.7 and 0.5 radius. What this does is ensuring that if one of the "collision layers" fails to interact with the other player, there are other 4 layers prepared to collide. It is like five lines of defense. Now it works AMAZING, this problem is gone for ever, or so I hope.

    If your characters are humans, then you have to put four humans of different sizes inside the original one, and with only the mesh collider it is enough. But in this case, I think that you would need a photon transform view and photon view on each of them, and this can be problematic. So a simplier solution is to use the unity default colliders (sphere, box) because you can add all of them on the same gameObject.

    I want this called The Photon-Matryoshka Technique. So if anytime someone asks, you say: use the photon-matryoshka technique and problems solved hahaha

    Edit: if you have a lot of problems with synchronization, try this: use the Photon Transform View Classic with this settings: synchronize position with enable teleport for big distances (10), interplote (estimate speed) and extrapolate disabled. Syncronize rotation enabled, with lerp and lerp speed 15 (in my case). Also add a photon rigid body view in case it has rigid body.

    I hope that it helped.
     
    Last edited: Apr 30, 2021
    gamefish and tobiass like this.