環境
- Unity 2021.311f1
- Windows 11 Home
UXMLドキュメント&スタイルシート
Assets/UIDocuments/Battle.uxml
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<Style src="project://database/Assets/UIDocuments/Battle.uss" />
<ui:VisualElement name="canvas" class="canvas">
<ui:VisualElement name="PlayerStatusWindow" class="window playerStatusWindow">
<ui:Label text="ゆうしゃ" name="PlayerName" class="windowLabel" />
<ui:GroupBox name="HPContainer" class="statsContainer hpContainer">
<ui:Label text="HP" name="HPLabel" />
<ui:Label text="68" name="HP" />
</ui:GroupBox>
<ui:GroupBox name="MPContainer" class="statsContainer">
<ui:Label text="MP" name="MPLabel" />
<ui:Label text="75" name="MP" />
</ui:GroupBox>
<ui:GroupBox name="LevelContainer" class="statsContainer">
<ui:Label text="Lv" name="LevelLabel" />
<ui:Label text="22" name="Level" />
</ui:GroupBox>
</ui:VisualElement>
<ui:VisualElement name="MessageWindow" class="window messageWindow">
<ui:Label name="MessageText" class="messageText" />
</ui:VisualElement>
<ui:VisualElement name="CommandWindow" class="window commandWindow">
<ui:Label text="コマンド" name="CommandLabel" class="windowLabel" />
<ui:GroupBox name="Command1" class="command commandAttack">
<ui:Label text="▶" name="CommandCursor1" class="commandCursor" />
<ui:Button text="こうげき" name="CommandButton1" class="commandButton" />
</ui:GroupBox>
<ui:GroupBox name="Command2" class="command">
<ui:Label text="▶" name="CommandCursor2" class="commandCursor" />
<ui:Button text="じゅもん" name="CommandButton2" class="commandButton" />
</ui:GroupBox>
<ui:GroupBox name="Command3" class="command">
<ui:Label text="▶" name="CommandCursor3" class="commandCursor" />
<ui:Button text="ぼうぎょ" name="CommandButton3" class="commandButton" />
</ui:GroupBox>
<ui:GroupBox name="Command4" class="command">
<ui:Label text="▶" name="CommandCursor4" class="commandCursor" />
<ui:Button text="どうぐ" name="CommandButton4" class="commandButton" />
</ui:GroupBox>
</ui:VisualElement>
<ui:VisualElement name="DetailCommandWindow" class="window detailCommandWindow">
<ui:GroupBox name="DetailCommandLabelContainer" class="detailCommandLabelContainer">
<ui:Label text="ゆうしゃのじゅもん" name="DetailCommandLabel" class="detailCommandLabel" />
</ui:GroupBox>
<ui:GroupBox name="DetailCommandContainer" class="detailCommandContainer">
<ui:GroupBox name="DetailCommand1" class="command detailCommand">
<ui:Label text="▶" name="DetailCommandCursor1" class="commandCursor" />
<ui:Button text="ファイア" name="DetailCommandButton1" class="commandButton" />
</ui:GroupBox>
<ui:GroupBox name="DetailCommand2" class="command detailCommand">
<ui:Label text="▶" name="DetailCommandCursor2" class="commandCursor" />
<ui:Button text="アイス" name="DetailCommandButton2" class="commandButton" />
</ui:GroupBox>
<ui:GroupBox name="DetailCommand3" class="command detailCommand">
<ui:Label text="▶" name="DetailCommandCursor3" class="commandCursor" />
<ui:Button text="パワーアップ" name="DetailCommandButton3" class="commandButton" />
</ui:GroupBox>
<ui:GroupBox name="DetailCommand4" class="command detailCommand">
<ui:Label text="▶" name="DetailCommandCursor4" class="commandCursor" />
<ui:Button text="ヒール" name="DetailCommandButton4" class="commandButton" />
</ui:GroupBox>
</ui:GroupBox>
</ui:VisualElement>
<ui:VisualElement name="CostWindow" class="costWindow window">
<ui:GroupBox name="CostLabelContainer" class="costLabelContainer">
<ui:Label text="しょうひMP" name="CostLabel" class="costLabel" />
</ui:GroupBox>
<ui:GroupBox name="CostContainer" class="costContainer">
<ui:GroupBox name="Cost" class="cost">
<ui:Label text="3" name="CostPoint" />
<ui:Label text="/" name="Separator" />
<ui:Label text="75" name="HavePoint" />
</ui:GroupBox>
</ui:GroupBox>
</ui:VisualElement>
<ui:VisualElement name="EnemyImage" class="enemyImage" />
</ui:VisualElement>
</ui:UXML>
Assets/UIDocuments/Battle.uss
* {
color: white;
font-size: 20px;
-unity-font-style: bold;
}
.canvas {
width: 100%;
height: 100%;
background-color: black;
position: absolute;
visibility: visible;
}
.window {
background-color: black;
border-color: white;
border-width: 3px;
border-radius: 4px 4px 4px 4px;
}
.playerStatusWindow {
width: 120px;
position: absolute;
left: 5%;
top: 5%;
right: 80%;
bottom: 60%;
}
.windowLabel {
position: absolute;
left: 50%;
top: -20px;
background-color: black;
padding-right: 5px;
-unity-text-align: upper-center;
margin-right: auto;
margin-left: auto;
right: auto;
translate: -50% 0;
padding-left: 5px;
align-items: flex-end;
}
.statsContainer {
flex-direction: row;
height: 25%;
padding: 0 5% 0 5%;
align-items: center;
justify-content: space-between;
}
.hpContainer {
margin-top: 10%;
}
.messageWindow {
right: 25%;
left: 25%;
top: 63%;
bottom: 5%;
position: absolute;
align-items: flex-end;
justify-content: flex-start;
flex-wrap: wrap-reverse;
}
.messageText {
left: -2.5%;
top: 2.5%;
width: 95%;
height: 95%;
align-items: auto;
padding: 0;
white-space: normal;
}
.commandWindow {
position: absolute;
left: 5%;
top: 60%;
right: 77%;
bottom: 8%;
}
.command {
align-items: center;
flex-direction: row;
height: 20%;
justify-content: flex-start;
margin: 0;
padding: 0 5% 0 5%;
}
.commandAttack {
margin-top: 10%;
}
.commandButton {
border-color: black;
background-color: black;
padding: 0 2px 0 0;
-unity-text-align: lower-left;
top: auto;
cursor: initial;
scale: 1 1;
margin: 0;
}
.commandCursor {
margin-bottom: 30px;
visibility: hidden;
}
.detailCommandWindow {
position: absolute;
left: 20%;
top: 65%;
right: 45%;
bottom: 6%;
flex-direction: row;
align-items: flex-start;
justify-content: space-between;
flex-wrap: wrap;
}
.detailCommandLabelContainer {
width: 100%;
height: 30%;
margin: 0;
padding: 0;
border-color: white;
border-bottom-width: 2px;
}
.detailCommandLabel {
-unity-text-align: middle-center;
white-space: normal;
}
.detailCommandContainer {
padding-left: 0;
padding-top: 0;
flex-direction: row;
align-items: stretch;
flex-wrap: wrap;
width: 100%;
height: 70%;
margin: 0;
padding-bottom: 0;
}
.detailCommand {
margin: 8px 0 0 4px;
padding: 0;
height: 35%;
width: 46%;
}
.costWindow {
position: absolute;
left: 53%;
top: 75%;
right: 30%;
bottom: 6%;
flex-direction: row;
align-items: flex-start;
justify-content: space-between;
flex-wrap: wrap;
}
.costLabelContainer {
width: 100%;
height: 43%;
margin: 0;
padding: 0;
border-bottom-color: white;
border-bottom-width: 2px;
}
.costLabel {
-unity-text-align: middle-center;
white-space: normal;
padding: 0;
}
.costContainer {
flex-direction: column;
align-items: flex-end;
flex-wrap: wrap-reverse;
justify-content: center;
width: 100%;
height: 59%;
margin: 0;
padding: 0;
}
.cost {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
flex-direction: row;
align-items: center;
justify-content: center;
}
.enemyImage {
position: absolute;
left: 30%;
top: 10%;
right: 30%;
bottom: 40%;
background-image: url('project://database/Assets/Images/dragon.png');
}
Unityで表示

