Skip to content

Instantly share code, notes, and snippets.

@atori708
Last active December 4, 2022 13:59
Show Gist options
  • Save atori708/93b1781d44627a246ad54b9db56873b9 to your computer and use it in GitHub Desktop.
Save atori708/93b1781d44627a246ad54b9db56873b9 to your computer and use it in GitHub Desktop.
【UIToolkit】スマホっぽいフッターUI
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using System.Collections.Generic;
public class FooterSample : EditorWindow
{
VisualElement indicator;
List<VisualElement> icons;
int selectIndex;
[MenuItem("Window/UI Toolkit/FooterSample")]
public static void ShowExample()
{
FooterSample wnd = GetWindow<FooterSample>();
wnd.titleContent = new GUIContent("FooterSample");
}
public void CreateGUI()
{
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/FooterSample.uxml");
VisualElement uxml = visualTree.Instantiate();
uxml.style.flexGrow = 1;
rootVisualElement.Add(uxml);
indicator = uxml.Q<VisualElement>("Indicator");
icons = uxml.Query<VisualElement>("Icon").ToList();
for (int i = 0; i < icons.Count; i++) {
var icon = icons[i];
icon.focusable = true;
var index = i;
// アイコンにクリック時の挙動を追加
icon.AddManipulator(new Clickable(() => {
SelectFooterIcon(index);
}));
}
EditorApplication.delayCall += () => SelectFooterIcon(0);
}
/// <summary>
/// インジケータの座標合わせ
/// </summary>
private void Update()
{
var icon = icons[selectIndex];
MoveIndicator(icon);
}
/// <summary>
/// アイコン選択
/// </summary>
/// <param name="index">アイコンのインデックス</param>
private void SelectFooterIcon(int index)
{
selectIndex = index;
var icon = icons[index];
for (int i = 0; i < icons.Count; i++) {
icons[i].RemoveFromClassList("active");
}
icon.AddToClassList("active");
MoveIndicator(icon);
}
/// <summary>
/// インジケータ移動
/// </summary>
/// <param name="targetIcon">移動先のアイコン</param>
private void MoveIndicator(VisualElement targetIcon)
{
var pos = targetIcon.layout.position.x + targetIcon.localBound.width * 0.5f;
var indicatorPos = indicator.transform.position;
indicatorPos.x = pos - indicator.localBound.width * 0.5f;
indicator.transform.position = indicatorPos;
}
}
:root {
--bgclr: rgb(56, 56, 56);
--clr: rgb(34, 50, 34);
background-color: var(--bgclr);
}
#Footer {
flex-direction: row;
bottom: 0;
}
#Icon {
-unity-font-style: bold;
color: var(--clr);
border-radius: 0;
border-width: 0;
flex-grow: 1;
height: 100%;
margin-left: 0;
margin-right: 0;
margin-top: 0;
margin-bottom: 0;
padding-left: 0;
padding-right: 0;
padding-top: 0;
padding-bottom: 0;
}
#Icon .Label {
flex-grow: 1;
margin: 1px;
padding: 1px;
opacity: 0;
translate: 0 10px;
transition-property: opacity, translate;
transition-duration: 0.2s, 0.2s;
}
#Icon .IconImage {
translate: 0 0;
transition-property: translate;
transition-duration: 0.2s;
}
#Icon.active .Label{
transition-property: opacity, translate;
transition-duration: 0.2s, 0.2s;
opacity: 1;
translate: 0 -5px;
}
#Icon.active .IconImage{
transition-property: translate;
transition-duration: 0.2s;
translate: 0 -22px;
}
.Indicator
{
position: absolute;
top: -45%;
border-color : var(--bgclr);
border-width:3px;
border-radius: 22.5px;
transition-duration: 0.2s;
}
<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/Editor/FooterSample.uss?fileID=7433441132597879392&amp;guid=563b2651b5bee3f4aa90cdfa280ad4a4&amp;type=3#FooterSample" />
<ui:VisualElement style="flex-grow: 1; justify-content: flex-end;">
<ui:GroupBox name="Footer" style="flex-direction: column;">
<ui:VisualElement name="BG" style="flex-direction: row; background-color: rgb(255, 255, 255); border-top-left-radius: 8px; border-bottom-left-radius: 8px; border-top-right-radius: 8px; border-bottom-right-radius: 8px; height: 50px; align-items: flex-end;">
<ui:VisualElement name="Indicator" class="Indicator" style="background-color: rgb(64, 144, 231); width: 52px; height: 52px; border-left-width: 4px; border-right-width: 4px; border-top-width: 4px; border-bottom-width: 4px; border-top-left-radius: 26px; border-bottom-left-radius: 26px; border-top-right-radius: 26px; border-bottom-right-radius: 26px;" />
<ui:VisualElement name="Icon" enable-rich-text="true" class="Icon" style="align-items: center; justify-content: flex-end; background-color: rgba(88, 88, 88, 0); flex-grow: 1; width: 100%;">
<ui:VisualElement name="IconImage" class="IconImage" style="width: 30px; height: 30px; background-image: url(&apos;project://database/Assets/Icons/icons8-%E9%9B%BB%E8%A9%B1-50.png?fileID=2800000&amp;guid=f41e2cdeff32caa47b6597e30abde194&amp;type=3#icons8-電話-50&apos;); margin-left: 0; margin-right: 0; margin-top: 4px; margin-bottom: -8px; flex-grow: 0; flex-shrink: 1;" />
<ui:Label text="Call" class="Label" style="flex-shrink: 1; flex-grow: 0;" />
</ui:VisualElement>
<ui:VisualElement name="Icon" enable-rich-text="true" class="Icon" style="align-items: center; justify-content: flex-end; background-color: rgba(88, 88, 88, 0); flex-grow: 1; width: 100%;">
<ui:VisualElement name="IconImage" class="IconImage" style="width: 30px; height: 30px; background-image: url(&apos;project://database/Assets/Icons/icons8-chat-bubble-50.png?fileID=2800000&amp;guid=d88b9c1febd67954aaa069f91fd81011&amp;type=3#icons8-chat-bubble-50&apos;); margin-left: 0; margin-right: 0; margin-top: 4px; margin-bottom: -8px; flex-grow: 0; flex-shrink: 1;" />
<ui:Label text="Chat" class="Label" style="flex-shrink: 1; flex-grow: 0;" />
</ui:VisualElement>
<ui:VisualElement name="Icon" enable-rich-text="true" class="Icon" style="align-items: center; justify-content: flex-end; background-color: rgba(88, 88, 88, 0); flex-grow: 1; width: 100%;">
<ui:VisualElement name="IconImage" class="IconImage" style="width: 30px; height: 30px; background-image: url(&apos;project://database/Assets/Icons/icons8-%E3%83%9B%E3%83%BC%E3%83%A0-50.png?fileID=2800000&amp;guid=10817bf34aff1724d93876742ecd4bfc&amp;type=3#icons8-ホーム-50&apos;); margin-left: 0; margin-right: 0; margin-top: 4px; margin-bottom: -8px; flex-grow: 0; flex-shrink: 1;" />
<ui:Label text="Home" class="Label" style="flex-shrink: 1; flex-grow: 0;" />
</ui:VisualElement>
<ui:VisualElement name="Icon" enable-rich-text="true" class="Icon" style="align-items: center; justify-content: flex-end; background-color: rgba(88, 88, 88, 0); flex-grow: 1; width: 100%;">
<ui:VisualElement name="IconImage" class="IconImage" style="width: 30px; height: 30px; background-image: url(&apos;project://database/Assets/Icons/icons8-%E3%82%AB%E3%83%A1%E3%83%A9-50.png?fileID=2800000&amp;guid=942e5a6ff7329e5448111b8556597d0b&amp;type=3#icons8-カメラ-50&apos;); margin-left: 0; margin-right: 0; margin-top: 4px; margin-bottom: -8px; flex-grow: 0; flex-shrink: 1;" />
<ui:Label text="Camera" class="Label" style="flex-shrink: 1; flex-grow: 0;" />
</ui:VisualElement>
<ui:VisualElement name="Icon" enable-rich-text="true" class="Icon" style="align-items: center; justify-content: flex-end; background-color: rgba(88, 88, 88, 0); flex-grow: 1; width: 100%;">
<ui:VisualElement name="IconImage" class="IconImage" style="width: 30px; height: 30px; background-image: url(&apos;project://database/Assets/Icons/icons8-%E3%83%A6%E3%83%8B%E3%83%86%E3%82%A3-50.png?fileID=2800000&amp;guid=c3eb2a44fd305e44f96882f5eb954bae&amp;type=3#icons8-ユニティ-50&apos;); margin-left: 0; margin-right: 0; margin-top: 4px; margin-bottom: -8px; flex-grow: 0; flex-shrink: 1; top: -2px; left: -2px;" />
<ui:Label text="Unity" class="Label" style="flex-shrink: 1; flex-grow: 0; margin-left: 0; margin-right: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-right: 0; padding-top: 0; padding-bottom: 0;" />
</ui:VisualElement>
</ui:VisualElement>
</ui:GroupBox>
</ui:VisualElement>
</ui:UXML>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment