OndrejNepozitek / Edgar-Unity

Unity Procedural Level Generator
https://ondrejnepozitek.github.io/Edgar-Unity/docs/introduction
MIT License
817 stars 70 forks source link

Tilemap didn't save the transform of a tile #49

Closed longtran2904 closed 4 years ago

longtran2904 commented 4 years ago

This is a problem that i've already knew in unity when i was trying to save and spawn an array of tiles. If you rotated or flipped the tile when drawing (by pressing "[" or "Shift+[") and then saved it back into an array it wouldn't save the transform of it so when you spawned the tiles back it would be flipped back to normal which was really weird. Some of my rooms while drawing i flipped and it wouldn't be stored. Are there any ways to get around it? I would recommend you to store the transform of the tiles (Matrix4x4) in the next update.

OndrejNepozitek commented 4 years ago

I've got a hotfix for you. I'll add this to the next version of the plugin but if you want it working now, do the following. Find the "PostProcessUtils.cs" file (Assets\ProceduralLevelGenerator\Runtime\Generators\Common\Utils) and find line 73. Below this line, add the following:

destinationTilemap.SetTransformMatrix(tilemapPosition + offset, sourceTilemap.GetTransformMatrix(tilemapPosition));

The result should look like this:

        public static void CopyTiles(List<Tilemap> sourceTilemaps, List<Tilemap> destinationTilemaps, Vector3Int offset)
        {
            sourceTilemaps = RoomTemplateUtils.GetTilemapsForCopying(sourceTilemaps);

            DeleteNonNullTiles(sourceTilemaps, destinationTilemaps, offset);

            foreach (var sourceTilemap in sourceTilemaps)
            {
                var destinationTilemap = destinationTilemaps.FirstOrDefault(x => x.name == sourceTilemap.name);

                if (destinationTilemap == null)
                {
                    continue;
                }

                foreach (var tilemapPosition in sourceTilemap.cellBounds.allPositionsWithin)
                {
                    var tile = sourceTilemap.GetTile(tilemapPosition);

                    if (tile != null)
                    {
                        destinationTilemap.SetTile(tilemapPosition + offset, tile);
                        destinationTilemap.SetTransformMatrix(tilemapPosition + offset, sourceTilemap.GetTransformMatrix(tilemapPosition));
                    }
                }
            }
        }
longtran2904 commented 4 years ago

I added the code, but when i generated the level again it still didn't worked, the tile still reset it transform.

longtran2904 commented 4 years ago

I was trying to debug it and when Debug.Log the sourceTilemap.GetTransformMatrix(tilemapPosition) it show: 1.00000 0.00000 0.00000 0.00000 0.00000 1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 1.00000 for all the tiles which was weired because i had some tiles that was flipped. Do i need to create a new room template or just use the old one.

OndrejNepozitek commented 4 years ago

You should be able to use your old room templates. If I understand it correctly, Unity should save the transformation data when serializing the room template, right? Did you try restarting Unity?

What I did when I tried it:

longtran2904 commented 4 years ago

I thought Matrix4x4 wasn't serializable. I tested it by flipping, rotating it and it still not working. Your line of code was setting the transform from the sourceTilemap to the destinationTilemap but the transform of sourceTilemap (when i debug.log it) wasn't flipped or rotated which is the source of the problem (again i didn't think that Matrix4x4 was serializable and Unity wouldn't save it).

longtran2904 commented 4 years ago

And i tried to restart Unity too.

longtran2904 commented 4 years ago

I tried creating a new room template and rotated a tile. It still didn't work. Maybe because i was using the custom room template and tilemaphandler

OndrejNepozitek commented 4 years ago

Which version of Unity do you use? Maybe it's really a serialization issue of Unity. I think it has nothing to do with your custom room template.

On Mon, 27 Apr 2020, 11:14 longtran2904, notifications@github.com wrote:

I tried creating a new room template and rotated a tile. It still didn't work. Maybe because i was using the custom room template and tilemaphandler

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/OndrejNepozitek/ProceduralLevelGenerator-Unity/issues/49#issuecomment-619846487, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARJCD7OIPVKVO72NX5N3KDROVEHDANCNFSM4MRJDLOA .

longtran2904 commented 4 years ago

Unity 2019.3.1f1

longtran2904 commented 4 years ago

Why don't you try to debug.log the the sorceTilemap's transform and see if it actually save at rotated and compare it to me? If true then there is most likely because the unity version and serialization issue.

OndrejNepozitek commented 4 years ago

I'm using Unity 2019.3.1f1, too.

So I tried to debug it. I rotated one single tile in a single room template by pressing "[" 3 times. When debugging, I see that there is once this:

0.00000 1.00000 0.00000 0.00000
-1.00000    0.00000 0.00000 0.00000
0.00000 0.00000 1.00000 0.00000
0.00000 0.00000 0.00000 1.00000

This seems correct because there is exactly one rotated tile in the whole level.

