Unity中如何给实例化的Prefab设置随机名称?建筑系统删除问题求助
解决方案
问题根源
你删除物体时用了GameObject.Find(RaycastReturn),但所有从同一个Prefab实例化的物体默认名称完全相同,GameObject.Find会返回场景中第一个匹配该名称的物体,导致误删逻辑错误。实际上根本不需要通过名称查找目标——射线已经直接命中了你要删除的物体,直接操作命中对象即可。
修复步骤
简化删除逻辑
删掉删除代码里的RaycastReturn赋值和GameObject.Find调用,直接销毁射线命中的hit.collider.gameObject:if(Input.GetKeyDown(KeyCode.L)) // 改用GetKeyDown,避免按住L持续触发销毁 { if(Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, 20)) { if (hit.collider.gameObject.CompareTag("buildi")) // 用CompareTag更高效,还能避免拼写错误静默失败 { Destroy(hit.collider.gameObject); } } }(可选)给实例化物体设置唯一名称
如果确实需要给每个建筑实例设置唯一名称,可以在Instantiate后直接修改:if (Input.GetKeyDown(KeyCode.Mouse0)) { GameObject newBuilding = Instantiate(BuildingPrefab, hit.point, Building.transform.rotation); // 方案1:用静态计数器生成唯一名称 private static int buildingCount = 0; newBuilding.name = $"Building_{buildingCount++}"; // 方案2:用随机数生成唯一名称 // newBuilding.name = $"Building_{Random.Range(1000, 9999)}"; }
额外优化建议
- 替换所有
hit.collider.gameObject.tag == "xxx"为hit.collider.gameObject.CompareTag("xxx"),性能更优且容错性更强。 - 移除冗余变量
RaycastReturn和FoundObject,当前逻辑完全用不到它们。 - 不要直接修改
BuildingPrefab的旋转(BuildingPrefab.transform.Rotate(...)),这会改动Project面板里的原始Prefab,只需修改预览用的Building对象旋转,实例化时继承它的旋转即可。
修改后的完整代码示例:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class building : MonoBehaviour { public GameObject Building; public GameObject BuildingPrefab; bool BuildingModeOn; RaycastHit hit; private static int buildingCount = 0; // 用于生成唯一名称的计数器 void Start() { } void Update() { if(BuildingModeOn) { Building.SetActive(true); if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, 20)) { Building.transform.position = hit.point; if (hit.collider.gameObject.CompareTag("ground") || hit.collider.gameObject.CompareTag("buildi")) { if (Input.GetKeyDown(KeyCode.Mouse0)) { GameObject newBuilding = Instantiate(BuildingPrefab, hit.point, Building.transform.rotation); newBuilding.name = $"Building_{buildingCount++}"; // 设置唯一名称 } } } } else { Building.SetActive(false); } if (Input.GetKeyDown(KeyCode.B)) { BuildingModeOn = true; } if (Input.GetKeyDown(KeyCode.X)) { BuildingModeOn = false; } if(Input.GetKeyDown(KeyCode.R)) { // 只修改预览物体的旋转,不改动原始Prefab Building.transform.Rotate(0, 90f, 0); } if(Input.GetKeyDown(KeyCode.L)) { if(Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, 20)) { if (hit.collider.gameObject.CompareTag("buildi")) { Destroy(hit.collider.gameObject); } } } } }
内容的提问来源于stack exchange,提问作者Luca Roverati
相关产品推荐
相关产品推荐

