2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Unity:UI Elements で共通コントロールを作成する

Posted at

はじめに

こんにちは、のんびりエンジニアのたっつーです。
ブログを運営しているのでよろしければ見てください。

今回は「いくつかサンプル書いたよ」の記事の1つの共通コントロールの作成方法と使い方を解説したいと思います。
ぜひ、お付き合いいただければと思います(#^^#)

UI Elementsとは?

こちらの記事をご参照いただければと思います。

共通コントロールの実装

さっそくですが、共通コントロールの実装をしてみたいと思います。

共通コントロール

Editor フォルダを作成し、右クリックのメニューから***「UIElements Editor Window」***を選択してください。
image-38.png

「RedButton」を入力してください。
 ※つけたいコントロールの名前に変更してしまって、OKです。
image-39.png

以下の3ファイルが生成されました、次にこの3ファイルを編集したいとおもいます。
image-40.png

まずは、RedButton.uxml は使わないので削除してください!
※使っても実装できますが今回はスクリプトですべて生成していきます。

次に、RedButton.uss を以下のように変更してください。

RedButton.uss
Button {
    font-size: 15px;
    -unity-font-style: bold;
    color: rgb(255, 0, 0);
}

次に、RedButton.cs を以下のように変更してください。

また、独自イベントとして clicked を定義しており、ボタンを押下イベントに合わせて clicked が呼ばれるようにしております。
また、MyControls のネームスペースに変更するのをお忘れずに!

RedButton.cs
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine.UIElements;


namespace MyControls
{
    internal class RedButton : VisualElement
    {
        public new class UxmlFactory : UxmlFactory<RedButton, UxmlTraits> { }

        public new class UxmlTraits : VisualElement.UxmlTraits
        {
            UxmlStringAttributeDescription m_Text =
                new UxmlStringAttributeDescription { name = "text", defaultValue = "none label" };

            public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
            {
                get { yield break; }
            }

            public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
            {
                base.Init(ve, bag, cc);
                var text = m_Text.GetValueFromBag(bag, cc);
                ((RedButton)ve).Init(text);
            }
        }

        private Button m_button;

        public string text
        {
            get { return m_button.text; }
            set { m_button.text = value; }
        }

        public event Action<EventBase> clicked;

        public RedButton()
        {
            var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/Editor/RedButton.uss");
            styleSheets.Add(styleSheet);

            m_button = new Button();
            m_button.text = "noen label";
            m_button.clickable.clickedWithEventInfo += Button_Clicked;
            hierarchy.Add(m_button);
        }

        public RedButton(string text) : this()
        {
            Init(text);
        }

        public void Init(string text)
        {
            this.text = text;
        }

        private void Button_Clicked(EventBase eb)
        {
            eb.target = this;
            clicked?.Invoke(eb);
        }
    }
}

呼び出し側

次に呼び出し側の実装になります。
先ほどと同じよう入力ですが今回は***「Sample1」で追加***してください。

image-41.png

同じように3ファイルとも以下のように編集してください。

共通コントロールとして、以下の赤い文字のボタン(RedButton)を用意しました、これを使いまわせるパーツとして、ボタン1~3の計3つを作成しています。

ポイントとしては、「xmlns:my=”MyControls”」 で my:RedButton が使えるようになります。

Sample1.uxml
<?xml version="1.0" encoding="utf-8"?>
<engine:UXML
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:engine="UnityEngine.UIElements"
    xmlns:editor="UnityEditor.UIElements"
    xmlns:my="MyControls"
    xsi:noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd"
    xsi:schemaLocation="UnityEngine.UIElements ../../UIElementsSchema/UnityEngine.UIElements.xsd">

  <engine:Label text="Sample1 UXML" />

  <my:RedButton text="button1" name="btn1" />
  <my:RedButton text="button2" name="btn2" />
  <my:RedButton text="button3" name="btn3" />

  <engine:Label text="Sample1 UXML end" />
</engine:UXML>
Sample1.uss
Label {
    font-size: 20px;
    -unity-font-style: bold;
    color: rgb(68, 138, 255);
}

ポイントとしては、各ボタンイベント(Clicked)にイベントを紐づけるために***「root.Q(“btn1”).clicked += ButtonClicked;」***で実行しています。

Sample1.cs
using MyControls;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public class Sample1 : EditorWindow
{
    [MenuItem("UIElementsSamples/Sample1")]
    public static void ShowExample()
    {
        Sample1 wnd = GetWindow<Sample1>();
        wnd.titleContent = new GUIContent("Sample1");
    }

    public void OnEnable()
    {
        VisualElement root = rootVisualElement;

        var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/Sample1.uxml");
        VisualElement labelFromUXML = visualTree.CloneTree();
        root.Add(labelFromUXML);

        root.Q<RedButton>("btn1").clicked += ButtonClicked;
        root.Q<RedButton>("btn2").clicked += ButtonClicked;
        root.Q<RedButton>("btn3").clicked += ButtonClicked;
    }

    void ButtonClicked(EventBase eventBase)
    {
        var redButton = (RedButton)eventBase.target;
        Debug.Log($"Clicked {redButton.text} RedButton!! ");
    }
}

動作結果

どうでしたか簡単に実装が行えたと思います。
今回は、RedButton.uxml は使わない実装でしたが使って実装する場合もそんなに難しくないと思いますのでぜひチャレンジしてみてください!

sample1.gif

終わりに

よければ ブログ「Unity+AssetStoreおすすめ情報」の方にも色々記載しているのでぜひご参照いただければと思います。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?