【问题标题】:Make objects between camera and character transparent使相机和角色之间的对象透明
【发布时间】:2026-01-10 04:05:02
【问题描述】:

我正在为我的相机编写一个脚本,以使自身和角色之间的对象透明。

我设法让它与 RayCast 一起工作,但是我不知道如何在物体逃离光线后重新建立 alpha 值。

这是我当前的代码:

private void XRay() {
    float characterDistance = Vector3.Distance(transform.position, GameObject.Find("Character").transform.position);
    Vector3 fwd = transform.TransformDirection(Vector3.forward);

    RaycastHit hit;
    if (Physics.Raycast(transform.position, fwd, out hit, characterDistance)) {

        // Add transparence
        Color color = hit.transform.gameObject.renderer.material.color;
        color.a = 0.5f;
        hit.transform.gameObject.renderer.material.SetColor("_Color", color);
    }
}

【问题讨论】:

    标签: unity3d rendering


    【解决方案1】:

    这是我的最终代码。请注意,它一次只使一个对象透明,但使用 RaycastAll 并为 oldHits 使用数组可以轻松完成相同的实现。

    public class Camara : MonoBehaviour {
        RaycastHit oldHit;
    
        // Use this for initialization
        void Start () {
    
        }
    
        // Update is called once per frame
        void Update () {
    
        }
    
        void FixedUpdate() {
            XRay ();
        }
    
        // Hacer a los objetos que interfieran con la vision transparentes
        private void XRay() {
    
            float characterDistance = Vector3.Distance(transform.position, GameObject.Find("Character").transform.position);
            Vector3 fwd = transform.TransformDirection(Vector3.forward);
    
            RaycastHit hit;
            if (Physics.Raycast(transform.position, fwd, out hit, characterDistance)) {
                if(oldHit.transform) {
    
                    // Add transparence
                    Color colorA = oldHit.transform.gameObject.renderer.material.color;
                    colorA.a = 1f;
                    oldHit.transform.gameObject.renderer.material.SetColor("_Color", colorA);
                }
    
                // Add transparence
                Color colorB = hit.transform.gameObject.renderer.material.color;
                colorB.a = 0.5f;
                hit.transform.gameObject.renderer.material.SetColor("_Color", colorB);
    
                // Save hit
                oldHit = hit;
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      我确实将这个脚本附加到我跟随播放器的简单相机上。它可能会帮助你。 它实际上可以管理不止一个阻碍视图,而且你看到我传递了一个掩码,我用它的名称作为目标,而不是检查对撞机名称标签。玩得开心。

      using UnityEngine;
      
      public class followPlayer : MonoBehaviour
      {
          public Transform player;
          public Vector3 offset;
          public Transform[] obstructions;
      
          private int oldHitsNumber;
      
          void Start()
          {
              oldHitsNumber = 0;
          }
      
          private void LateUpdate()
          {
              viewObstructed();
          }
      
          void Update()
          {
              transform.position = player.TransformPoint(offset);
              transform.LookAt(player);
          }
      
          void viewObstructed()
          {
              float characterDistance = Vector3.Distance(transform.position, player.transform.position);
              int layerNumber = LayerMask.NameToLayer("Walls");
              int layerMask = 1 << layerNumber;
              RaycastHit[] hits = Physics.RaycastAll(transform.position, player.position - transform.position, characterDistance, layerMask);
              if (hits.Length > 0)
              {   // Means that some stuff is blocking the view
                  int newHits = hits.Length - oldHitsNumber;
      
                  if (obstructions != null && obstructions.Length > 0 && newHits < 0)
                  {
                      // Repaint all the previous obstructions. Because some of the stuff might be not blocking anymore
                      for (int i = 0; i < obstructions.Length; i++)
                      {
                          obstructions[i].gameObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
                      }
                  }
                  obstructions = new Transform[hits.Length];
                  // Hide the current obstructions 
                  for (int i = 0; i < hits.Length; i++)
                  {
                      Transform obstruction = hits[i].transform;
                      obstruction.gameObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
                      obstructions[i] = obstruction;
                  }
                  oldHitsNumber = hits.Length;
              }
              else
              {   // Mean that no more stuff is blocking the view and sometimes all the stuff is not blocking as the same time
                  if (obstructions != null && obstructions.Length > 0)
                  {
                      for (int i = 0; i < obstructions.Length; i++)
                      {
                          obstructions[i].gameObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
                      }
                      oldHitsNumber = 0;
                      obstructions = null;
                  }
              }
          }
      }
      
      

      【讨论】: