Unityで、コンポーネント内のフィールドを文字列から動的に変更する

こんにちはー!!

Json からUnity2dのステージのデータを取ろうとしています。
その時、コンポーネントの値を変えたいと思い、この方法をやりました。
Reflectionを使ったりして、結構複雑でした。

ReflectionTest コンポーネントの内容は次のようにします。

これを、GameObject1 にアタッチすればできます。

安全性は・・

しかし、コンポーネント内すべてのフィールドにアクセスできるのは
ちょっとセキュリティが・・・なので、
特定の属性(ここではPermitReflection)がついたフィールドのみにアクセスできるようにします。

Reflectionに使ったしたコード(2つ上のコード)を、次のように編集します。

    Type componentType = Type.GetType(componentType);
    Attribute fieldAttribute = Attribute.GetCustomAttribute(componentType.GetField(fieldName), typeof(PermitReflectionAttribute));
    if (fieldAttribute != null)  // 属性が存在する場合のみ
    {
        Component targetComponent = GameObject.Find(gameObjectName).GetComponent(componentName);
        Type fieldType = componentType.InvokeMember(fieldName, BindingFlags.GetField, null, targetComponent, null).GetType();
        object parameter;
        // 汎用性を重視して、型がどんな場合でもstringからParseできるように
        if (fieldType == typeof(string))
        {
            parameter = fieldVal;
        }
        else if (fieldType == typeof(int))
        {
            parameter = int.Parse(fieldVal);
        }
        componentType.InvokeMember(fieldName, BindingFlags.SetField, null, targetComponent, new object[] { parameter });
    }
}

// 属性を追加
[AttributeUsage(AttributeTargets.Field)]
public class PermitReflectionAttribute : Attribute
{
}

ReflectionTest コンポーネントは次のように変更します。

PermitReflectionAttributeですが、属性として指定する場合は、
Attributeを抜いて、PermitReflectionとします。

Unityで二次元配列のJsonを読む

こんばんはー。

Unityのステージ内容を Yaml で作ろうと思っていました。

UnityでYAMLをパースする
※ UnityYamlMerge のことではありません!Unity で、2D ステージの内容を YAML で作って、それをパースする方法です。yaml-net を入れるhttp://sourceforge.net/project...

しかし、よく考えてみれば、Unity 公式でサポート(5.3から)されている、
Json で十分じゃね?と思いました。
ステージの内容は、次のようなJsonにしました。

{
  "version": 1,
  "stage": [
    ["block1", 2, 4],
    ["block1", 4, 4]
  ]
}

しかし、JsonUtilityでParseしても、うまくやってくれませんでした。

■配列のネストは1つまで

多次元配列、配列内配列(ジャグ配列)、配列のコレクションなどは、JSONにシリアライズしてくれない。
多次元配列(int[,] とか)は、.NET標準のシリアライザも対応してないので仕方ない。
しかし int[][] や List<int[]> 、 List<List>なども、JsonUtilityは華麗にスルーする。

http://ch.nicovideo.jp/ntmi/blomaga/ar927398より)
とのことです。

というわけで、LitJSON というライブラリを使うことにしました。

ダウンロード

http://lbv.github.io/litjson/から、
Download で dll をダウンロードすると楽。
litjson-download-dll

ダウンロードした dll を、Plugins/ ディレクトリにドラッグ&ドロップ。
Drag-litjson-Unity

次のように書く。

using LitJson;

// 省略

void MakeStageJson(string data)
{
    JsonData jsonData = JsonMapper.ToObject(data);
    Debug.Log((string)jsonData["stage"][0]);
}

実行結果:
unity-debuglog-litjson

このように、jsonData["stage"][0] と、ただインデックス(?)をたどるだけで、
二次元配列も使えます!

LitJSON便利です!

Visual Studio Code で便利なショートカット!

こんばんは。

Visual Studio Code 使ってますかー!!

GitとTypeScriptの補完をプラグインなしでやってくれて便利です!

さて、今回はよく使っているショートカットキーと

デフォルトにないけどよく使うショートカットキーを紹介します!

(ぼくはWindowsなのでCtrlになりますがMacだとCommandキーなのかな?)

デフォルトにあるショートカットキー

Ctrl + Shift + P

コマンドパレットを開きます。超便利です。

Ctrl + Tab (エディタで)

workbench.action.quickOpenNavigateNext らしいです。

VSCodeにはタブはありませんが、作業中のファイルを切り替えてくれます。

Ctrl + Shift + Tab (エディタで)

Ctrl + Tabの逆バージョン

Ctrl + Shift + F (どこでも)

フォルダーを開いているとき、すべてのファイルから検索ができます!!

デフォルトにないから追加するショートカットキー

設定の方法

Ctrl + Shift + P でコマンドパレットを開き、Preferences: Open Keyboard Settings
keybindings.jsonに、次のような形式でキーバインドを書きます。

{
  "key": "バインドするキー(例: ctrl+alt+o)",
  "command": "コマンド 左側のファイルの下の方にずらっと。"
}

Open Recent Folder

コマンドは workbench.action.openRecent です。過去に開いたフォルダーを表示してくれます。

ぼくは Ctrl + Alt + O にバインドしています。

KeyBindを設定する

workbench.action.openGlobalKeybindings です。KeyBindを設定してくれる画面になります。

最後に

VSCodeは、こんな感じで自分風にアレンジがすぐにできるので、ぜひ使ってみてください!!