光线投射不适用于 Unity 中的预制件

时间:2021-04-28 17:03:22

标签: c# unity3d

我是 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 插槽中,代码有效,有人可以帮助我吗?

1 个答案:

答案 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")

但通常按字符串操作容易出错且效率较低