【问题标题】:How can I select a unit in Unity and activate the Canvas on that unit?如何在 Unity 中选择一个单元并激活该单元上的画布?
【发布时间】:2020-11-03 13:09:57
【问题描述】:

我目前正在开发一款回合制策略游戏,我想为玩家提供他们获得的每个单位的更多信息。

代码如下:

    public void UnitSelection ()
    {
        Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
        RaycastHit hit;
        if (Physics.Raycast (ray, out hit, Mathf.Infinity))
        {
            if (hit.collider.tag == "Unit Player 1")
            {
                // How can I select the Canvas from here + Canvas.SetActive(true)
            }
        }
    }

我可以用鼠标选择一个单位,但我不知道如何到达该游戏对象上的画布。 我应该使用标签(这不是不好的做法吗?)还是使用其他方法?

如果您需要更多信息,请将其写在评论中。我会添加你需要的一切。

提前致谢。

【问题讨论】:

    标签: unity3d user-interface canvas


    【解决方案1】:

    假设hit.colliderCanvas 的父对象ArmoredBear_a06,您可以使用GetComponentInChildren

    public void UnitSelection ()
    {
        if (Physics.Raycast (Camera.main.ScreenPointToRay(Input.mousePosition), out var hit, Mathf.Infinity))
        {
            var hitCollider = hit.collider;
    
            if (hitCollider.CompareTag("Unit Player 1"))
            {
                // pass in true to also get inactive or disabled components
                var canvas = hitCollider.GetComponentInChildren<Canvas>(true);
    
                if(!canvas)
                {
                    Debug.LogWarning($"Hitting {hitCollider.name} but no Canvas found in children"); 
                    return;
                }
    
                canvas.gameObject.SetActive(true);
            }
        }
    }
    

    或者,如果您知道 Canvas 始终是您可以使用的第一个子元素transform.GetChild

    public void UnitSelection ()
    {
        if (Physics.Raycast (Camera.main.ScreenPointToRay(Input.mousePosition), out var hit, Mathf.Infinity))
        {
            var hitCollider = hit.collider;
    
            if (hitCollider.CompareTag("Unit Player 1"))
            {
                var canvas = hitCollider.tramsform.GetChild(0);
    
                canvas.gameObject.SetActive(true);
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      您有多种选择来获取画布。

      首先

      像这样直接获取 Canvas(如果在根对象上有碰撞器):

      public void UnitSelection ()
      {
         Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
         RaycastHit hit;
         if (Physics.Raycast (ray, out hit, Mathf.Infinity))
         {
            if (hit.collider.tag == "Unit Player 1")
            {
               Canvas canv = hit.collider.GetComponentInChildren<Canvas>(true);
               canv.gameObject.SetActive(true);
               //or you can change only canvas state like this canv.enabled = true;
            }
         }
      }
      

      第二:

      或者您可以将脚本附加到您的单元并更改 Canvas 内部的状态: 部分机器人脚本:

      public class Bot : MonoBehaviour
      {
          [SerializeField] private GameObject canvasObject;
      
          public void ChangeStateCanvas(bool state)
          {
              canvasObject.SetActive(state);
          }
      }
      

      改变画布状态的脚本:

      public void UnitSelection ()
      {
         Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
         RaycastHit hit;
         if (Physics.Raycast (ray, out hit, Mathf.Infinity))
         {
            if (hit.collider.tag == "Unit Player 1")
            {
               hit.collider.GetComponent<Bot>().ChangeStateCanvas(true);
            }
         }
      }
      

      【讨论】:

      • 第一次会失败。请参阅my answer:您需要传入true 才能找到非活动或禁用的组件。第二个是有效的,但有点矫枉过正;)
      猜你喜欢
      • 2020-06-07
      • 2017-01-08
      • 2020-02-12
      • 2022-07-09
      • 1970-01-01
      • 1970-01-01
      • 2018-06-24
      • 1970-01-01
      • 2014-05-08
      相关资源
      最近更新 更多