テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

作成したScriptableObjectを呼び出す

そういえば[Unity]Excelでデータを管理してUnity iOS/Androidで使うワークフローをノーコーディングで使えるようにした等でScriptableObjectを作る方法を紹介したが使う方法を紹介していなかったので、紹介。

ScriptableObjectについては[Unity]ScriptableObjectの使い方をどうぞ。



参照する方法だが、非常に簡単だ。
  1. プレハブと同じように、publicや[SerializeField]を使用して
    inspectorからD&Dで参照出来るようにする。
  2. Resourcesから呼び出して登録する

例えば以下のScriptableObjectを作るとする。


using UnityEngine;

public class TestData : ScriptableObject
{
    public int count;
    public string msg;
}

呼び出したいスクリプトにpublic ScriptableObject名 変数名 と宣言し、後はドラッグ&ドロップでScriptableObjectを登録すれば呼び出すことが出来る。つまりプレハブと同じ感じだ。


using UnityEngine;

public class CallTestData : MonoBehaviour
{
    public TestData m_testData;

   
void Update ()
    {
        Debug.Log (m_testData.count);
        Debug.Log (m_testData.msg);
    }
}

スクリーンショット 2014-03-22 0.56.02

もしドラッグ&ドロップが面倒な場合、Resourcesから呼び出すことも出来る。下のコードではStartのタイミングでResourcesフォルダに配置したtestdata.assetファイルをを呼び出している。

using UnityEngine;

public class CallTestData : MonoBehaviour
{
    private TestData m_testData;

    void Start ()
    {
        m_testData = Resources.Load<TestData> ("testdata");
    }

    void Update ()
    {
        Debug.Log (m_testData.count);
        Debug.Log (m_testData.msg);
    }
}


呼び出しと言えば、実はScripableObjectは継承して使用することが出来る。継承して挙動をoverride(上書き)することで、状況によりScriptableObjectを差し替える事で挙動を判断するAIライクな事も可能になる。

例えばTestDataを継承してTestDataAとTestDataBを用意する。またTestDataにはインターフェース宜しくabstructやvertualのメソッドを用意しておく。その後、処理を記述。

public class TestData : ScriptableObject
{
    public int count;
    public string msg;

    public virtual string GetMessage ()
    {
        return null;
    }
}

public class TestDataA : TestData
{
    public override string GetMessage ()
    {
        return "TestDataA " + this.msg;
    }
}

public class TestDataB : TestData
{
    public override string GetMessage ()
    {
        return "TestDataB " + this.msg;
    }
}

後は各々のScriptableObjectを差し替えるだけで、ScriptableObjectに登録したメソッドの挙動を切り替える。下の図は実際にTestDataAとTestDataBのScriptableObjectを差し替え、GetMessageを呼び出した時の動作だ。

 スクリーンショット 2014-03-22 1.11.28

スクリーンショット 2014-03-22 1.11.13



(質問は大歓迎です)

Unity-Excel-Importer-Maker 配列型に対応

Unity-Excel-Importer-Makerで配列型をサポートした。
変数名と入力している場合、その項目を結合して配列として扱う。

Unity-Excel-Importer-Maker

[Unity]Excelでデータを管理してUnity iOS/Androidで使うワークフローをノーコーディングで使えるようにした

例えば「data」と入力した場合、dataを結合して配列とみなす。下の例の場合だと、data[2] = {1,7};と同じような感じになる。

スクリーンショット 2013-11-02 01.02.23

配列には---[array]---が付く。
スクリーンショット 2013-11-02 01.01.33

スクリーンショット 2013-11-02 01.01.55

他にも、一度設定した変数の型を保持する設定とか、色々と追加。(主に@pigeon6氏が)

もっと色々とガンバルゾー!

Excelでデータを管理してUnity iOS/Androidで使うワークフローをノーコーディングで使えるようにした

以前紹介した「Excelでデータを管理して(中略)ワークフロー」に「助かりました!」の声があったのが嬉しかったので、それのソースコードを作成する部分を自動化した。(我ながら単純!!)

これで、すごく簡単にXLSファイルのデータをUnityに持ってくる事ができるようになった。

で、今回はソースコードオープンソースとして公開する事にした。
エディタ拡張をする程でも無い部分は、こういった機能を活用して欲しい。
一応アセットストアにも出そうと思う

Unity-Excel-Importer-Maker


