从脚本中创建Unity UI控件

12

我通过代码创建了一个切换按钮,但它无法显示。此外,我无法更改文本字段的位置。我尝试了很多方法,但都不起作用。这是我的当前版本,也许你能看出错误所在。

我是Unity的新手,这非常困难。

public class Game : MonoBehaviour 
{

    public GameObject canvas;

    void Start () 
    {
        GameObject newGO = new GameObject("myTextGO");
        newGO.transform.SetParent(this.transform);
        newGO.transform.position = new Vector3(0, 0, 0);

        Text myText = newGO.AddComponent<Text>();
        myText.text = "Ta-dah!";
        Font ArialFont =  
           (Font)Resources.GetBuiltinResource(typeof(Font),"Arial.ttf");
        myText.font = ArialFont;
        myText.material = ArialFont.material;
        myText.color = Color.black;
        myText.transform.position = new Vector3(0, 10, 0);

        GameObject secGO = new GameObject("myGO");
        secGO.transform.SetParent(this.transform);
        Toggle myToggle = secGO.AddComponent<Toggle>();
        myToggle.isOn = true;
        myToggle.transform.position = new Vector3(10, 10, 0);
    }
}
1个回答

19
你应该将Toggle作为Canvas的子级。在你的代码中没有这样做。另外,你移动了一个UI组件和GameObject,使用的是newGO.GetComponent<RectTransform>().anchoredPosition3D而不是newGO.transform.position
在Unity中创建完整UI控件的方法有三种:
1. 使用DefaultControls API生成它(简单且推荐)
使用DefaultControls类,Unity会创建所提供的UI,然后返回UI的父级。这是最简单和推荐的方法。它以DefaultControls.Resources作为参数,这样您就可以在创建默认UI控件时提供要使用的精灵。
public GameObject canvas;
void Start()
{
    DefaultControls.Resources uiResources = new DefaultControls.Resources();
    //Set the Button Background Image someBgSprite;
    uiResources.standard = someBgSprite;
    GameObject uiButton = DefaultControls.CreateButton(uiResources);
    uiButton.transform.SetParent(canvas.transform, false);
}

切换:

public GameObject canvas;
void Start()
{
    DefaultControls.Resources uiResources = new DefaultControls.Resources();
    //Set the Toggle Background Image someBgSprite;
    uiResources.background = someBgSprite;
    //Set the Toggle Checkmark Image someCheckmarkSprite;
    uiResources.checkmark = someCheckmarkSprite;
    GameObject uiToggle = DefaultControls.CreateToggle(uiResources);
    uiToggle.transform.SetParent(canvas.transform, false);
}

滑块:

public GameObject canvas;
void Start()
{
    DefaultControls.Resources uiResources = new DefaultControls.Resources();
    //Set the Slider Background Image someBgSprite;
    uiResources.background = someBgSprite;
    //Set the Slider Fill Image someFillSprite;
    uiResources.standard = someFillSprite;
    //Set the Slider Knob Image someKnobSprite;
    uiResources.knob = someKnobSprite;
    GameObject uiSlider = DefaultControls.CreateSlider(uiResources);
    uiSlider.transform.SetParent(canvas.transform, false);
}

面板:

public GameObject canvas;
void Start()
{
    DefaultControls.Resources uiResources = new DefaultControls.Resources();
    //Set the Panel Background Image someBgSprite;
    uiResources.background = someBgSprite;
    GameObject uiPanel = DefaultControls.CreatePanel(uiResources);
    uiPanel.transform.SetParent(canvas.transform, false);
}

输入字段:

public GameObject canvas;
void Start()
{
    DefaultControls.Resources uiResources = new DefaultControls.Resources();
    //Set the InputField Background Image someBgSprite;
    uiResources.inputField = someBgSprite;
    GameObject uiInputField = DefaultControls.CreateInputField(uiResources);
    uiInputField.transform.SetParent(canvas.transform, false);
    uiInputField.transform.GetChild(0).GetComponent<Text>().font = (Font)Resources.GetBuiltinResource(typeof(Font), "Arial.ttf");
}

下拉菜单:

public GameObject canvas;
void Start()
{
    DefaultControls.Resources uiResources = new DefaultControls.Resources();
    //Set the Dropdown Background and Handle Image someBgSprite;
    uiResources.standard = someBgSprite;
    //Set the Dropdown Scrollbar Background Image someScrollbarSprite;
    uiResources.background = someScrollbarSprite;
    //Set the Dropdown Image someDropDownSprite;
    uiResources.dropdown = someDropDownSprite;
    //Set the Dropdown Image someCheckmarkSprite;
    uiResources.checkmark = someCheckmarkSprite;
    //Set the Dropdown Viewport Mask Image someMaskSprite;
    uiResources.mask = someMaskSprite;
    GameObject uiDropdown = DefaultControls.CreateDropdown(uiResources);
    uiDropdown.transform.SetParent(canvas.transform, false);
}

其他的UI控件:

public static GameObject CreateImage(Resources resources);
public static GameObject CreateRawImage(Resources resources);
public static GameObject CreateScrollbar(Resources resources);
public static GameObject CreateScrollView(Resources resources);
public static GameObject CreateText(Resources resources);

2.通过Prefab和Instantiate

这种方法需要你已经创建并保存UI作为prefab。然后在需要的时候,可以使用Instantiate实例化UI。

从编辑器中创建一个Toggle控件,然后将其保存为prefab。删除原始控件。您可以在运行时实例化Toggle控件预制件,并根据需要定位或缩放它。

public GameObject canvas;
public GameObject togglePrefab;