Assets/UIDocumentsフォルダを作成し、上記Battle.uxmlとBattle.ussをコピー。

Projectウィンドウ上で右クリック→[Create]>[UI Toolkit]>[Panel Settings Asset]を選択。
Scale Modeを「Scale With Screen Size」
Reference Resolution を X:800 Y450に設定。

いらすとやからドラゴンのイラストをダウンロードしAssets/Images/dragon.pngとして保存。
Hierarchyウィンドウ上で右クリック→[Create Empty]を選択。
作成したゲームオブジェクトに「UI Document」をアタッチし、先ほど作成したPanel SettingsとUXMLドキュメントをプロパティにセット。

UI Toolkitを使用してみた感想
- ブラックボックスになりやすいUI部分をコードで管理できる。
→ コードなのでGithub上でも確認できる、それによってレビューもしやすい。 - UIBuilderを使用してGUIで作成することも可能。
→ 初心者でも始めやすい。
→ 設定する必要がないのにデフォルト値で設定したり、インラインスタイルを意図せず作成する等が起きがちなので注意。
- まだ動作が不安定な部分がある。
→ 親要素を非表示にしたのに子要素が表示されっぱなし、文字が一部だけ太字になってない等 - C#と連携するためにはコードを書く必要がある。
→ プロパティやUnityEventをインスペクターから使用するのと比べるとコード量は結構増える。
→ メンバーがUniTask、UniRxを使用できるとやりやすいかも。