使い方

  1. Unity-Excel-Importer-MakerのDownload Zipを選択してファイルをダウンロード。ダウロードしたファイルのAssets/Terasurwareフォルダをプロジェクトにインポートする。

  2. XLSファイルをD&Dでプロジェクトにインポートする。
    残念ながらファイル名が日本語だったり、頭に数字が入っているファイルは使えない。注意。

    import excel

  3. 先ほどインポートしたXLSファイルを選択し、右クリック>Create XLS Importerを選択する。

    create xls importer

  4.   XLSを解析してデータを注入するクラスを作るので、パラメータの型と名称を設定してCreateを選択。数値の初期値はDoubleとなっているので、必要な場合はIntとしておく。

    push create button

  5. これでインポーターが作られるので、2でインポートしたファイルを右クリック>ReImportすれば、excelファイルの隣にScriptableObjectが生成される。

    以降はxlsファイルの値を変更する度にScriptableObjectの値が変更される。

    ファイルを移動させたい場合、移動させたい場所へScriptableObjectとxlsファイルを移動させ、再度インポーターを作れば移動できる事も確認した。

    scriptable object

ちなみに変数名はヘッダー、値は2行目、クラス名はシート名から拝借する。そのシート名とヘッダーに日本語が入っていると正常に動作しないので注意。またインポーター名はxlsファイルから拝借しているので、これも日本語が使えない(インポーターをファイル毎に分けているのは、複数のxlsファイルをインポートするため)。

 importer settings


とりあえずノーコーディングでココまで出来る。

ツィート数が10回行ったらxlsxも対応するかも

エディタでゲーム再生中に変更した値を停止しても消さない方法

Unityはゲーム再生中のデータを残せない。

例えばPushを押す度にカウントが+1されるプログラムを組む。それをシーンに配置し、ゲームを再生前は0のカウントをプレイ中に5まで増やしたとする。その後再生を停止させてしまうと0に逆戻り、5から進行することは出来ない。

スクリーンショット 2013-09-29 20.14.03

スクリーンショット 2013-09-29 20.13.49

かといって絶対に出来ないという訳ではない。
例えばScriptableObjectを使用する方法がある。

[Unity]ScriptableObjectの使い方・・・?
[Unity]ScriptableObjectのhideFlagをリセット
ScriptableObjectマニュアル(日本語)

簡単な手順はこんな感じ。

  1. データを保持したいクラスを用意する(今回はSample.cs)。
    スクリーンショット 2013-09-29 20.32.19
  2. CreateScriptableObjectPrefubで1で用意したクラスをプレハブ化する。
    スクリーンショット 2013-09-29 20.32.32
  3. 適当なコンポーネントをシーンに配置し、そこから1で作ったプレハブを参照する。
    スクリーンショット 2013-09-29 20.33.00
これで、3で作ったコンポーネントから1で作ったScriptableObjectの値を変更した場合、ゲームの再生を停止した場合もゲームの情報が保持出来る。

スクリーンショット 2013-09-29 20.34.58  スクリーンショット 2013-09-29 20.35.04 

参考資料

UNITE 2013 レポート(4)[Unity]
Unity Serialization(英語)

ちなみに、再生中にコンポーネントをコピーし、終了後にペーストすればゲーム実行時のコンポーネントを適応出来る。単体のコンポーネント情報を保持したい場合はコレでもOK。



間違ってはいけないのが、これはエディタ上でのみ有効な手順という事。要するにiOSAndroidやWeb向けにビルドして出力した場合、ScriptableObjectの中身は変更されず、アプリを終了すると情報は失われる。

この場合、MsgpackやJSON等でシリアライズして保持するのが有効だ。間違っても大規模なデータをPlayerPrefsに突っ込んではいけない。(理由についてはこちらを参照)


ちなみに、エディタ上の単純な情報を保持したいだけならばUnityEditor.EditorPrefsがある。これはどちらかと言えばエディタ拡張で有効と思われ。


ちなみに、シーンを再生中に変更したデータを終了時にも保持させるアセットもある。
こっちの方はScriptableObjectを作らなくても保持出来るので、便利そうだ。

PlayModePersistスクリーンショット 2013-09-29 22.04.21

余りにも便利なので、記事にした。
[Unity]エディタ再生中の情報を停止時も保持するPlayModePersistが予想以上に使いやすい件