【Unity】Unity内で魚を泳がせよう UniAquariumというエディター拡張をつくってみた
つくったもの
UnityのVisualElement下で動く水族館を作ってみました。
HtmlのCanvas風に描画できるPainter2D
というものを使用しています。
完成品はこちら
また、今回作成したものは[ネタ]VSCodeで魚を飼って仕事中に癒されることにしたをほとんど参考にしています。
使い方
要件
- Unity 2022.1 or later
インストール
1.Window > Package Manager
からPackage Managerを開く
2.「+」ボタン > Add package from git URL
をクリック
3. 以下を入力してインストール
https://github.com/Garume/UniAquarium.git?path=/Assets/UniAquarium
開き方
ツールバーから Window > Aquarium
でアクアリウムウィンドウを開けます。
機能
餌あげ
ウィンドウ上の任意の場所をクリックすると餌をあげることができます。
魚が餌を食べに行く様子をみると癒されますね。
衝撃波
ウィンドウ上の任意の場所をクリックすると餌をあげることができます。
魚が衝撃波をよけます。かわいい。
魚が群れを成して動く
本家でも説明されていますが、群れを再現するために Boids Algorithm
というアルゴリズムを採用しています。
詳しくは以下の記事を読んでみてください。
Wikipedia
水族館を作ろう:BOIDの基本
カスタム設定
デフォルト状態では魚やクラゲの数が決まっていますが、これらの設定を独自にカスタマイズできます。
設定用のScriptable Object
を提供しており、これを使用します。
ツールバーのAssets > Create > UniAquarium Settings
から作成することができます。
Assets以下であればどこに保存しても大丈夫です。
Fish Settings
の要素数が1のときは通常通り。
1以上の場合自動的にBoid
が適用されて群れを成して動くようになります。
自分好みに設定したら、Aquarium Window
をリロードしましょう。
リロードはウィンドウ右上の3点リーダー > Reload
からできます。
Aquarium Component
Window以外にもアクアリウムを描画できるようにVisualElement
を継承したAquarium Component
を用意しています。
このComponentを任意のコンテナに追加することで好きな場所にアクアリウムを表示させることができます。
試しにヒエラルキーウィンドウへ描画させてみましょう。
以下のコードをAssets以下の任意のスクリプトに記述してください。
アセンブリが切られているため、参照を追加する必要があることに注意。
using System.Reflection;
using UniAquarium.Aquarium;
using UnityEditor;
using UnityEngine.UIElements;
[InitializeOnLoad]
public class HierarchyWindowHook
{
private static VisualElement _rootVisualElement;
static HierarchyWindowHook()
{
EditorApplication.update += Update;
}
private static void Update()
{
if (_rootVisualElement != null) return;
// get SceneHierarchyWindow.
var hierarchyWindowType = typeof(Editor).Assembly.GetType("UnityEditor.SceneHierarchyWindow");
var hierarchyWindow = EditorWindow.GetWindow(hierarchyWindowType);
// get VisualElement using reflection.
if (hierarchyWindow == null) return;
var fieldInfo = hierarchyWindowType.GetField("m_SceneHierarchy",
BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfo == null) return;
var sceneHierarchy = fieldInfo.GetValue(hierarchyWindow);
var sceneHierarchyType = sceneHierarchy.GetType();
var visualElementFieldInfo = sceneHierarchyType.GetField("m_EditorWindow",
BindingFlags.NonPublic | BindingFlags.Instance);
if (visualElementFieldInfo == null) return;
var treeView = visualElementFieldInfo.GetValue(sceneHierarchy);
var root = treeView as EditorWindow;
_rootVisualElement = root.rootVisualElement;
// Setting it to false disables clicks and other actions.
var aquariumComponent = new AquariumComponent(false);
_rootVisualElement.Add(aquariumComponent);
aquariumComponent.Enable();
}
}
保存したらヒエラルキーウィンドウを見てみましょう。
いい感じに表示できていますね!
リフレクションを使用しているためやたら長いですが、重要なのは次の3行です。
var aquariumComponent = new AquariumComponent(false);
_rootVisualElement.Add(aquariumComponent);
aquariumComponent.Enable();
AquariumComponent
をインスタンス化して、Visual Element
に追加、Enable関数を呼んでいるだけです。
インスタンス化の際にfalseを引数にとっているのは、クリック等のインタラクティブを無効化するためです。
これをしないと、本来表示されていたヒエラルキー内のアイテムを触ることができません。
内部的には、
pickingMode = PickingMode.Ignore;
を指定しているだけです。
さいごに
Painter2Dを使用してアクアリウムを作成してみました。
描画しているものはがっつり本家になってしまいましたが、設計面ではかなり考えさせられるものが多かったです。
よかったら⭐をいただけると嬉しいです。
Discussion