Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

rotating objects with loops

Discussion in '2D' started by JorisenTom, Nov 8, 2019.

  1. JorisenTom

    JorisenTom

    Joined:
    Jan 24, 2019
    Posts:
    10
    We want to rotate an object when we stand on it, but as soon as we stand on it unity crashes (we think because it is too much rotations to handle when we do it in a loop:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Teleportation : MonoBehaviour {
    6.  
    7.     public GameObject Portal;
    8.     public GameObject Player;
    9.     private Transform tf;
    10.  
    11.     public int tpDelay;
    12.  
    13.     private GameObject pentagram;
    14.    
    15.     void Start()
    16.     {
    17.         pentagram = GameObject.FindWithTag("Pentagram");
    18.         tf = pentagram.GetComponent<Transform>();
    19.     }
    20.  
    21.     public void OnTriggerEnter2D(Collider2D other)
    22.     {
    23.         if (other.gameObject.tag == "Player")
    24.         {
    25.             StartCoroutine (Teleport ());
    26.             Rotate();    
    27.         }
    28.     }
    29.  
    30.     void Rotate()
    31.     {
    32.         while (true)
    33.         {
    34.             tf.Rotate(new Vector3(0, 0, 6));
    35.         }
    36.     }
    37.  
    38.     IEnumerator Teleport()
    39.     {
    40.         yield return new WaitForSeconds (tpDelay);
    41.         Player.transform.position = new Vector2 (Portal.transform.position.x, Portal.transform.position.y);
    42.     }
    43.  
    44. }
     
  2. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    1,361
    Hi @JorisenTom

    You should watch the Unity basics tutorials, and also some C# coding tutorials for general logic...

    Your rotation method won't work - you are basically saying "while something is true" (which is always, as your condition is simply "true" and not a condition (like x < 10 or something).

    So you are starting a while loop once in OnTriggerEnter2D and it will run forever in that loop after that (= stuck).

    If you need some continuous animation, movement or rotation (or anything continuous that doesn't happen at once / one time) you'll have to do it in Update, FixedUpdate or LateUpdate, depending on your needs. This way you can run something one step at time (rotate 5 degrees / second, x degrees per frame).

    This all is explained in Unity's tutorials.
     
    Last edited: Nov 8, 2019
    MisterSkitz likes this.
  3. JorisenTom

    JorisenTom

    Joined:
    Jan 24, 2019
    Posts:
    10
    So we had it in void update first but we want it only to rotate when you are interacting with it how can we do this?
     
  4. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    1,361
    Do pretty much what I tried to explain. Put your realtime stuff to Update method.

    You will just have to decide when you want your object to rotate.

    Maybe when your player character activating a trigger? OnTriggerStay does that.

    Then your logic should be something like: "when player is touching the trigger, let object rotate in Update".

    You'll have to learn how to use basic conditional checks (if, then, switch) together with triggers.
     
    MisterSkitz likes this.
  5. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    636
    You don't need the while loop to rotate your piece. NOTE- Update() is a "loop" That's what we'll do here.

    Code (CSharp):
    1. private bool canRotate;
    2.  
    3. void Start()
    4. {
    5. canRotate = false;
    6. }
    7.  
    8. void Update()
    9. {
    10. if(canRotate == true)
    11. {
    12. Rotate();
    13. }
    14. }
    15.  
    16. void Rotate()
    17. {
    18. tf.Rotate(new Vector3(0f, 0f, 6f));    
    19. }
    20.  
    21. void OnTriggerEnter2D(Collider2D other)
    22. {
    23. if(other.tag == "Player")
    24. {
    25. StartCoroutine(Teleport());
    26. canRotate = true;
    27. }
    28. }
    29.  
    30. void OnTriggerExit2D(Collider2D other)
    31. {
    32. if(other.tag == "Player")
    33. {
    34. canRotate = false;
    35. }
    36. }
    You can really lock Unity up using while loops improperly. The program waits for the loop to finish before taking the next step and an Infinte loop isn't a good approach. (Python or Pygame maybe you're used to? But this isn't that good with C# API).


    Edit:

    Perhaps it isn't such a bad idea to create a rotation speed?

    Code (CSharp):
    1. private float rotationSpeed = 5f; // Set this however you wish
    2.  
    3. // Then in Rotate()
    4.  
    5. void Rotate()
    6.     {    
    7.       tf.Rotate(new Vector3(0f, 0f, 6f * rotationSpeed * Time.deltaTime));
    8.  
    9. //Since you're updating frames within Update() use deltaTime
    10. // to smooth the rotation cycles.
    11. // If you use FixedUpdate() --- Preferred for calculations
    12. // Use fixedDeltaTime instead.
    13.     }
     
    Last edited: Nov 11, 2019
    JorisenTom likes this.