UnityのInspectorで配列の順番を変更したい場合はReorderableList

Unityで配列を使いたい場合、

using UnityEngine;

public class Example : MonoBehaviour
{
  public string[] Array;
}

のような感じで実装すると、Inspectorには次のように表示されます。

これだけでもInspectorから配列のサイズと値を設定することができて便利ですが、要素の並び替えがしたいと思って実装方法を調べてみました。

ReorderableList

ということで、ReorderableListを使うとInspectorで並び替えができるようになるみたいです。

最低限の実装で並び替えだけしたい場合

とりあえず並び替えだけできれば良いという場合は、次のように実装できるみたいです。

using UnityEditor;
using UnityEditorInternal;

[CustomEditor(typeof(Example))]
public class ExampleEditor : Editor
{
  ReorderableList _reorderableList;

  void OnEnable()
  {
    var property = serializedObject.FindProperty("Array");
    _reorderableList = new ReorderableList(serializedObject, property, true, true, false, false);
  }

  public override void OnInspectorGUI()
  {
    base.OnInspectorGUI();

    serializedObject.Update();
    _reorderableList.DoLayoutList();
    serializedObject.ApplyModifiedProperties();
  }
}

Inspectorの表示は次のような感じになります。

Serialized Propertyに表示されているElementをドラッグで移動できるようになります。(移動した場合は上のArrayの値も変更されます。)

値も表示したい

値も表示したいという場合は、次のような感じでdrawElementCallbackを実装します。

void OnEnable()
{
  var property = serializedObject.FindProperty("Array");
  _reorderableList = new ReorderableList(serializedObject, property, true, true, false, false);

  _reorderableList.drawElementCallback = (rect, index, isActive, isFocused) =>
  {
    var element = property.GetArrayElementAtIndex(index);
    EditorGUI.PropertyField(rect, element);
  };
}

Inspectorの表示は次のような感じになります。

構造体を表示したい

構造体を表示したい場合は、Serializable属性を設定した上で、次のような感じで修正します。

using UnityEngine;

public class Example : MonoBehaviour
{ 
  [System.Serializable]
  public struct Struct
  { 
    public string text;
    public int value;
  }

  public Struct[] Array;
}
using UnityEditor;
using UnityEditorInternal;

[CustomEditor(typeof(Example))]
public class ExampleEditor : Editor
{
  ReorderableList _reorderableList;

  void OnEnable()
  {
    var property = serializedObject.FindProperty("Array");
    _reorderableList = new ReorderableList(serializedObject, property, true, true, false, false);

    _reorderableList.elementHeightCallback = (index) =>
    {
      var element = property.GetArrayElementAtIndex(index);
      return EditorGUI.GetPropertyHeight(element.FindPropertyRelative("text")) + EditorGUI.GetPropertyHeight(element.FindPropertyRelative("value"));
    };

    _reorderableList.drawElementCallback = (rect, index, isActive, isFocused) =>
    {
      var element = property.GetArrayElementAtIndex(index);

      rect.height = EditorGUI.GetPropertyHeight(element.FindPropertyRelative("text"));
      EditorGUI.PropertyField(rect, element.FindPropertyRelative("text"));

      rect.y += rect.height;
      rect.height = EditorGUI.GetPropertyHeight(element.FindPropertyRelative("value"));
      EditorGUI.PropertyField(rect, element.FindPropertyRelative("value"));
    };
  }

  public override void OnInspectorGUI()
  {
    base.OnInspectorGUI();

    serializedObject.Update();
    _reorderableList.DoLayoutList();
    serializedObject.ApplyModifiedProperties();
  }
}

Inspectorの表示は次のような感じになります。

もう少し真面目に実装したい場合

同じ設定が二重に表示されないようにしたい場合はHideInInspector属性を設定します。

[HideInInspector] public Struct[] Array;

ただ、このままではInspectorから配列のサイズが変更できなくなってしまうので、

_reorderableList = new ReorderableList(serializedObject, property);

とした上で、_reorderableListonAddCallbackonRemoveCallbackを実装すると良いみたいです。

Raspberry Piに関するTIPS

Raspberry Piの温度を調べたい

下記コマンドで温度が調べられます。

/opt/vc/bin/vcgencmd measure_temp

アップデート

Raspberry Piにインストールしているソフトウェアをアップデートしたい場合は、下記コマンドを実行します。

sudo apt update
sudo apt upgrade

もしくは

sudo apt update
sudo apt full-upgrade

