我是 Unity 新手,在预制件上使用 Raycast 时遇到问题。 更具体地说,我想要做的是使用脚本 A 随机生成 10 个预制件,然后我使用脚本 B,在那里我使用 Raycast 命中这些对象。 脚本 A 和脚本 B 使用具有相同预制件的 SerializeField 来知道要生成哪个对象(脚本 A)以及命中哪个对象(脚本 B)。 问题是 Raycast 无法将实例化识别为在 SerializeField 中分配的 GameObject,因此当我点击实例化时什么也没有发生。 我的代码是:
脚本 A
{
[SerializeField]
GameObject coin, floor, house;
public GameObject mushSpawn;
Quaternion rot = Quaternion.Euler(Vector3.zero);
public GameObject coinInstance;
void Start()
{
Vector3 center = floor.GetComponent<MeshRenderer>().bounds.center;
Vector3 size = floor.GetComponent<MeshRenderer>().bounds.size;
Vector3 centerHouse = house.GetComponent<MeshRenderer>().bounds.center;
Vector3 sizeHouse = house.GetComponent<MeshRenderer>().bounds.size;
float posX = (center.x - (size.x / 2)) + 2;
float posZ = (center.z - (size.z / 2)) + 2;
float posHouseX = (centerHouse.x - (sizeHouse.x / 2));
float posHouseZ = (centerHouse.z - (sizeHouse.z / 2));
for (int i = 0; i <= 10; i++)
{
{
Vector3 position = new Vector3(posXSpawn, 0.0f, posZSpawn);
mushSpawn = Instantiate(coin, position, rot) as GameObject;
}
}
}
}
脚本 B
public class GazeSysten : MonoBehaviour
{
[SerializeField]
GameObject coin, buttonMove, buttonTake, pointer, floor, buttonEnding;
public Camera cam;
private Vector3 position;
private Color active = Color.green;
private Color noActive = Color.red;
private void Start()
{
pointer.GetComponent<MeshRenderer>().material.color = noActive;
position = this.transform.position;
}
private void Update()
{
this.transform.position = position;
RaycastHit hit;
Ray lastPosition = cam.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(lastPosition, out hit))
{
pointer.GetComponent<MeshRenderer>().material.color = active;
}
else
{
pointer.GetComponent<MeshRenderer>().material.color = noActive;
}
if (Input.GetMouseButtonDown(0))
{
if(Physics.Raycast(lastPosition, out hit))
{
if(hit.transform.gameObject == coin)
{
Debug.Log("Is a coin");
}
}
}
}
}
如果在场景中我将实例化的对象拖动到脚本 B 的 SerializeObject 插槽中,代码有效,有人可以帮助我吗?
答案 0 :(得分:1)
coin
预制件的实例(克隆)!= coin
预制件引用本身。它们根本不相等,而是两个不同的对象...
宁愿给它一个 Tag 并检查 hit.gameObject.CompareTag
if (Physics.Raycast(lastPosition, out hit))
{
pointer.GetComponent<MeshRenderer>().material.color = active;
if(hit.gameObject.CompareTag("Coin"))
{
Debug.Log("Is a coin");
}
}
else
{
pointer.GetComponent<MeshRenderer>().material.color = noActive;
}
或者给它一个特定的组件,例如
public class Coin : MonoBehaviour { }
并检查 TryGetComponent
喜欢
if (Physics.Raycast(lastPosition, out hit))
{
pointer.GetComponent<MeshRenderer>().material.color = active;
if(hit.gameObject.TryGetComponent<Coin>(out var hitCoin))
{
Debug.Log("Is a coin", hitCoin);
}
}
else
{
pointer.GetComponent<MeshRenderer>().material.color = noActive;
}
是的,当然你可以在产卵时这样做
var coinInstance = Instantiate (coinPrefab, ...);
coinInstance.name = "Coín";
然后检查
if(hit.gameObject.name == "Coin")
但通常按字符串操作容易出错且效率较低