【问题标题】:raycast doesn't work with prefabs in Unityraycast 不适用于 Unity 中的预制件
【发布时间】:2021-04-28 17:03:22
【问题描述】:

我是 Unity 新手,在 Prefab 上使用 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 插槽中,代码有效,有人可以帮助我吗?

【问题讨论】:

  • 在这种情况下您建议做什么?如何访问实例?
  • (双光线投射是我的错误)

标签: c# unity3d


【解决方案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")

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

【讨论】:

  • 我可以更改克隆的名称并使用 hit.gameObject.name = "clone name" 访问吗?还是坏习惯?
  • 使用字符串总是可行的,但容易出错且速度很慢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-30
  • 1970-01-01
  • 2020-11-03
相关资源
最近更新 更多