break prefab instance的原理

prefab可无限apply:

如果把一个模块做成了prefab,这个prefab可能在同一个scene中添加多个,甚至添加到了多个scene中。设所有这些实例为instance(1),instance(2),...,instance(n),那么我们应该保证对于任何一个instance(i)来说,对它点apply都不会对工程造成任何影响。那么假如做不到这一点,那么或把prefab及其中引用的资源完全拷贝一份做成一个新的prefab,或者直接break prefab instance使其成为独立节点

转载于:https://www.cnblogs.com/timeObjserver/p/6251499.html

你别乱改,using System.Collections.Generic; using UnityEngine; using UnityEngine.Tilemaps; namespace gridstudy { public class GridManager : MonoBehaviour { [SerializeField] private GridConfig _config; [SerializeField] private Tilemap _terrainTilemap; [SerializeField] private TileBase _defaultTile; private GridCell[,] _gridData; private Dictionary<Vector2Int, List<GridObject>> _objectsMap = new(); private Dictionary<GridObjectType, GameObject> _prefabMap; public int GridWidth => _gridData?.GetLength(0) ?? 0; public int GridHeight => _gridData?.GetLength(1) ?? 0; public GridConfig Config => _config; void Awake() { // 初始化prefab映射 _prefabMap = new Dictionary<GridObjectType, GameObject> { { GridObjectType.Terrain, _config.TerrainPrefab }, { GridObjectType.Structure, _config.StructurePrefab }, { GridObjectType.Chess, _config.ChessPrefab }, { GridObjectType.Token, _config.TokenPrefab } }; } public void GenerateGrid(int width, int height) { _gridData = new GridCell[width, height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { _gridData[x, y] = new GridCell(new Vector2Int(x, y)); Vector3Int tilePos = new Vector3Int(x, y, 0); _terrainTilemap.SetTile(tilePos, _defaultTile); } } } public GridCell GetCellData(Vector2Int coord) { if (coord.x < 0 || coord.x >= GridWidth || coord.y < 0 || coord.y >= GridHeight) { Debug.LogWarning($"Invalid coordinate: {coord}"); return null; } return _gridData[coord.x, coord.y]; } public CustomTile GetTileAtPosition(Vector2Int gridPos) { GridCell cell = GetCellData(gridPos); if (cell == null || cell.terrain == null) return null; TerrainConfig config = _config.GetTerrainConfig(cell.terrain.type); return config?.tile; } public void PlaceObject<T>(GridObjectType type, Vector2Int gridPos, T data) where T : ScriptableObject { if (!_prefabMap.TryGetValue(type, out GameObject prefab)) { Debug.LogError($"No prefab found for type: {type}"); return; } // 验证坐标有效性 GridCell cell = GetCellData(gridPos); if (cell == null) { Debug.LogError($"Invalid grid position: {gridPos}"); return; } GameObject instance = Instantiate(prefab, GridToWorld(gridPos), Quaternion.identity); GridObject gridObject = instance.GetComponent<GridObject>(); if (gridObject == null) { Debug.LogError($"Prefab for {type} is missing GridObject component"); Destroy(instance); return; } gridObject.GridPosition = gridPos; // 更新数据层 switch (type) { case GridObjectType.Terrain: cell.terrain = data as TerrainData; var terrainObj = instance.GetComponent<TerrainObject>(); if (terrainObj != null) { TerrainConfig config = _config.GetTerrainConfig(cell.terrain.type); terrainObj.Initialize(cell.terrain, config?.Sprite); } UpdateTileAtPosition(gridPos,config?.tile); break; case GridObjectType.Structure: cell.structure = data as StructureData; break; case GridObjectType.Chess: cell.chess = data as ChessData; break; case GridObjectType.Token: cell.tokens.Add(data as TokenData); break; default: Debug.LogError($"Unhandled object type: {type}"); break; } // 更新对象映射 if (!_objectsMap.ContainsKey(gridPos)) _objectsMap[gridPos] = new List<GridObject>(); _objectsMap[gridPos].Add(gridObject); // 触发对象放置事件 gridObject.OnPlaced(); } // 添加 Tilemap 更新方法 private void UpdateTileAtPosition(Vector2Int gridPos, CustomTile tile) { if (_terrainTilemap == null) return; Vector3Int tilePos = new Vector3Int(gridPos.x, gridPos.y, 0); _terrainTilemap.SetTile(tilePos, tile); } // 坐标转换(网格坐标->世界坐标) private Vector3 GridToWorld(Vector2Int gridPos) { return new Vector3(gridPos.x + 0.5f, gridPos.y + 0.5f, 0); } } }从这个开始,只把功能修改好,其他的别做,上一次生成作废
最新发布
07-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值