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

Resolved Object rotates fine in update but not in a different method

Discussion in 'Scripting' started by justsum1uknow, May 24, 2020.

  1. justsum1uknow

    justsum1uknow

    Joined:
    May 21, 2020
    Posts:
    2
    I'm trying to rotate a door with the following code, it works when the methods are called in Update but not in Interact, when done in Interact the door only rotates one way.
    Also for some reason bool isOpen will get changed twice

    Code (CSharp):
    1. //From answers.unity.com
    2.  
    3.     IEnumerator RotateMe(Vector3 byAngles, float inTime)
    4.     {
    5.        
    6.         var fromAngle = transform.rotation;
    7.         var toAngle = Quaternion.Euler(transform.eulerAngles + byAngles);
    8.         for (var t = 0f; t <= 1; t += Time.deltaTime / inTime)
    9.         {
    10.             transform.rotation = Quaternion.Slerp(fromAngle, toAngle, t);
    11.             yield return null;
    12.         }
    13.     }
    14.  
    15. //Rotates an object correctly when called in Update
    16.  
    17. void Update () {
    18.      if(Input.GetKeyDown("e")){
    19.      StartCoroutine(RotateMe(Vector3.up * 90, 0.8f));
    20.      }
    21.      if(Input.GetKeyDown("q")){
    22.      StartCoroutine(RotateMe(Vector3.up * -90, 0.8f));
    23.      }
    24.    }
    25.  
    26.  
    27. //Does not work when called in a method like so
    28.  
    29.    void Interact()
    30.     {
    31.         Debug.Log(tf.rotation.y);
    32.         if (!isOpen)
    33.             OpenDoor();
    34.         if (isOpen)
    35.             CloseDoor();
    36.     }
    37.    
    38.     void CloseDoor()
    39.     {
    40.         StartCoroutine(RotateMe(Vector3.up * -90, 0.8f));
    41.         isOpen = false;
    42.         Debug.LogError(isOpen.ToString());
    43.     }
    44.     void OpenDoor()
    45.     {
    46.         StartCoroutine(RotateMe(Vector3.up * 90, 0.8f));
    47.         isOpen = true;
    48.         Debug.LogError(isOpen.ToString());
    49.     }
    50.  
    51. //Interact method gets called like this
    52.  
    53.     void Update()
    54.     {
    55.  
    56.         if (Input.GetKeyDown(KeyCode.E))
    57.         {
    58.             RaycastHit hit;
    59.  
    60.             if (Physics.Raycast(transform.position, cam.transform.forward, out hit, 10))
    61.             {
    62.                 if (hit.collider.gameObject.tag == "Interactable")
    63.                 {
    64.                     Debug.Log("Looking at interactable object" + hit.collider.gameObject.tag);
    65.                     hit.collider.gameObject.SendMessageUpwards("Interact");
    66.                     Debug.Log("Used interactable object");                  
    67.                 }
    68.             }
    69.         }
    70.     }
    71. }
     
  2. Pagefile

    Pagefile

    Joined:
    Feb 10, 2013
    Posts:
    51
    You have a logic error in Interact(). On first use, assuming the door os closed it will call OpenDoor(), which sets isOpen to true. Once OpenDoor() returns, CloseDoor() is immediately called since isOpen is true and passes the if check. Try making it an if else if block.

    You could also try moving the isOpen assignment to the end of the coroutines so it isn't considered open or closed until it's finished that action.
     
  3. justsum1uknow

    justsum1uknow

    Joined:
    May 21, 2020
    Posts:
    2
    Thanks for catching that, I added a bool isOpening, I set it to true at the start of RotateMe and false at the end of it.
    And in the two if statements instead of checking if the door is open it now checks for isOpen && !isOpening.