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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Help on a door script

Discussion in 'Scripting' started by clawd31, Mar 5, 2016.

  1. clawd31

    clawd31

    Joined:
    Aug 5, 2013
    Posts:
    26
    Hello, a time ago, i had a problem with door interaction. On my server, only the master was able to interact with the door, i fixed it.
    Now i have another, when the client interact with a door, it's very laggy and don't open properly (half way and start to freeze), same with the host when he close the door. I think this is a problem due to RPC but i don't find out what's the problem :/
    Can someone help me please ?

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class DoorInteractionMultiplayer : Photon.MonoBehaviour
    5. {
    6.     public PhotonView pv;
    7.     public float smooth = (float)2.0;
    8.     public float DoorOpenAngle = (float)90.0;
    9.     public float DoorCloseAngle = (float)0.0;
    10.     public bool open = false;
    11.     public bool enter = false;
    12.     public string defined_key = "f";
    13.     public AudioClip OpenDoorSound;
    14.     public AudioSource ASource;
    15.  
    16.     void Start()
    17.     {
    18.         //Create PhotonView
    19.         this.gameObject.AddComponent<PhotonView>();
    20.         pv = PhotonView.Get(this);
    21.         pv.observed = this;
    22.         pv.synchronization = ViewSynchronization.UnreliableOnChange;
    23.         pv.viewID = 7;
    24.     }
    25.      
    26.     void OnTriggerEnter(Collider other)
    27.     {
    28.         if (other.gameObject.tag == "Player")
    29.         {
    30.             (enter) = true;
    31.         }
    32.     }
    33.      
    34.     void OnTriggerExit(Collider other)
    35.     {
    36.         if (other.gameObject.tag == "Player")
    37.         {
    38.             (enter) = false;
    39.         }
    40.     }
    41.      
    42.     void Update () {
    43.         if (open == true) {
    44.             pv.RPC("openDoor", PhotonTargets.AllBuffered, null);
    45.         } else {
    46.             pv.RPC("closeDoor", PhotonTargets.AllBuffered, null);
    47.         }
    48.  
    49.         if (enter == true && Input.GetKeyDown(defined_key)) {
    50.             open = !open;
    51.             ASource.PlayOneShot(OpenDoorSound, 0.7F);
    52.         }
    53.     }
    54.  
    55.     [PunRPC]
    56.     void closeDoor()
    57.     {
    58.         var target1 = Quaternion.Euler (transform.rotation.x, DoorCloseAngle, transform.rotation.z);
    59.         transform.rotation = Quaternion.Slerp(transform.rotation, target1, Time.deltaTime * smooth);
    60.     }
    61.  
    62.     [PunRPC]
    63.     void openDoor()
    64.     {
    65.         var target = Quaternion.Euler (transform.rotation.x, DoorOpenAngle, transform.rotation.z);
    66.         transform.rotation = Quaternion.Slerp(transform.rotation, target, Time.deltaTime * smooth);
    67.     }
    68. }
    69.  
    EDIT: Video of the sync bug
     
    Last edited: Apr 17, 2016
  2. clawd31

    clawd31

    Joined:
    Aug 5, 2013
    Posts:
    26
    If you need a video, i can provide one :)
    Thank for you help :)
     
  3. clawd31

    clawd31

    Joined:
    Aug 5, 2013
    Posts:
    26
    Does anyone had this sync problem ? I added the video :)
     
  4. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,887
    You need to make sure only the server ever opens the door. The clients should tell the server they want to open it, then the server actually opens it.
     
  5. clawd31

    clawd31

    Joined:
    Aug 5, 2013
    Posts:
    26
    I'm new to networking, first time ever using it, does it work if i use: PhotonNetwork.isMasterClient to send RPC ?
     
  6. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,887
    I don't use Photon networking, just the official Unity one Unet, but it looks like they are reading each others data, and one has it closed, the other has it open, so it messes up. Clients should only read from the server. Server shouldn't be watching/reading the client's door state.

    RPC should be for server to run functions on clients, so maybe checking PhotonNetwork.isMasterClient first will work.
     
  7. clawd31

    clawd31

    Joined:
    Aug 5, 2013
    Posts:
    26
    Do you have an exemple ? I'm a little bit lost with those rpc and masterclient check :x
     
  8. clawd31

    clawd31

    Joined:
    Aug 5, 2013
    Posts:
    26
    Do u have an UNET exemple of that ? Maybe i can adapt it to photon :)
     
  9. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,887
    It was hooked through an interaction system and won't make any sense.

    In Unet, the client would call a Command. Commands are called from clients, but only run server-side.

    The problem is that the client can't do GetComponent<Door>().openDoor(), because it doesn't own the object (it's a server-owned networked door, not a local offline door), so you just pass in the netId of the thing you're trying to interact with.

    Usage on client:
    Code (csharp):
    1. void Update()
    2. {
    3.     if (!isLocalPlayer) return;
    4.  
    5.     if (Input.GetButtonDown("Use"))
    6.     {
    7.         // Detect what object you want to use, and pass netId as parameter.
    8.         // Client executes this function.
    9.         CmdUseDoor(doorGameObject.GetComponent<NetworkIdentity>.netId)
    10.     }
    11. }
    12.  
    13. // Runs on server only
    14. [Command]
    15. CmdUseDoor(NetworkInstanceId doorNetID)
    16. {
    17.     GameObject doorGO = NetworkServer.FindLocalObject(id);
    18.  
    19.     // Server opens door
    20.     doorGO.GetComponent<Door>().useDoor();
    21.  
    22.     // Server opens door on clients' machines
    23.     RpcUseDoor(...);
    24. }
    This was the old way I did it, but I think Unet has updated ownership stuff since then, so it might be easier. This was just an example, so you should actually have better interaction system using interfaces/inheritance, and use syncvars/hooks/syncevents.

    Note that "hosts" are clients too, so RPC's will run there.
     
  10. clawd31

    clawd31

    Joined:
    Aug 5, 2013
    Posts:
    26
    That's different in Photon :/ It's very strange that no one on this forum has this sync problem :x
     
  11. skalev

    skalev

    Joined:
    Feb 16, 2012
    Posts:
    264
    Maybe other people are not using Photon so they don't know. Did you try post / read stuff off the photon forum/website? this might be the better place to look, as opposed to a general unity forum. Also, I would check the unity networking forums.