Unity 2D中如何获取瓦片地图内特定瓦片的位置?
解决Tilemap碰撞时拾取物在瓦片附近生成的问题
方法一:直接用碰撞接触点生成(最简单)
你当前用col.transform.position拿到的是整个Tilemap的原点,自然会在(0,0)附近生成拾取物。直接用碰撞产生的接触点作为生成基准即可,修改后的代码如下:
using UnityEngine; public class Drops : MonoBehaviour { public GameObject wooddropling; public GameObject stonedropling; // 可在Inspector面板调整的随机生成范围 public float spawnRange = 3f; void OnCollisionEnter2D(Collision2D col) { // 获取首个碰撞接触点的世界坐标 Vector2 hitPos = col.contacts[0].point; if (col.gameObject.CompareTag("trees")) { Vector3 spawnPos = new Vector3( hitPos.x + Random.Range(-spawnRange, spawnRange), hitPos.y + Random.Range(-spawnRange, spawnRange), 0f ); Instantiate(wooddropling, spawnPos, Quaternion.Euler(0, 0, Random.Range(0f, 360f))); } else if (col.gameObject.CompareTag("stones")) { Vector3 spawnPos = new Vector3( hitPos.x + Random.Range(-spawnRange, spawnRange), hitPos.y + Random.Range(-spawnRange, spawnRange), 0f ); Instantiate(stonedropling, spawnPos, Quaternion.Euler(0, 0, Random.Range(0f, 360f))); } } }
方法二:精准获取碰撞瓦片的中心位置(适合严格限定在瓦片范围内生成的场景)
如果需要确保拾取物生成在碰撞瓦片的中心附近,可通过Tilemap的坐标转换方法实现:
using UnityEngine; using UnityEngine.Tilemaps; public class Drops : MonoBehaviour { public GameObject wooddropling; public GameObject stonedropling; public float spawnRange = 3f; void OnCollisionEnter2D(Collision2D col) { Tilemap tilemap = col.gameObject.GetComponent<Tilemap>(); if (tilemap == null) return; // 将碰撞接触点转换为Tilemap的单元格坐标 Vector2 hitPos = col.contacts[0].point; Vector3Int cellPos = tilemap.WorldToCell(hitPos); // 获取该瓦片的中心世界坐标 Vector3 tileCenter = tilemap.GetCellCenterWorld(cellPos); if (col.gameObject.CompareTag("trees")) { Vector3 spawnPos = new Vector3( tileCenter.x + Random.Range(-spawnRange, spawnRange), tileCenter.y + Random.Range(-spawnRange, spawnRange), 0f ); Instantiate(wooddropling, spawnPos, Quaternion.Euler(0, 0, Random.Range(0f, 360f))); } else if (col.gameObject.CompareTag("stones")) { Vector3 spawnPos = new Vector3( tileCenter.x + Random.Range(-spawnRange, spawnRange), tileCenter.y + Random.Range(-spawnRange, spawnRange), 0f ); Instantiate(stonedropling, spawnPos, Quaternion.Euler(0, 0, Random.Range(0f, 360f))); } } }
额外提示
- 优先使用
CompareTag()替代直接用==比较标签,既能提升性能,也能避免拼写错误导致的Bug - 若碰撞存在多个接触点,可根据需求选择首个接触点或遍历所有接触点
- 将随机范围设为公开变量,无需修改代码就能在编辑器中调整生成范围
内容的提问来源于stack exchange,提问作者Ted Hutter
相关产品推荐
相关产品推荐

