[Unity学习教程] Unity实现遮挡人物的停滞物体设为透明,并在不遮挡时规复的个人办理方法

[复制链接]
查看1116 | 回复0 | 2023-8-23 11:58:34 | 显示全部楼层 |阅读模式 来自 中国北京
   思路:通过摄像机向人物发射射线,检测第一个碰到的物体是否为人物。如果不是人物,那么就判断为停滞,将其透明度设为0.2,并将其添参加一个GameObject数组中。当射线检测到第一个物体是人物时,将这个GameObject数组中的全部物体透明度规复为1,并清空这个数组。
PS:  此脚本挂载于 摄像机上,我省略了跟随移动的代码段 等
PS-2: 用此方法改变材质的透明度,不需要额外新建材质。由于好像在人物被遮挡时,停滞物会天生一个Instance材质实例更换之前的材质。因此不会出现改变单个物体的材质透明度时,导致别的共用此材质的物体都变透明的题目。
PS-3: 若材质的渲染模式(Renderer Mode)为Opaque时,出现更改A值透明度不发生变化的题目,则可以把渲染模式(Renderer Mode)改为Transparent(透明)[这个大概是Albedo贴图的题目,少了A通道?]
PS-4: 需要遮挡物带有碰撞器组件。我碰到的题目是:当停滞物有网格碰撞器组件时,才能透明;如果不带有网格碰撞器(或者别的碰撞器),那么就无法改变透明度
PS-5:迩来又看到了用shader实现的方法,不知道和用代码调解哪个对性能影响更大
  1.     public Transform player;
  2.     RaycastHit HitInfo;
  3.     List<GameObject> TransparentObjects = new List<GameObject>();
  4.     void Update()
  5.     {
  6.         SetTrans();
  7.     }
  8.     private void SetTrans()
  9.     {
  10.         Vector3 Direction = player.position - transform.position;//射线方向为摄像头指向人物
  11.         RaycastHit[] hits;
  12.         
  13.         if (Physics.Raycast(transform.position,Direction,out HitInfo))
  14.         {
  15.             if (HitInfo.transform.tag != "Player")//若人物被遮挡了
  16.             {
  17.                 hits = Physics.RaycastAll(transform.position, Direction, 100f,1<< LayerMask.NameToLayer("Default"));//只检测Default图层的物体,其它图层检测不到
  18.                 for (int i = 0; i < hits.Length; i++)
  19.                 {
  20.                     var hit = hits[i];
  21.                     if (hit.transform.tag == "Player")
  22.                     {
  23.                         return;
  24.                     }
  25.                     else
  26.                     {
  27.                         ClearTransparentObjects();
  28. 首先先将透明物体全部恢复,不然会出现人物持续被遮挡时,多个物体全部变成透明的问题。
  29. 也就是说,只能将挡在人物前面的首个物体透明。如果人物前面有多个物体遮挡,这句语句可以删掉或进行调整
  30.                         if (hit.transform.GetComponent<MeshRenderer>())//若障碍物带有碰撞器组件
  31.                         {
  32.                             if(hit.transform.GetComponent<MeshRenderer>().material.color.a != 0.2f)//若障碍物的透明度不为0.2
  33.                             {
  34.                                 var ChangeColor = hit.transform.GetComponent<MeshRenderer>().material.color;
  35.                                 ChangeColor.a = 0.2f;
  36.                                 SetMaterialRenderingMode(hit.transform.GetComponent<MeshRenderer>().material, RenderingMode.Transparent);
  37.                                 hit.transform.GetComponent<MeshRenderer>().material.color = ChangeColor;
  38.                                 TransparentObjects.Add(hit.transform.gameObject);//将透明物体添加到数组中
  39.                                 Debug.Log("射线检测到的物体名为:" + hit.transform.name);
  40.                             }                       
  41.                         }
  42.                         
  43.                     }
  44.                 }
  45.             }
  46.             else//若人物没有被遮挡
  47.             {
  48.                 ClearTransparentObjects();
  49.             }
  50.             
  51.         }
  52.         
  53.     }
  54.     void ClearTransparentObjects()//将透明物体恢复不透明
  55.     {
  56.         if (TransparentObjects != null)
  57.         {
  58.             for (int i = 0; i < TransparentObjects.Count; i++)
  59.             {
  60.                 var ChangeColor = TransparentObjects[i].transform.GetComponent<MeshRenderer>().material.color;
  61.                 ChangeColor.a = 1f;
  62.            
  63.                 TransparentObjects[i].transform.GetComponent<MeshRenderer>().material.color = ChangeColor;
  64.             }
  65.             TransparentObjects.Clear();//清除数组
  66.         }
  67.     }
复制代码


来源:https://blog.csdn.net/qianhang120/article/details/128145939
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则