方法在onGUI()方法内部不起作用

时间:2019-06-26 06:01:39

标签: c# unity3d

我想做的事情是编写一个可以在onGUI()方法中调用的方法。

我写了这个方法。但是,当我运行程序时,方法没有显示效果。

    private void ShowSubPartsOnClick(float x, float y, float widthLABEL, float heigth, HumanBodyPart bodyPart)
    {

        x = x + 14;

        for(int i = 0; i < bodyPart.SubParts.Count; i++)
        {

            y = y + 14;
            GUI.Label(new Rect(x+14,y,widthLABEL,heigth), bodyPart.SubParts[i].EnglishTitle);

            if(GUI.Button(new Rect(x, y, 14, heigth),"+"))
            {
                ShowSubPartsOnClick(x, y, widthLABEL, heigth, bodyPart.SubParts[i]);
            }
        }
    }

}


  private void OnGUI()
    {
        GUI.Label(new Rect(text.transform.position.x+14, text.transform.position.y, text.rectTransform.sizeDelta.x, 14),bodyVisualizer.BodyData.Body.SubParts[0].EnglishTitle);

        if(GUI.Button(new Rect(text.transform.position.x, text.transform.position.y, 14, 14), "+"))
        {
            ShowSubPartsOnClick(text.transform.position.x, text.transform.position.y, text.rectTransform.sizeDelta.x, 14, bodyVisualizer.BodyData.Body.SubParts[0]);
        }


    }


如何解决此问题或有什么问题?

1 个答案:

答案 0 :(得分:2)

这里面临的挑战是必须从GUI.Label直接调用GUI.ButtonOnGUI之类的函数才能正常工作:

  

From Unity Forums:“唯一可以绘制/创建GUI元素的地方是从OnGUI函数内部触发它们。”

鉴于那里的建议,一种解决方案是通过while循环运行深度优先的迭代搜索。参见所附示例。

话虽如此,我强烈建议使用Unity Canvas而不是OnGUI。它功能强大得多,并且其编程逻辑并不局限于单个函数。

OnGUI代码段

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class HumanBodyPart
{
    public string EnglishTitle;
    public List<HumanBodyPart> SubParts;
    public bool IsExpanded;
    public int DrawDepth;

    public HumanBodyPart(string title, HumanBodyPart[] subParts)
    {
        this.EnglishTitle = title;
        this.SubParts = new List<HumanBodyPart>();
        this.SubParts.AddRange(subParts);
        this.IsExpanded = false;
        this.DrawDepth = 0;
    }
}

public class Script : MonoBehaviour 
{
    [SerializeField]
    Text text;
    HumanBodyPart mainBodyPart;

    private void Start()
    {
        HumanBodyPart subSubSubBodyPart = new HumanBodyPart("SubSubSubBodyPart", new HumanBodyPart[] { });
        HumanBodyPart subSubBodyPart1 = new HumanBodyPart("SubSubBodyPart1", new HumanBodyPart[] { subSubSubBodyPart });
        HumanBodyPart subSubBodyPart2 = new HumanBodyPart("SubSubBodyPart2", new HumanBodyPart[] { });
        HumanBodyPart subBodyPart = new HumanBodyPart("SubBodyPart", new HumanBodyPart[] { subSubBodyPart1, subSubBodyPart2});
        mainBodyPart = new HumanBodyPart("BodyPart", new HumanBodyPart[] { subBodyPart });
        UpdateDrawDepths(mainBodyPart);
    }

    private void UpdateDrawDepths(HumanBodyPart currentBodyPart, int currentDrawDepth=0)
    {
        currentBodyPart.DrawDepth = currentDrawDepth;
        foreach (HumanBodyPart bodyPart in currentBodyPart.SubParts)
        {
            UpdateDrawDepths(bodyPart, currentDrawDepth + 1);
        }
    }

    private void OnGUI()
    {
        float spacing = 30;
        float x = text.transform.position.x + spacing;
        float y = text.transform.position.y;
        int drawDepth = 0;
        List<HumanBodyPart> nextPartsToRender = new List<HumanBodyPart>(new HumanBodyPart[] { mainBodyPart });
        while (nextPartsToRender.Count > 0)
        {
            HumanBodyPart currentPart = nextPartsToRender[0];
            GUI.Label(new Rect(currentPart.DrawDepth * spacing + x, y, 200, 20), currentPart.EnglishTitle);
            nextPartsToRender.RemoveAt(0);
            if (GUI.Button(new Rect(x - spacing + currentPart.DrawDepth * spacing, y, 20, 20), "+"))
            {
                currentPart.IsExpanded = true;
            }
            if (currentPart.IsExpanded)
            {
                nextPartsToRender.InsertRange(0, currentPart.SubParts);
            }
            y += spacing;
        }
    }
}

example code UI expanded