Now when I open the prefab file of the room template and look for the "-1", I see this:

  m_TileMatrixArray:
  - m_RefCount: 1
    m_Data:
      e00: 0
      e01: 1
      e02: 0
      e03: 0
      e10: -1
      e11: 0
      e12: 0
      e13: 0
      e20: 0
      e21: 0
      e22: 1
      e23: 0
      e30: 0
      e31: 0
      e32: 0
      e33: 1

Which looks like it's exactly the transformation matrix that I'm looking for. Maybe you can also look into that room template file and see what is there?

longtran2904 commented 4 years ago

How to look into that? Is it from the json file of generated level?

OndrejNepozitek commented 4 years ago

No. This is the room template prefab. Something like "Assets\ProceduralLevelGenerator\Examples\EnterTheGungeon\Room templates\Entrance.prefab". This is the one that I tried this on. It is just the native Unity serialization of the Room template game object.

longtran2904 commented 4 years ago

I don't have the folder "EnterTheGungeon", just have "Example1", ... But i still tried it on "Room 1" in "Assets\Pro..\Examples...Example1\Room templates\Room 1.prefab" and it didn't work. Rotated tiles: image

When generated: image

OndrejNepozitek commented 4 years ago

One more thing to try: Add a rotated tile to the Room 1 room template, but use a tile from the Example 1 tile palette? Maybe there is a problem with your tiles/tile palette?

longtran2904 commented 4 years ago

Still didn't work: image

After: image

Does the example use a different script? Should i pass the line of code to somewhere in there?

longtran2904 commented 4 years ago

Are there any other ways to get and set the transform of the tiles in your code?

OndrejNepozitek commented 4 years ago

This is really weird.

I also tried it in Unity 2018.4.18f1 and it works. I tried it with both Example 1 and Example 2 tile palettes.

This is the exact version of the PostProcessUtils files that I'm using - https://gist.github.com/OndrejNepozitek/9d489680f57549373684236c3247c309 . I added a debug.log with "Trying to correct the transformation" to really check that you use the correct version of the file.

longtran2904 commented 4 years ago

The directory of your namespace is different than me. Mine is Assets.ProceduralLevelGenerator.Scripts.Generators.Common.Rooms, and your is ProceduralLevelGenerator.Unity.Generators.Common.Rooms. Does it affect anything? Should i change it to mine? (some other namespace are also wrong)

OndrejNepozitek commented 4 years ago

This is from the newest version of the plugin so you can change it back to yours.

OndrejNepozitek commented 4 years ago

This is the "Assets\Pro..\Examples...Example1\Room templates\Room 1.prefab" file after I added several rotated tiles to it: https://gist.github.com/OndrejNepozitek/eb3686db8f96505f45d0637e38f27300 For example on line 2492 you can see a "-1" in the rotation matrix which hints that something is rotated/flipped.

Can you try what happend if xou replace your "Assets\Pro..\Examples...Example1\Room templates\Room 1.prefab" with the content of the gist?

Steps:

longtran2904 commented 4 years ago

Do that, all the banners reset their transform when generated.

longtran2904 commented 4 years ago

Let's me try using this in another project i have

longtran2904 commented 4 years ago

After created a new project (2019.3.1f1) and go into example 1 the problem still existed. Maybe you can try to create a new project on your own, then import your plugin and test it?

OndrejNepozitek commented 4 years ago

It seems that I was finally able to reproduce the issue in an older version of the plugin.

longtran2904 commented 4 years ago

Which version? v2 or v1.x

longtran2904 commented 4 years ago

Have you figured it out what is the problem yet?

OndrejNepozitek commented 4 years ago

Yeah, I was able to fix that.

If you use the v2.0.0-alpha.1-hotfix.1 or some slightly older version, there is one more change needed. In the file "Assets/ProceduralLevelGenerator/Scripts/Generators/Common/Utils/GeneratorUtils.cs" you need to comment the lines 43 and 44:

//var transformation = layoutRoom.Transformation;
//roomTransformations.Transform(roomTemplateInstance, transformation);

Or if you use the newest v2.0.0-alpha.2 version, only the change with the PostProcessUtils file is needed.

I'd probably recommend to update to the newest version but there are some breaking changes (you would have to remove all the old files of the plugin and then import the new files, so it would only work if you didn't change anything in the directory with the plugin. And after you import it, there may be some namespace problems which should be easily fixed by Visual Studio or a similar IDE. All the details are in the release page. And you should not lose any data like Room templates or settings, etc.

Thanks for your patience and that you help me improve the plugin!

P.S. Some time ago, I thought that I would let users automatically rotate/flip rooms. But there were way too many problems with doing that automatically so I later abandoned the idea. And when I did some refactoring in the newest version, I deleted all the files that were related to this idea and the side effect was that it fixed the problems with transformations.

longtran2904 commented 4 years ago

Yes, it've finally been fixed. Thank you so much for helping me. I really appriciate it.

Wish you the best!