マウスの動作が遅い

/boot/cmdline.txtusbhid.mousepollの設定を追加して再起動します。

usbhid.mousepoll=0

キーボードのCtrlキーとCapsキーを入れ替えたい

/etc/default/keyboardXKBOPTIONSの設定を追加して再起動します。

XKBOPTIONS="ctrl:swapcaps"

Swapが発生して遅くなった

Raspberry Piでの場合、特にSDカードを使っているとSwapが発生した場合に動作が遅くなる場合があります。

メモリの使用状況はfreeコマンドで確認できますので、Swap領域が使用されている場合は解放してみることで改善する場合もあるかと思います。

$ free
total        used        free      shared  buff/cache   available
Mem:        7905608     1560764     3883220      164912     2461624     5929408
Swap:        102396       32768       69628
$ sudo /etc/init.d/dphys-swapfile restart
$ free
total        used        free      shared  buff/cache   available
Mem:        7905608     1893808     3505060      145496     2506740     5615644
Swap:        102396           0      102396

※うまく解放できない場合はPCを再起動してもいいと思います。

IPアドレスを固定したい

/etc/dhcpcd.confに以下のような内容を追加します。(192.168.1.23は固定したいIPアドレス、1.1.1.1はネームサーバーの例です。)

interface eth0
static ip_address=192.168.1.23/24
static routers=192.168.1.1
static domain_name_servers=1.1.1.1

dhcpcd.confが修正できたら再起動するか、下記コマンドを実行します。

sudo ipconfig eth0 down
sudo ipconfig eth0 up

無線LANのIPアドレスを固定したい場合はeth0の部分をwlan0に読み替えてください。

interface wlan0

SSIDステルス機能を有効にしている無線LANに接続したい

wpa_passphrase "SSID名" "パスワード"

を実行して、表示された内容を/etc/wpa_supplicant/wpa_supplicant.confに追加します。

もしくは、

sudo wpa_passphrase "SSID名" "パスワード" >> /etc/wpa_supplicant/wpa_supplicant.conf

を実行します。

更に、エディタでwpa_supplicant.confを開いてnetwork={…}内に

scan_ssid=1

を追加し、再起動します。

NFSサーバーとして運用したい

まず、nfs-kernel-serverをインストールします。

sudo apt install nfs-kernel-server

インストールできたら、/etc/exportsを以下のような感じで設定します。(/exportを公開する場合の例です。)

/export 192.168.1.0/24(rw,fsid=0,insecure,no_subtree_check,async)

※NFSクライアントを制限する必要がない場合は192.168.1.0/24の部分を*とします。

設定できたら下記コマンドを実行します。

sudo exportfs -rav

リンク

Network File System (NFS) – Raspberry Pi Documentation
https://www.raspberrypi.org/documentation/configuration/nfs.md

Sambaサーバーにアクセスしたい

とりあえずSambaのファイルを読み書きしたいという場合はファイルマネージャー「PCmanFM」が使えます。

アドレスバーに

smb://192.168.1.23/shared_folder

と入力してみてください。

192.168.1.23はサーバーのIPアドレス、shared_folderはフォルダー名です。

SDカードの認識状況を確認したい

lsblkコマンドを実行すると次のような感じで表示されます。

$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 1 29.7G 0 disk
└─sda1 8:1 1 29.7G 0 part /media/pi/6439-3038
mmcblk0 179:0 0 29.7G 0 disk
├─mmcblk0p1 179:1 0 256M 0 part /boot
└─mmcblk0p2 179:2 0 29.5G 0 part /

mmcblk0というのがOS(raspbian)がインストールされているSDカード、sdaというのがカードリーダーに挿したmicroSDカードです。(実際の表示内容は環境によって変ってくると思います。)

UnityでビルドしたWebGLゲームのURLが知りたい場合

UnityでビルドしたWebGLのゲームで、実行時にURLが知りたい場合はApplication.absoluteURLを使って確認できるみたいです。

使い方

Debug.Log(Application.absoluteURL);

ちなみに、Android/iOS/UWPでビルドした場合、absoluteURLはdeep link URLになっているそうです。WebGL以外でabsoluteURLを参照する場合は注意してください。

リンク

Unity – Scripting API: Application.absoluteURL
https://docs.unity3d.com/ScriptReference/Application-absoluteURL.html

Unity – Scripting API: Application.deepLinkActivated
https://docs.unity3d.com/ScriptReference/Application-deepLinkActivated.html