この記事でのバージョン
Unity 2018.4.8f1
はじめに
アセットストアのアセットや外部SDKなどをUnityで使う際、
ScriptableObjectが使われてる事はよくあります。
そしてそのScriptableObjectの値を使いたいのに、
外部からは取得出来ない形に実装されているという場合は少なくありません。
という事で今回はScriptableObjectの内容をで無理やり取得する方法を3パターンほど紹介する記事です!
なお、ScriptableObject以外のアセットやプログラムに使えるものもあります。
なお、どのパターンでも以下のような
privateなフィールドのみを持ったScriptableObjectを例に使っています。
using UnityEngine; /// <summary> /// サンプル用のScriptableObject /// </summary> public class SampleScriptableObject : ScriptableObject { //外部から取得できない文字列 [SerializeField] private string _text = "SampleText"; //外部から取得できない数字 [SerializeField] private int _num = 58; }
Reflection
C#ではReflectionという機能で
オブジェクトから型情報を得たり、クラスかどうか調べる事が出来ます。
そして、そのReflectionを使えばPublicではないフィールドの値を読むことも可能です。
//ScriptableObjectをロード var sample = AssetDatabase.LoadAssetAtPath<SampleScriptableObject>("Assets/SampleScriptableObject.asset"); //_textというPublicではないフィールドの情報を取得 FieldInfo fieldInfo = sample.GetType().GetField("_text", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance); //_textの値を取得 Debug.Log((string)(fieldInfo.GetValue(sample)));
TextAsset
Unityは.txtなどのテキストデータをTextAssetとして読み込む事が出来ます。
なお、Resources以外からアセットをロードする場合はAssetDatabase(エディタ上専用)を使います。
実際にコードにしてみると以下のような感じに。
//テキストを読み込み、内容をログで表示 var textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/SampleText.txt"); Debug.Log(textAsset.text);
ただし、ScriptableObjectのようなテキストの拡張子でないものをTextAssetにする事は出来ません。
なので、そういうものをTextAssetで読み込みたい場合は、拡張子を変更したものをコピーして使います。
なお、アセットをコピーしたい場合もAssetDatabase(エディタ上専用)を使います。
実際にコードにしてみると以下のような感じに。
//元のScriptableObjectとそれをテキストデータに変換した時のパス string scriptableObjectPath = "Assets/SampleScriptableObject.asset"; string textAssetPath = "Assets/SampleScriptableObject.txt"; //ScriptableObjectをテキストデータとしてコピー AssetDatabase.CopyAsset(scriptableObjectPath, textAssetPath); //テキストデータをロード、内容をログで表示 var textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(textAssetPath); Debug.Log(textAsset.text); //テキストデータを削除 AssetDatabase.DeleteAsset(textAssetPath);
ちなみに、例えばマテリアルの内容を無理やり取得するなど、ScriptableObject以外にも使えます。
StreamReader
C#にはStreamReaderという機能があり、これでテキストファイルを読み込む事が出来ます。
もちろんこの機能はUnityでも使えますし、しかもどのアセットでもテキストとして扱えます。
//ScriptableObjectの情報を取得 string assetPath = Path.Combine(Application.dataPath, "SampleScriptableObject.asset"); FileInfo fileInfo = new FileInfo(assetPath); //ScriptableObjectをテキストとして読み込む using (StreamReader reader = new StreamReader(fileInfo.OpenRead(), Encoding.UTF8)){ //全テキスト取得 Debug.Log(reader.ReadToEnd()); }
もちろん、このやり方もScriptableObject以外でも使えます。