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

need help with c# script

Discussion in 'Scripting' started by gbagiryan, Jul 3, 2020.

  1. gbagiryan

    gbagiryan

    Joined:
    May 7, 2020
    Posts:
    10
    Hey everyone. Could anyone help me with this script? It's supposed to be an elevator script and it kinda works, but it's very buggy I can't understand why. The first script I put on a button, which represents a position where the elevator must go.

    Code (csharp):
    1.  
    2.     public float MaxRange {get{return maxRange;}}
    3.     private const float maxRange = 100f;
    4.  
    5.     public customElevator Elevator;
    6.     public GameObject OuterDoorLeft;
    7.     public GameObject OuterDoorRight;
    8.     public Vector3 LeftDoorTarg;
    9.     public Vector3 LeftDoorPos;
    10.     public Vector3 RightDoorPos;
    11.     public Vector3 RightDoorTarg;
    12.  
    13.     private void Awake()
    14.     {
    15.         LeftDoorPos = OuterDoorLeft.transform.localPosition;
    16.         LeftDoorTarg.x = LeftDoorPos.x+0.35f;
    17.  
    18.         RightDoorPos = OuterDoorRight.transform.localPosition;
    19.         RightDoorTarg.x = RightDoorPos.x-0.35f;
    20.     }
    21.     public void OnInteract()
    22.     {
    23.         Elevator.ActivateElevator(this);
    24.     }
    25.  
    26.     public void OnStartHover()
    27.     {
    28.      
    29.     }
    30.     public void OnEndHover()
    31.     {
    32.      
    33.     }
    34.  
    Second script goes on the elevator itself and moves it when a button is pressed. It also deals with door opening and here's the problem. The doors act strange, the speed varies and it seems like the try to open and close at the same time, stuttering. What could be the reason?
    Code (csharp):
    1.  
    2.     public float MaxRange {get{return maxRange;}}
    3.     private const float maxRange = 100f;  
    4.     public GameObject InnerDoorLeft;
    5.     public GameObject InnerDoorRight;
    6.  
    7.     bool move = false;
    8.     bool arrived = false;
    9.     bool DoorsOpened = false;
    10.     public float speed=1f;
    11.     public float doorSpeed=1f;
    12.     Vector3 TargetFloor;
    13.     interButton floor;
    14.  
    15.     public void ActivateElevator(interButton floor){
    16.         if(floor!=null){
    17.             this.floor = floor;
    18.             move = true;
    19.             TargetFloor = floor.transform.position;
    20.         }
    21.     }
    22.  
    23.     private void FixedUpdate() {
    24.         if(DoorsOpened==true){          
    25.             StartCoroutine(CloseDoors());
    26.         }
    27.         if (move==true && DoorsOpened==false)
    28.         {
    29.             MoveElevator();
    30.         }
    31.         if(move==false && arrived==true){
    32.             OpenDoors();
    33.         }      
    34.     }
    35.     public void MoveElevator(){
    36.  
    37.         transform.position = Vector3.MoveTowards(transform.position, TargetFloor, speed*Time.deltaTime);
    38.             if(transform.position == TargetFloor){
    39.                 move=false;
    40.                 arrived = true;
    41.             }
    42.     }
    43.     public void OpenDoors(){
    44.         floor.OuterDoorLeft.transform.localPosition = Vector3.MoveTowards(floor.OuterDoorLeft.transform.localPosition, floor.LeftDoorTarg, doorSpeed*Time.deltaTime);
    45.         floor.OuterDoorRight.transform.localPosition = Vector3.MoveTowards(floor.OuterDoorRight.transform.localPosition, floor.RightDoorTarg, doorSpeed*Time.deltaTime);
    46.      
    47.         if(floor.OuterDoorLeft.transform.localPosition == floor.LeftDoorTarg && floor.OuterDoorRight.transform.localPosition == floor.RightDoorTarg){
    48.             arrived = false;
    49.             DoorsOpened = true;
    50.         }
    51.  
    52.     }
    53.     public IEnumerator CloseDoors(){
    54.         yield return new WaitForSeconds(3);
    55.      
    56.         floor.OuterDoorLeft.transform.localPosition = Vector3.MoveTowards(floor.OuterDoorLeft.transform.localPosition, floor.LeftDoorPos, doorSpeed*Time.deltaTime);
    57.         floor.OuterDoorRight.transform.localPosition = Vector3.MoveTowards(floor.OuterDoorRight.transform.localPosition, floor.RightDoorPos, doorSpeed*Time.deltaTime);
    58.  
    59.         if(floor.OuterDoorLeft.transform.localPosition == floor.LeftDoorPos && floor.OuterDoorRight.transform.localPosition == floor.RightDoorPos){          
    60.             DoorsOpened = false;
    61.         }
    62.     }
    63.  
    There's also a script on my camera and an IInteractable interface but they just deal with my interaction system.

    I apologize for the terrible code I'm still pretty new to c# and Unity. Hope someone can help me and thanks in advance.
     
    Last edited: Jul 3, 2020
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,514
    gbagiryan likes this.
  3. Elango

    Elango

    Joined:
    Jan 27, 2016
    Posts:
    107
    Problem is in FixedUpdate switch logic.
    You calling "StartCoroutine(CloseDoors())" a hundred times.
    Instead of DoorsOpened bool make enum for doors states
    Code (CSharp):
    1.     enum E_DoorsState {
    2.         Delay,
    3.         Closed,
    4.         Closing,
    5.         Opened,
    6.         Opening
    7.     }
    Make "public IEnumerator CloseDoors()" only for delay (don't forget to StopAllCoroutines() if you need restart it)
    Code (CSharp):
    1.     public IEnumerator CloseDoorsDelay()
    2.     {
    3.         doors = E_DoorsState.Delay;
    4.         yield return new WaitForSeconds(3);
    5.         doors = E_DoorsState.Closing;
    6.     }
    And move closing code in its own method like OpenDoors.
    FixedUpdate should look like this:
    Code (CSharp):
    1.     private void FixedUpdate()
    2.     {
    3.         if (doors == E_DoorsState.Opened)
    4.         {
    5.             StartCoroutine(CloseDoorsDelay());
    6.         }
    7.         else if (move == false && arrived == true && doors == E_DoorsState.Closed)
    8.         {
    9.             doors = E_DoorsState.Opening;
    10.         }
    11.         else if (move == true && doors == E_DoorsState.Closed)
    12.         {
    13.             MoveElevator();
    14.         }
    15.         else if(doors == E_DoorsState.Closing)
    16.         {
    17.             CloseDoors();
    18.         }
    19.         else if(doors == E_DoorsState.Opening)
    20.         {
    21.             OpenDoors();
    22.         }
    23.     }
    And don't forget to put E_DoorsState.Closed/E_DoorsState.Opened into CloseDoors()/OpenDoors() ends and E_DoorsState.Opening into OpenDoors() start.
    Also try using Time.smoothDeltaTime instead of Time.deltaTime.
    I hope you get the idea... there is a lot more problems ahead like button ActivateElevator logic and floor switching.
     
    Last edited: Jul 3, 2020
    gbagiryan likes this.
  4. gbagiryan

    gbagiryan

    Joined:
    May 7, 2020
    Posts:
    10
    Thanks a lot! I can see the mistake now. Everything is fixed and working. I really appreciate your help.