Slowly rotate Tilemap.SetTransformationMatrix

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.

Tilemap t= GetComponent<Tilemap>();
       Matrix4x4 m= Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(rX, rY, rZ), Vector3.one);
       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:

transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 180, 0), Time.deltaTime * speed);
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

Theres a handy unity function called Lerp for this

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?

Matrix4x4.TRS(
    Vector3.zero, 
    Quaternion.Euler(
        Quaternion.Lerp(transform.rotation, Quaternion.Euler(0, 0, 0), Time.deltaTime * speed),
        Quaternion.Lerp(transform.rotation, Quaternion.Euler(0, 0, 0), Time.deltaTime * speed),
        Quaternion.Lerp(transform.rotation, Quaternion.Euler(0, 0, 90), Time.deltaTime * speed),
    ), 
    Vector3.one
);

Thanks in advance

Jason

I found a way to slowly transform a tilemap position. Here is what i got so far:

    /// <summary>
    /// Rotate a tile slowly
    /// </summary>
    /// <param name="ASpeed"></param>
    void SlowRotateTile(float ASpeed, float ADegree) {
        currRotationZ = Mathf.Lerp(currRotationZ, ADegree, ASpeed * Time.deltaTime);
        Debug.Log("currRotation:" + currRotationZ);
        tileMap.SetTransformMatrix(
            currentTilePos,
            Matrix4x4.TRS(
                Vector3.zero,
                Quaternion.Euler(tileRotationX, tileRotationY, currRotationZ),
                new Vector3(tileScaleX, tileScaleY, tileScaleZ)
            )
        );
        if (currRotationZ >= ADegree) {
            rotate = false;
        }  
    }

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

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 :frowning:

Thanks Jason

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:

angle += speed * Time.deltaTime; // in degrees

If you have limits in mind, when those limits are reached, stop updating it:

if (angle > 50) angle = 50; // for example

After updating it every frame, then drive the desired axis:

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.