3D House Prefab无论重叠与否都不会变成透明的红色或绿色

问题描述 投票:0回答:1

我有一个建筑放置项目,不适用于 3D 房屋对象。这些对象都具有刚体和盒子碰撞器组件,而只有房屋预制对象具有子对象。 我的脚本是这样的:

BuildingManager 脚本:

public class BuildingManager : MonoBehaviour
{
      private GameObject pendingObject;
      [SerializeField] private Material[] materials;
      public bool canPlace;

void Update()
{
     if (pendingObject != null)
     {
         UpDateMaterials();
          
      pendingObject.transform.position = pos;

         if (Input.GetMouseButtonDown(0) && canPlace)
         {
             PlaceObject();
         }
     }
}

public void PlaceObject()
{
     pendingObject.GetComponent<MeshRenderer>().material = materials[2];
     pendingObject = null;
}

public void UpDateMaterials()
{
     if (canPlace)
     {
         pendingObject.GetComponent<MeshRenderer>().material = materials[0];
     
     }
     if (!canPlace)
     {
         pendingObject.GetComponent<MeshRenderer>().material = materials[1];
     
     }
}
}

检查放置脚本:

public class CheckPlacement : MonoBehaviour
{
    BuildingManager buildingManager;

    void Start()
    {
        buildingManager = GameObject.Find("BuildingManager").GetComponent<BuildingManager>();
    }

   private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("Building"))
        {
            Debug.Log("Can't Place Building");
            buildingManager.canPlace = false;
        }
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.gameObject.CompareTag("Building"))
        {
            Debug.Log("Can Place Building");
             buildingManager.canPlace = true;
       }
    }
}

这些脚本可以很好地与 Unity 的默认 3D 对象配合使用,例如 3D 胶囊、球体、盒子对象。例如,我尝试将胶囊对象与已经在地面(平面)上的房屋对象重叠。当胶囊对象与房屋对象碰撞时,它会变成透明的红色,当我将它拖到地面时,它会变成透明的绿色。

欢迎任何建议...

unity-game-engine object prefab
1个回答
0
投票

由于房屋对象有多个子对象,因此您需要更新所有网格渲染器。为此,请使用 GetComponentsInChildren 获取所有网格渲染器,并在更改材质时循环遍历这些渲染器。如果对象没有改变,您可以缓存网格渲染器以避免多次调用 GetComponents。您还可以添加待处理状态,这样就可以避免每帧更新材质,即使它们没有更改状态。我将排除该部分,因为它需要一些解释,并且可能会使这个答案变得复杂。

private MeshRenderer[] meshRenderers;

private void Awake()
{
    meshRenderers = pendingObject.GetComponentsInChildren<MeshRenderer>();
}
...

private void UpdateMaterials()
{
    if (canPlace)
    {
        UpdateMeshRenderersMaterial(materials[0]);
    }
    else
    {
        UpdateMeshRenderersMaterial(materials[1]);
    }
}
private void PlaceObject()
{
    UpdateMeshRenderersMaterial(materials[2]);
}
private void UpdateMeshRenderersMaterial(Material material)
{
    foreach (var meshRenderer in meshRenderers)
    {
        meshRenderer.material = material;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.