Closed M0Z1NG0 closed 7 months ago
Hi there, @M0Z1NG0. Sorry for the late reply. This is a problem with the sprite atlas texture that ST2U creates and places in the TSX asset through a scripted importer. I think the time is coming (or is here) where I need to abandon that approach and instead reference the source textures when creating tiles.
If I can put together an early release of the ST2U plugin that addresses this would you be willing to test it out?
Absolutely, thank you! I'm testing this plugin out for a prototype at work, so the sooner we know we can commit to this tool the better we can plan things out. Just let me know what I can do.
I'm almost ready to share a new version of ST2U that uses source texture assets instead of generated atlases. What version of Unity would you like me to double-check this on before I send you a zip?
Awesome thank you! I'm currently using 2022.3.10f1.
Hi again, @M0Z1NG0. I'm sorry this is taking so long. I've run into an issue with the way Unity reimports textures that are broken up into sprites. For large textures with lots of sprites (10's of thousands) it's taking over an hour to import and it gives the appearance that Unity is in an infinite loop. I've been looking into ways around this and will keep you posted.
Hi again, @M0Z1NG0. I've just deployed version 2.2.0
to my test branch which gets rid of the generated sprite atlases and instead uses sprites that are added to your source textures automatically.
Everything should "just work" but if you run into issues let me know and I'll fix ASAP. If your project is on github I'm happy to take a look there as well if fixes are needed.
@Seanba Thank you so much again. After reimporting, it seems to be about 99% working. All the .tmx .tsx. and .tx files are importing fine and without error. And the tilemap renderers are all looking as expected. The only thing that I'm having trouble with are the colliders. I've been using a custom importer to add TilemapCollider2Ds and CompositeCollider2Ds to the tilemap GOs, and the TilemapCollider2D never seems to be populated with tiles anymore. I tried checking the colliderType of each tile in the tilemap and they all seem to be set to None. I'm not sure if that works the same with your SuperTile class. Also the spritesheet for the tileset does have physics shapes generated. I haven't changed anything about my project, and this setup was working before the update, so let me know if there's a change I need to make on the Tiled side or something. Unfortunately our project isn't on Github, and I can't send it to you, but here is the custom importer I've been using. It's specifically the Solid layer that isn't working with collisions, the part under else if(child.name == "Solid")
using SuperTiled2Unity;
using SuperTiled2Unity.Editor;
using UnityEngine;
using UnityEngine.Tilemaps;
public class RCFTMXImporter : CustomTmxImporter
{
public override void TmxAssetImported(TmxAssetImportedArgs args)
{
var map = args.ImportedSuperMap;
var gridTransform = map.transform.GetChild(0);
for(int i = 0; i < gridTransform.childCount; i++)
{
var child = gridTransform.GetChild(i).gameObject;
child.transform.position = Vector3.zero;
//move each tilemap so bottom left at 0,0
var tilemap = child.GetComponent<Tilemap>();
if (tilemap != null)
{
var newTilemapOrigin = new Vector3Int(0, tilemap.origin.y + map.m_Height-1, tilemap.origin.z);
var tiles = tilemap.GetTilesBlock(tilemap.cellBounds);
var tilemapSize = tilemap.cellBounds.size;
tilemap.ClearAllTiles();
tilemap.SetTilesBlock(new BoundsInt(newTilemapOrigin, tilemapSize), tiles);
}
//Make sure objects are positioned correctly as well
var objLayer = child.GetComponent<SuperObjectLayer>();
if(objLayer != null)
{
for(int j=0; j<objLayer.transform.childCount; j++)
{
var obj = objLayer.transform.GetChild(j).gameObject;
/*
var superObj = obj.GetComponent<SuperObject>();
if (superObj != null) {
//create door, set door height
if (superObj.m_Type == "Door")
{
var doorPrefab = Resources.Load<GameObject>("Objects/Door");
var doorObj = InstantiateChildWithUniqueName(objLayer.gameObject, doorPrefab); //Gotta have a unique name i guess
doorObj.transform.position = obj.transform.position;
var door = doorObj.GetComponent<LockingDoor>();
door.height = superObj.m_Height;
Object.DestroyImmediate(obj);
j--;//since child list has changed, do this index again
}
}*/
//Shift the object up to match the map
obj.transform.position = obj.transform.position + new Vector3(0, map.m_Height * 16);
}
}
else if (child.name == "Solid")
{
//Add colliders to terrain
child.layer = (int)GameConstants.Layers.Terrain;
child.GetComponent<TilemapRenderer>().sortingLayerID = GameConstants.SortingLayers.Foreground.ID();
var col = child.AddComponent<TilemapCollider2D>();
col.usedByComposite = true;
var rb = child.AddComponent<Rigidbody2D>();
rb.bodyType = RigidbodyType2D.Static;
var compcol = child.AddComponent<CompositeCollider2D>();
compcol.geometryType = CompositeCollider2D.GeometryType.Polygons;
compcol.offsetDistance = 0;
var shadowcaster = child.AddComponent<Game.Utils.TilemapShadowCaster2D>();
shadowcaster.m_SelfShadows = false;
shadowcaster.m_TilemapCollider = compcol;
}
else if(child.name == "Pass Through")
{
//Set up one way platforms
child.layer = (int)GameConstants.Layers.OneWayTerrain;
child.GetComponent<TilemapRenderer>().sortingLayerID = GameConstants.SortingLayers.Foreground.ID();
var PTchildObj = new GameObject("Pass Through Colliders");
PTchildObj.transform.parent = child.transform;
PTchildObj.transform.localPosition = Vector3.zero;
var onewayCol = PTchildObj.AddComponent<OneWayPlatformColliderGenerator>();
onewayCol.platformColliderPrefab = Resources.Load<GameObject>("Prefabs/One Way Collider");
}
else if(child.name.Contains("BG"))
{
if (child.name.Contains("BG1")) //for depth of field effect
{
child.layer = (int)GameConstants.Layers.Background;
}
child.GetComponent<TilemapRenderer>().sortingLayerID = GameConstants.SortingLayers.Background.ID();
//Set up parallax for bg
var bgInfo = child.GetComponent<SuperTileLayer>();
if(bgInfo.m_ParallaxX != 1 || bgInfo.m_ParallaxY != 1)
{
child.transform.position = new Vector2(bgInfo.m_OffsetX, bgInfo.m_OffsetY);
var parallax = child.AddComponent<ParallaxScroll>();
//Gotta convert parallax values since tiled is weird
parallax.SetParallaxAmount(new Vector2(1-bgInfo.m_ParallaxX,1-bgInfo.m_ParallaxY));
}
}
else
{
child.gameObject.SetActive(false);
}
}
}
public static GameObject InstantiateChildWithUniqueName(GameObject go, GameObject child)
{
if (go == null)
{
return null;
}
if(child == null)
{
return null;
}
var newObj = UnityEditor.PrefabUtility.InstantiatePrefab(child, go.transform) as GameObject;
// Make sure the child name is unqiue
string name = newObj.name;
int count = 0;
while (go.transform.Find(name) != null)
{
name = string.Format("{0} ({1})", newObj.name, ++count);
}
newObj.name = name;
return newObj;
}
}
And here's a screenshot of the hierarchy and inspector for that specific layer. You can see there's no green gizmo for the tilemap colliders at all.
Wow, did the TilemapCollider2D
actually work with previous versions of ST2U? That one surprises me.
Thanks for sending me the code for your custom importer. I'll look into this soon. Hopefully it's a quick fix.
@M0Z1NG0 When things were working before what did the physics shapes on the sprites for the tiles look like? Were they just rectangles that matched the dimensions of the sprite or did they try to take on the shape of the outline of each sprite?
@Seanba They were just bounding boxes, not the sprite outlines. Although, weirdly enough, I just checked with the old version, in the custom importer, when I call tilemap.GetColliderType() it returns Sprite for all the tiles and not Grid.
Here's a screen showing the tilemap collider working:
@Seanba Oh wait, I misread, you asked about the physics shapes. The texture2D that I'm using is actually still set to Single mode, and doesn't have the tiles seperated into sprites or physics shapes generated. It's just a big rectangle for the whole sheet. It seems to work no matter what settings I use for the texture.
@M0Z1NG0 There must be something you're doing with your project that I'm not thinking of. I'm working with an older version of ST2U and have the same setup with Tilemap
, TilemapRenderer
, Rigidbody2D
, CompositeCollider2D
, and TilemapCollider2D
classes but I don't get any collision geometry for that game object. (That's what I would expect, fwiw.)
If you could make a small example with the behavior you were getting before and share it with me I'd be happy to explore why it's a) working as you intended before the upgrade and b) broken with the upgrade.
Alternatively, we could discuss how to get this working with the Tiled Collision Editor
in Tiled but I suppose there was a reason why you wanted this in a TilemapCollider2D
component to begin with.
@M0Z1NG0 sorry for all the replies but I wonder if you were to modify this code below in the new SuperTiled2Unity delivery if it would help ...
public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
{
tileData.sprite = m_Sprite;
tileData.colliderType = Tile.ColliderType.None; // <------ Try this: use Sprite or Grid collider type?
}
This is in ...Packages\com.seanba.super-tiled2unity\Runtime\Tiles\SuperTile.cs
If that helps then I can make it an option on the TSX importer to set the collider type for the tiles it creates. That could get you on your way.
@Seanba Geeze, I created a new project to test this and couldn't get the colliders to generate either. So I ran the ST2U package from both projects through a diff tool, and noticed there was exactly one line of code different between the two. The same one you just suggested to add haha. Sorry about that. I wrote down the other change I made, so I don't know how I lost track of this one. I still need to re-setup my project with 2.2.0, but I'm certain this'll do the trick. I'll let you know if I run into any other problems. Thanks again for getting this done so quickly.
Alright! Just got everything set back up, and it's all working perfectly. Collisions work, and I was able to set up a sprite atlas on the Unity side without any issue. All the art looks great in editor and in build without any seams, and no errors. Thank you so much!
I'm using version 2.1.1 and getting this error only in builds on both Unity versions 2022.3.10f1 and 2023.2.7f1.
This error only occurs in builds, everything runs fine in editor. It only occurs when I have "Use Sprite Atlas for Tiles" checked on the .tsx I'm using for my tilemap. I'm using a custom importer to add a Tilemap Collider 2D and a Composite Collider 2D to that tilemap.
Interestingly, this issue only occurs when I instantiate the .tmx prefab at runtime. When I add the .tmx prefab to the hierarchy as part of a scene, and then build, it works fine. When this error occurs, none of the collisions on that tilemap work, and my player character falls through the map.
From what I can tell from googling, this error is related to the texture not being set Read/Write, but I have that option enabled in the spritesheet's texture import settings. This guy suggests that it might be related to having a blank tile in the tilemap, but I've combed through my .tmx file and removed any I could find and I'm still getting this error.