void Start()
{
    GameObject uiToggle = Instantiate(togglePrefab) as GameObject;
    uiToggle.transform.SetParent(canvas.transform, false);
    //Move to another position?
    uiToggle.GetComponent<RectTransform>().anchoredPosition3D = new Vector3(...,...,...);
    //Re-scale?
    uiToggle.GetComponent<RectTransform>().localScale = new Vector3(...,...,...);
}

3. 逐个创建(困难)

首先从编辑器中创建一个 UI,然后在编辑器中研究 Hierarchy 和与之相关联的组件,通过代码再次复制它。

GameObject->UI->Toggle

例如,这是 Toggle 的外观:

enter image description here

1. 创建一个 Toggle GameObject,将其设置为 Canvas 的子物体。

2. 创建一个 Background GameObject,将其设置为 Toggle GameObject 的子物体。

3. 创建一个 Checkmark GameObject,将其设置为 Background GameObject 的子物体。

4. 创建一个 Label GameObject,将其设置为 Toggle GameObject 的子物体。

5. 现在像在编辑器中一样,将组件如 ImageTextToggle 附加到每个 GameObject 上。

在代码中:

public GameObject canvas;

void Start()
{
    makeToggle();
}

void makeToggle()
{
    GameObject toggleObj = createToggleObj(canvas);
    GameObject bgObj = createBackgroundObj(toggleObj);
    GameObject checkMarkObj = createCheckmarkObj(bgObj);
    GameObject labelObj = createLabelObj(toggleObj);
    attachAllComponents(toggleObj, bgObj, checkMarkObj, labelObj);
}

//1.Create a *Toggle* GameObject then make it child of the *Canvas*.
GameObject createToggleObj(GameObject cnvs)
{
    GameObject toggle = new GameObject("Toggle");
    toggle.transform.SetParent(cnvs.transform);
    toggle.layer = LayerMask.NameToLayer("UI");
    return toggle;
}

//2.Create a Background GameObject then make it child of the Toggle GameObject.
GameObject createBackgroundObj(GameObject toggle)
{
    GameObject bg = new GameObject("Background");
    bg.transform.SetParent(toggle.transform);
    bg.layer = LayerMask.NameToLayer("UI");
    return bg;
}

//3.Create a Checkmark GameObject then make it child of the Background GameObject.
GameObject createCheckmarkObj(GameObject bg)
{
    GameObject chmk = new GameObject("Checkmark");
    chmk.transform.SetParent(bg.transform);
    chmk.layer = LayerMask.NameToLayer("UI");
    return chmk;
}

//4.Create a Label GameObject then make it child of the Toggle GameObject.
GameObject createLabelObj(GameObject toggle)
{
    GameObject lbl = new GameObject("Label");
    lbl.transform.SetParent(toggle.transform);
    lbl.layer = LayerMask.NameToLayer("UI");
    return lbl;
}

//5.Now attach components like Image, Text and Toggle to each GameObject like it appears in the Editor.
void attachAllComponents(GameObject toggle, GameObject bg, GameObject chmk, GameObject lbl)
{
    //Attach Text to label
    Text txt = lbl.AddComponent<Text>();
    txt.text = "Toggle";
    Font arialFont =
    (Font)Resources.GetBuiltinResource(typeof(Font), "Arial.ttf");
    txt.font = arialFont;
    txt.lineSpacing = 1;
    txt.color = new Color(50 / 255, 50 / 255, 50 / 255, 255 / 255);
    RectTransform txtRect = txt.GetComponent<RectTransform>();
    txtRect.anchorMin = new Vector2(0, 0);
    txtRect.anchorMax = new Vector2(1, 1);
    //txtRect.y

    //Attach Image Component to the Checkmark
    Image chmkImage = chmk.AddComponent<Image>();
    chmkImage.sprite = (Sprite)AssetDatabase.GetBuiltinExtraResource(typeof(Sprite), "UI/Skin/Checkmark.psd");
    chmkImage.type = Image.Type.Simple;

    //Attach Image Component to the Background
    Image bgImage = bg.AddComponent<Image>();
    bgImage.sprite = (Sprite)AssetDatabase.GetBuiltinExtraResource(typeof(Sprite), "UI/Skin/UISprite.psd");
    bgImage.type = Image.Type.Sliced;
    RectTransform bgRect = txt.GetComponent<RectTransform>();
    bgRect.anchorMin = new Vector2(0, 1);
    bgRect.anchorMax = new Vector2(0, 1);

    //Attach Toggle Component to the Toggle
    Toggle toggleComponent = toggle.AddComponent<Toggle>();
    toggleComponent.transition = Selectable.Transition.ColorTint;
    toggleComponent.targetGraphic = bgImage;
    toggleComponent.isOn = true;
    toggleComponent.toggleTransition = Toggle.ToggleTransition.Fade;
    toggleComponent.graphic = chmkImage;
    toggle.GetComponent<RectTransform>().anchoredPosition3D = new Vector3(0, 0, 0);
}

第三种方法是最困难的,所以你应该避免使用它。在这种情况下,第一种方法应该是可以的。

希望这可以帮到你!


1
这很棒。但是Unity API仍然缺少基本功能 - 例如,它不会使用默认的背景图像、按钮图像等(按定义应该这样做)。但是这个技巧可以帮助你解决这个问题:https://forum.unity3d.com/threads/how-to-apply-uisprite-image-to-button-and-keep-borders-via-script.386434/#post-2514534 - Adam
是的,这是一个缺点。希望Unity能够解决这个问题。感谢提供链接。 - Programmer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接