Unity 2D跑酷游戏Tilemap实例化异常及Grid子对象设置问题
Unity 2D跑酷关卡生成Tilemap压缩问题解决
我正在开发一款Unity 2D平台跑酷游戏,已将平台段Tilemap制作成预制体。使用LevelGenerator脚本生成关卡时,Tilemap被压缩到当前网格的单个单元格中;手动将Tilemap放置到Grid下可正常显示。请问如何通过脚本将实例化的Tilemap设置为Grid组件的子对象?
现有代码
public class LevelGenerator : MonoBehaviour { private const float PLAYER_GENERATION_DISTANCE = 200f; [SerializeField] private Transform StartLevel; [SerializeField] private List<Transform> levelPartsList; [SerializeField] private GameObject player; private Vector3 lastEndPosition; private void Awake() { player = GameObject.FindWithTag("Player"); lastEndPosition = StartLevel.Find("endPosition").position; } void Update(){ if (Vector3.Distance(player.transform.position, lastEndPosition) < PLAYER_GENERATION_DISTANCE) { print("I am WOrking!!!"); SpawnLevelPart(); } } private void SpawnLevelPart() { Transform selectRandomType = levelPartsList[Random.Range(0,levelPartsList.Count)]; Transform lastLevelPartTransform = SpawnLevelPart(selectRandomType,lastEndPosition); lastEndPosition = lastLevelPartTransform.Find("endPosition").position; } private Transform SpawnLevelPart(Transform levelPart,Vector3 spawnPosition) { Transform levelPartTransform = Tilemap.Instantiate(levelPart,spawnPosition,Quaternion.identity); return levelPartTransform; } }
效果说明
- 异常效果:实例化后的Tilemap被压缩至单个网格单元格内
- 预制体效果:Tilemap布局显示正常
解决方案
问题核心是实例化的Tilemap没有挂载到Grid对象下,缺少正确的网格坐标系参考,导致显示异常。按以下步骤修改:
- 在脚本中添加Grid组件的引用,指定Tilemap的父对象
- 实例化Tilemap后,设置其transform的父对象为Grid的transform
修改后的完整代码
public class LevelGenerator : MonoBehaviour { private const float PLAYER_GENERATION_DISTANCE = 200f; [SerializeField] private Transform StartLevel; [SerializeField] private List<Transform> levelPartsList; [SerializeField] private GameObject player; // 添加Grid引用,在Inspector中拖入场景中的Grid对象 [SerializeField] private Grid levelGrid; private Vector3 lastEndPosition; private void Awake() { player = GameObject.FindWithTag("Player"); lastEndPosition = StartLevel.Find("endPosition").position; } void Update(){ if (Vector3.Distance(player.transform.position, lastEndPosition) < PLAYER_GENERATION_DISTANCE) { print("I am WOrking!!!"); SpawnLevelPart(); } } private void SpawnLevelPart() { Transform selectRandomType = levelPartsList[Random.Range(0,levelPartsList.Count)]; Transform lastLevelPartTransform = SpawnLevelPart(selectRandomType,lastEndPosition); lastEndPosition = lastLevelPartTransform.Find("endPosition").position; } private Transform SpawnLevelPart(Transform levelPart,Vector3 spawnPosition) { Transform levelPartTransform = Tilemap.Instantiate(levelPart,spawnPosition,Quaternion.identity); // 设置实例化对象的父对象为Grid,保持局部坐标不变避免偏移 levelPartTransform.SetParent(levelGrid.transform, false); return levelPartTransform; } }
关键修改点
- 新增
[SerializeField] private Grid levelGrid;,在Unity编辑器中将场景中的Grid对象拖入该字段 - 在
SpawnLevelPart方法中添加levelPartTransform.SetParent(levelGrid.transform, false);,第二个参数false确保实例化对象的位置不会因父对象变换而偏移
内容的提问来源于stack exchange,提问作者Jbalda
相关产品推荐
相关产品推荐

