首页 > 解决方案 > 实例化 GameObjects 并在它撞到地面时更改材质

问题描述

有一个代码用于将立方体实例化到列表中,并在每个克隆击中地面时更改其材质

以下代码有效,但不适用于Real-Time更新函数的作用类似于Foreach方法的Start函数

如何 在实时更新函数中获取item.transform.position.y的值?

public GameObject cubePrefab;
public Material RedMat;
public float GroudLevel = 0.5f;

void Update()
{
    if (Input.GetMouseButtonDown(0))
    { 
         List<GameObject> cloneList = new List<GameObject>();
         //instantiate clones into the list
         for (int i = 0; i < 10; i++)
         {
            var clone = Instantiate (cubePrefab,new Vector3(Random.Range(-3f, 3f),
            Random.Range(4f, 10.5f),Random.Range(-3f, 3f)), Quaternion.identity);
            cloneList.Add(clone);
         }

         //if clone is grounded change a Material for each clone
         foreach (var item in cloneList)
         {
            //Debug.Log(item.transform.position.y);

            //check if clone is on the ground
            if(item.transform.position.y < GroudLevel)
            {
             item.GetComponent<Renderer>().material = RedMat;
            }
            
        }  

    }
}

有一个GroudLevel = 7的屏幕截图

在此处输入图像描述

标签: unity3d

解决方案


这个函数不起作用的原因是transform.position你的 item 的 pivot() 总是在 object 的中心。这不是您可以在 Unity 中更改的内容(您也不一定想要)。

最重要的是,当您使用insteaad of时,您正在检查项目是否地下,而不是在地下,因为位置需要小于才能返回 true。<<=groundLevel

这里有几种解决方案。

最简单的方法是将所有这些逻辑转移到OnCollisionEnterorOnTriggerEnter方法中。有关这方面的更多信息,请查看Unity 文档

另一种解决方案是找到对象大小的方法,将其除以二,然后检查是否

item.transform.position - halfSize <= groundLevel; 

然而,这看起来确实很麻烦而且过于复杂。除非你有理由不这样做,否则你最好使用 Unity 的内置碰撞系统。


推荐阅读