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
  4. Dismiss Notice

Slowly rotate Tilemap.SetTransformationMatrix

Discussion in 'Scripting' started by masterkrueger, May 19, 2020.

  1. masterkrueger

    masterkrueger

    Joined:
    Apr 23, 2016
    Posts:
    10
    Hi @All,

    I want to rotate a tile slowly, lets say in 5 seconds.

    I can rotate them instantly with a quaternion, but cant find a way to do it over time.

    Code (CSharp):
    1. Tilemap t= GetComponent<Tilemap>();
    2.        Matrix4x4 m= Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(rX, rY, rZ), Vector3.one);
    3.        t.SetTransformMatrix(new Vector3Int(0, 0, 0), m);
    The crucial part is Quaternion.Euler(rX, rY, rZ) where the parameters should be applied over time.
    I tried to use StartCoroutine with "yield return new WaitForSeconds(5);" but that didn't work either.

    I found slow rotation methods like this:
    Code (CSharp):
    1. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 180, 0), Time.deltaTime * speed);
    2. transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(0, 180, 0), speed * Time.deltaTime);
    But i don't know how to use this with my Tilemap.

    Can anyone enlighten me please.

    Many thanks
    Jason
     
  2. Primoz56

    Primoz56

    Joined:
    May 9, 2018
    Posts:
    369
    Theres a handy unity function called Lerp for this
     
  3. masterkrueger

    masterkrueger

    Joined:
    Apr 23, 2016
    Posts:
    10
    Hi Primoz56, thanks for your help. I took a look at Lerp and understand what this method is for but how to use it in my example. Could i write it like this to rotate slowly 90° around the Z-axis?

    Code (CSharp):
    1. Matrix4x4.TRS(
    2.     Vector3.zero,
    3.     Quaternion.Euler(
    4.         Quaternion.Lerp(transform.rotation, Quaternion.Euler(0, 0, 0), Time.deltaTime * speed),
    5.         Quaternion.Lerp(transform.rotation, Quaternion.Euler(0, 0, 0), Time.deltaTime * speed),
    6.         Quaternion.Lerp(transform.rotation, Quaternion.Euler(0, 0, 90), Time.deltaTime * speed),
    7.     ),
    8.     Vector3.one
    9. );
    Thanks in advance

    Jason
     
  4. masterkrueger

    masterkrueger

    Joined:
    Apr 23, 2016
    Posts:
    10
    I found a way to slowly transform a tilemap position. Here is what i got so far:

    Code (CSharp):
    1.     /// <summary>
    2.     /// Rotate a tile slowly
    3.     /// </summary>
    4.     /// <param name="ASpeed"></param>
    5.     void SlowRotateTile(float ASpeed, float ADegree) {
    6.         currRotationZ = Mathf.Lerp(currRotationZ, ADegree, ASpeed * Time.deltaTime);
    7.         Debug.Log("currRotation:" + currRotationZ);
    8.         tileMap.SetTransformMatrix(
    9.             currentTilePos,
    10.             Matrix4x4.TRS(
    11.                 Vector3.zero,
    12.                 Quaternion.Euler(tileRotationX, tileRotationY, currRotationZ),
    13.                 new Vector3(tileScaleX, tileScaleY, tileScaleZ)
    14.             )
    15.         );
    16.         if (currRotationZ >= ADegree) {
    17.             rotate = false;
    18.         }  
    19.     }
    But now i am stuck on how to rotate in time. I managed to stop the rotation with a boolean in the Update() method but i want to start the rotation on Mouseclick. This works but you have to click very often to get to the full 90° turn ^^
    I'm not sure how to start a process on a tile.

    Maybe this should be a recursive function turning the tile as long as the desired degree are not reached and calling it self with the current rotation to get the result?

    Maybe someone has a better idea or done this before. This cant be so difficult to achieve.

    Thx Jason
     
  5. masterkrueger

    masterkrueger

    Joined:
    Apr 23, 2016
    Posts:
    10
    Ok last try if someone can help me. I just want to GetTransformMatrix alter the Z value and put a result back with SetTransformMatrix. But as the documentation says, you can not read euler angles and put them back as quaternions.

    So how do i store information about the rotation of tiles to stop the rotation routine in the update function if a desired degree per tile is reached?

    I am reading and progging for a week now with no result, thats so annoying :(

    Thanks Jason
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,780
    If you're rotating on only one axis, just use a single float variable.

    Every frame adjust that float value by how much you want the object to rotate that frame:

    Code (csharp):
    1. angle += speed * Time.deltaTime; // in degrees
    If you have limits in mind, when those limits are reached, stop updating it:

    Code (csharp):
    1. if (angle > 50) angle = 50; // for example
    After updating it every frame, then drive the desired axis:

    Code (csharp):
    1. transform.rotation = Quaternion.Euler( 0, 0, angle); // spin on Z axis
    If this is part of a more complex object, perhaps you want to set
    transform.localRotation
    instead.