スコープを意識する

こんにちは,インターン生の鳥井保秀と申します.

この記事では読みやすいコードの書き方と題して,コードの見た目を整え可読性の高いコードを書くための手法をご紹介しています.

最終回である今回はスコープを意識することの重要性についてご説明したいと思います.

スコープとは,Wikipediaによるとプログラミングでのスコープとは,ある変数や関数が特定の名前で参照される範囲のことで,わかりやすく言えばその変数や関数が使える範囲のことを指します.

その表し方は言語によって異なりますが,ここからはc++を例に説明していきたいと思います.

//————————グローバルスコープ開始—
int a;

int function(){ //——関数functionのスコープ開始-
int b;

{ //—————ブロック1のスコープ開始–
int c;
int d;

} //—————ブロック1のスコープ終了–

{ //—————ブロック2のスコープ開始–
int d;

} //—————ブロック2のスコープ終了–

}//———————-関数functionのスコープ終了-

//————————-グローバルスコープ終了——-

(説明のため識別子の名前は適当です.)

例えば上記のようなc++のコードでは変数aが使える範囲はソースコード全体で,変数aのことをグローバル変数と呼び,この変数aのスコープのことをグローバルスコープと呼びます.逆にソースコード全体からは使えないほかの変数のことをローカル変数と呼び,そのスコープのことをローカルスコープと呼びます.例えば変数bは関数function内部でのみ使うことが可能で,ほかの関数からは使うことができません.{}でくくった部分はブロックと呼ばれ,変数cは上のブロック1内部でのみ使うことが可能で,ほかのブロックから使うことはできません.また.変数dのようにスコープが異なれば,同じ名前の変数であっても使用することができます.

今回は説明を省略しますが,名前空間やクラスのスコープも存在します.

グローバル変数のような広いスコープの変数が避けられるのは,それがどこからでも使うことができてしまい,どこでどのように書き換えられているのか把握しづらいのと,広いスコープの変数名が多くなるとその管理が大変になってしまうからです.

前回までの説明で変数や関数の名称をわかりやすくすることをご説明いたしましたが,システムの規模が大きくなり長いプログラムになると,変数を数百個も使用することになり,時には同じ名称を複数使いたいと思うことがあると思います.しかし同じスコープ内で同じ名称の変数を使用することはできません.しかしだからと言って例えば変数名の後ろに数字を付けて区別したりすると,せっかく付けた変数名が分かりにくくなり,コード全体が読みにくくなってしまいます.

そこで,変数のスコープを意識し,識別子のスコープを適切に小さくするよう心がけることで,それを解決することができます.具体的には,なるべく内側のブロックで変数を定義する癖をつけることでその変数のスコープを狭めることができ,変数名の衝突を起こりにくくし,また,見た目上処理に関係する変数の数が少なくなることで,ソースコードを理解しやすくすることができます.

今回はスコープを意識することの重要性についてご説明しました.スコープを意識することで変数が使用可能な範囲を絞り,コードの理解を手助けることができます.

以上今回まで読みやすいコードに関してご紹介してきました.ほかにも読みやすいコードを書くための手法は数多く存在するので,機会があれば調べてみてください.

興味を持たれた方はお気軽にお問い合わせください。

識別子の命名(2)

こんにちは,インターン生の鳥井保秀と申します.

この記事では読みやすいコードの書き方と題して,コードの見た目を整え可読性の高いコードを書くための手法をご紹介しています.

前回は識別子の見た目を整える方法についてご説明いたしました.しかし見た目がきれいでも識別子の意味そのものが分かりにくければ,読みやすいコードとは呼べません.そこで今回は意味を分かりやすくするための識別子の名づけ方についてご紹介いたします.

ただし前提として識別子,変数名や関数名の名づけ方に関しては,使用している言語のルールや個人の好み,所属している組織の方針などもあるため下記のテクニックが常に役に立つわけではありません.そのためプログラミングをするうえで絶対に守らなければならない作法ではなくあくまで一テクニックとしてお読みください.とはいえ,これらを知っておくとほかの人が書いたコードやサンプルのコードなどが読みやすくなると思います.

まず読みやすい識別子の基本は,可能な限りシンプルにかつコード全体としてみたときなるべく英文として自然であるようにすることです.

そのため基本的に動作を行う関数は動詞,変数は名詞として書くことが多いです.

また,配列の名称はArrayを付けるか複数形にした方が親切です.特に複数形にすればそこまで文字数を増やすことなくそのデータが複数であることを示すことができるのでお勧めです.例えば
int book[10];
とするよりも
int book_array[10];
int books[10];
等とした方が,文中で見たときに意味を理解しやすくなります.

bool型などでフラグとして変数を利用する際は,be動詞isや動名詞などで補った方が意味が分かりやすくなります.例えば
bool remove; //削除されたかのフラグ true:削除済み
bool removeFlg; //削除可能かのフラグ true:削除可能
等とするより
bool isRemoved;
bool canRemoved;
等とした方が,コード上で自然な英語に近くなり読みやすくなります.
if(isRemoved){} //if (it) is removed. (削除されたなら)と読めば削除された際の条件であることが分かる
if(canRemoved){} //if can removed.(削除可能なら)と読めば削除可能な際の条件であることが分かる

なるべく一般的な英単語を使用するというのもコードを読みやすくする手法の一つです.私は英語が苦手なのであまり単語を知らないため,辞書を引くか,プログラムで一般的に使用される単語をまとめたサイトを利用することが多いです.特に
「Codic」
プログラマ向けの辞書サイトが使いやすくておすすめです.

また短く書くという観点では略語の知識を持っていることも大切です.例えば
vir: variable: 変数
arg: argument: 引数
dir: directory: ディレクトリ
等は比較的よく利用される略語で,これらを使えば同じ意味の識別子でも短くシンプルにまとめることができます.またよく使用されるので,知っておくと他人の書いたコードの意味が分かりやすくなります.略語に関してもまとめられたサイトが複数存在しますが.
「Acronym Finder」
というサイトが規模が大きくておすすめです.ただし略語はやみくもに使うと他人が見てわかりにくいコードになってしまうため,必要なところで適切に使用するよう心がけましょう.

今回は識別子の命名についてご説明いたしました.識別子の名前を少し意識することにより,ソースコード全体を読みやすくすることができるようになります.

興味を持たれた方はお気軽にお問い合わせください。

識別子の命名(1)

こんにちは,インターン生の鳥井保秀と申します.

この記事では読みやすいコードの書き方と題して,コードの見た目を整え可読性の高いコードを書くための手法をご紹介しています.

前回は読みやすいコメントについてご説明いたしました,しかしコメントが多すぎるとかえってコード全体の見通しが悪くなってしまうため,可能ならばコメントに頼らずともソースコードの意図が理解できるのが望ましいです.そのためにはわかりやすい変数や関数の名前が必要不可欠.そこで今回から二回に分けて読みやすい識別子の命名についてご紹介したいと思います.

ソースコード上で命名が必要な変数名,関数名,クラス名等これらはまとめて識別子と呼ばれますが,これらが読みにくいと,当然コード全体が読みにくくなってしまいます.そのためまず今回は識別子の見た目を整えることを考えます.

識別子の見た目を表す記法には主に以下のようなものがあります.

・パスカルケース(アッパーキャメルケース):すべての単語の先頭を大文字にする.クラス名に使用される.
 例:PascalCase
・キャメルケース(ロウワーキャメルケース):二番目以降の単語の先頭を大文字にする.変数名や関数名に使用されることが多い.
 例:camelCase
・コンスタントケース(アッパースネークケース):すべての単語を大文字で書き,単語間をアンダーバーでつなぐ.定数名に使用される.
 例:CONSTANT_CASE
・スネークケース(ロウワースネークケース):すべての単語を小文字で書き,単語間をアンダーバーでつなぐ.関数名や変数名に使用されることが多い.
 例:snake_case
・チェインケース(ケバブケース):単語を小文字で書き,単語間をハイフンでつなぐ.HTMLのclass名やid名に使用される.
 例:chain-case

例えば私はC++での開発時はおおよそ
変数名: スネークケースorキャメルケース
関数名: キャメルケース
定数名: コンスタントケース
クラス名: パスカルケース
名前空間名:パスカルケース
となるようにすることが多いです.

このあたりのルールは人や組織によって異なり,何が良いというわけではありませんので,組織の方針や周りの状況を見て使い分ける必要がありますが,プロジェクトの開始時に自分の中で何かしらルールを作っておいた方がコードの見栄えが良くなります.

今回は識別子の見た目を整える重要性についてご説明いたしました.見た目を整えることによりコード全体の見通しが良くなり,同じ内容のコードでもストレスなく目を通すことができるようになります.

しかしながら,見た目がきれいでも識別子の意味そのものが分かりにくければ,読みやすいコードとは呼べません.そこで次回は識別子の意味を分かりやすくするための識別子の名づけ方についてご紹介する予定です.

興味を持たれた方はお気軽にお問い合わせください。

コメントの書き方

こんにちは,インターン生の鳥井保秀と申します.

この記事では読みやすいコードの書き方と題して,コードの見た目を整え可読性の高いコードを書くための手法をご紹介しています.

前回はコードの可読性を意識することの重要性,可読性を意識することのメリットをご紹介しました.ではどのようにすれば可読性が高くなるのか,第二回である今回は読みやすいコメントの書き方について,私の主観を交えながらご説明したいと思います.

読みやすいコメントの話をするにあたり,まず初めに述べておくべきことは,どんなコメントでもないよりはある方がましということです.これは所属している研究室でシステム改修を行っている一個人の経験からくる意見ですが,例えば,
・メモ書き程度の粗雑なコメント
・誤った内容のコメント
等といった読みにくいコメントであったとしても,コメントがない部分よりはある部分のほうがはるかに問題発生個所を特定しやすく,修正が容易です.そのため慣れないうちはコメントの読みやすさを意識しすぎずに,とにかくコメントを書く癖をつけたほうが良いと思います.

そのことを前提に,しかしながら読みにくいコメントが多い部分はやはり読みにくく,ソースコードの理解に時間がかかる要因となってしまうため,できればそのようなコメントはないほうが望ましいです.ではどのようにすれば読みやすいコメントになるのでしょうか.

まずメモ書き程度の粗雑なコメントについてですが,もともとコメントはメモをするものなのでこれ自体に問題はありません,しかし少し工夫をすることでより読みやすいコメントに変えることができます.それはコメントに見出しを付けることです.例として
TODO: 後でやること
FIXME: 要修正
WARNING: 注意
HACK: 正しいがきれいではないコード
XXX: なぜ動くのかわからないコード
といったコメントの意味を示す文字列をコメント本文の前に加えるという記法(アノテーションコメント)があります.この記法を用いることでコメントが何を表しているのか瞬時に理解することができ,大きな手間をかけることなくコメントを読みやすくすることができます.

次に誤った内容のコメントに関してですが,誤った内容のコメントが発生する原因は大きく2種類に分けられると考えます,一つはプログラムの理解不足やソースコードそのものの誤りからソースコードとコメントが乖離してしまうケース,もう一つはプログラムの修正がコメントに反映されていないケースです.前者に関してはコメントの書き方の工夫では対処できず,製作者の理解やソースコードの修正が必要となりますが,後者に関してはコメントに内容を意識することで多少防止することができる可能性があります.それはコメントを書く際にそのコードが何をしているのかではなくそのコードが何をしたいかを意識することです.言い換えれば,コードの手法ではなくそのコードを書いた目的を記述するということです.プログラム修正において,同じブロック内ならば目的が大きく変わることは手法が変わることに比べて比較的少ないため,目的を書いておくことによってソースコードの修正の影響を受けにくくなり,逆に手法が固定されないことでソースコードの修正がしやすくなります.

今回は読みやすいコメントについてご紹介しました.読みやすいコードのためには,少なくともソースコードを読んで意図の読み取れない部分にはコメントが必要となるため,読みやすいコードのためには読みやすいコメントを書けるようになる必要があります.

しかし前半の話と矛盾するようですが,コメントが多すぎるとかえってコード全体の見通しが悪くなってしまいます.もし,ソースコードの変数や関数名から意図が読み取れるならばコメントは最小限で済みます.そのため次回はコメントに頼りすぎずに読みやすいコードを書くために,変数や関数の命名についてご説明しようと思います.

興味を持たれた方はお気軽にお問い合わせください。

読みやすいコードのすゝめ

初めまして,インターン生の鳥井保秀と申します.

今回から5回に分けて,主にプログラミング初中級者に向けて,読みやすいコードの書き方と題し,可読性の高いコードを意識するメリットとそのための手法の一部をご紹介したいと思います.対象のプログラミング言語は特定の言語に絞らず,プログラムを書く上で普遍的なルール,ソースコードをテキストとして読んだ際の見た目をきれいにするという観点を主軸として解説していく予定です.

プログラミングをやったことがある人ならば,一度くらいは変数名をaやbとしたり,自分にしかわからない略語を使ってしまったり,関数名をfunction()などとしてしまったことがあるのではないでしょうか,そしてそれが可読性を下げる悪いことであるということもまたご存じかと思います.しかしながらソースコードの可読性を常に意識している人は意外と少ないのではないでしょうか.

そこで初回である今回は読みやすいコードのすゝめとして,コードの可読性を意識する重要性,可読性を意識することでどのようなメリットをがあるのかを説明していきたいと思います.

まず,なぜ読みやすいコードを書くことが重要かといえば,システム開発をするうえではソースコードを読むという行為が何度も繰り返されるからです.例えばバグを修正したり,機能を追加したり,性能を改善しようとする際には必ずコードを読むという行為があります.実際に,学校の課題レベルの小規模なシステムであってもコードを読み直さないということはないでしょう.大規模なシステムではなおさらです.そのため読みにくいコードではこれらの行為ごとに時間がかかってしまい,システムの完成が遅れてしまいます.

また,読みにくいコードはバグが発見しにくいという問題もあります.システム全体で何かバグがあることが分かっても,読みにくいコードでは問題の発生場所を絞り込むのが難しくなってしまい,結果として書き換えなければならない箇所が広くなってしまいます.これは労力的にも無駄が多いですし,システムを大幅に書き換えると新たなバグが混入する可能性もあります.

他には可読性を意識することのメリットとして,他人のコードが読めるようになるというのもあります.例えば,特にうまい人が書いたものや多くの人の手によって作成され公開されているライブラリの中身などは,今後紹介するものも含めた可読性を上げるためのテクニックが多分に使われています.そのためテクニックを知っていることで,これらを読む手助けになります.

以上,今回は私の思うコードの可読性を意識する重要性やメリットについて紹介しました.

次回からは具体的にコードの可読性を上げる手法について紹介していく予定です.引き続きよろしくお願いします.

興味を持たれた方はお気軽にお問い合わせください。

Unityで値を触りやすいデータを作ろう -拡張編3-

こんにちは。インターン生の東谷太喜です。

今日の記事が最後となります。Scriptは前回の記事のものになっております。

今回は値の入力ミスを回避するために入力の制限をしていこうと思います。

遷移シーンの入力を「String」から「SceneAsset」に変更話していきます。

1.特定のオブジェクトタイプのみの入力場所を作成

まずはシーンの選択ができるようにします。

Editor内「保持させる変数」を一つ追加します。

private Object 保持させる変数名;
保持させる変数名 = EditorGUILayout.ObjectField(“表示名”, 保持させる変数名, typeof(SceneAsset), true);
を新しく書きます。

「保持させる変数名」と「表示名」は自由に名前を付けてください。

私は「sceneObj」と「遷移シーン」にしておきます。

Editorに戻り確認をしてみると、シーンのみを選択できるようになっています。

2.シーン名をScriptableObjectに文字列で保存

ScriptableObjectに保存をしていないため、インスペクターを変えると値がリセットされてしまいます。

そこで次に、Stringで値を保存させます。

EditorGUI.BeginChangeCheck();
//変更検知範囲
if(EditorGUI.EndChangeCheck())
{
var serialized = serializedObject.FindProperty(“保存先の変数名”);
serialized.stringValue = 保持させる変数名.name;
}

これで「String」型の保存ができます。

他の型の保存方法については、今回は紹介しません。

変更をし続けるため検知をした時のみ、値を保存するようにする

EditorGUI.BeginChangeCheck();
EditorGUI.EndChangeCheck();
を使用しています。

「保存先の変数名」と「保持させる変数名」を私は「levelName」と「sceneObj」にしています。

あとは、値がNullになった際に文字列を空白にする処理を書き足せば保存処理の完成です。

試しに保存されている値も一緒に表示させてみましょう。

シーンの選択を変更した際に、文字列が変化していれば正常に動作しています。

3.文字列から「SceneAsset」を読み込む

この状態では、ScriptableObjectをインスペクターから閉じてしまうと再度開いた際に値が「None」になってしまいます。

そこで次にScriptableObjectの文字列でシーンを探し、Editorの保持先の変数に保存する処理を書きます。

開いた際の処理の呼び出しは、Unity内の関数に存在している

public void OnEnable() {}
を使用します。

では、ScriptableObjectの保存している値を取得する処理を書きます。

var serialized = serializedObject.FindProperty(“取得する変数名”);
string 変数名 = serialized.stringValue;
取得する変数名と変数名は自由な名前で大丈夫です。

foreach (var guid in AssetDatabase.FindAssets(“t:Scene”))
{
var path = AssetDatabase.GUIDToAssetPath(guid);
var asset = AssetDatabase.LoadMainAssetAtPath(path);

if (asset.name == sceneName)
{
sceneObj = asset;
break;
}
}

最初に「SceneAsset」に絞って検索をするために

AssetDatabase.FindAssets(“t:Scene”)
を使い、文字列のパスを取得します。

このままでは、ロードできないためアセットパスを

AssetDatabase.GUIDToAssetPath(string guid);
で変換します。

最後に見つけたオブジェクトをロードする

AssetDatabase.LoadMainAssetAtPath(string assetPath);
で取得します。

取得したオブジェクトの名前が一致したとき保存させれば、開いたときに取得が完了しているということです。

シーンの名前を変更した場合取得できなくなるので「LogError」を書き足して完成です。

終わりに

ここまで記事を見てくださった方、ありがとうございました。

他にも工夫できる点がたくさんありますので、是非とも研究してみてください。

以上で全5回の記事は終了となります。ありがとうございました。

Unityで値を触りやすいデータを作ろう -拡張編2-

こんにちは。東谷太喜です。

前回の -拡長編- の続きとなりますので、前回の記事を元に書いていきます。

前回は4.まで進み、ゴールスコアを表示するところまで書きました。

5.変数名表示の変更

ここで何の値かを明確にするため、変数名を日本語表示に変更します。

変更の仕方は簡単です。

19行目、EditorGUILayout.PropertyField(serialized)に第2引数を追加するだけで出来ます。

なので、

EditorGUILayout.PropertyField(serialized, new GUIContent(“表示したい名前”));
のように変更します。

「GUIContent」は、インスペクター上の表示名などを変えるものだと思ってください。

私は、”表示したい名前” を “目標スコア” にしておきます。

6.表示変更用の関数の作成

他の変数に、同様の処理を行う際にコピペよりは関数を作成したほうが増やすのが圧倒的に楽になります。

public void 関数名(string 引数名1, string 引数名2) { }
を関数で新しく書きます。

関数名、引数1,2は自由にして大丈夫です。

4. と 5. で書いた2行の処理を移動させ、処理を一部書き換えます。

var serialized = serializedObject.FindProperty(引数名1);
EditorGUILayout.PropertyField(serialized, new GUIContent(引数名2));
に変更しておきます。

引数名1,2は、関数の引数名に合わせて変更してください。

あとは「OnInspectorGUI」内に作成した関数を書いていきます。

関数名(引数1,引数2);
引数1に「拡張したいクラスに存在し、対象にする変数名」

引数2に「インスペクターに表示される文字」を書きます。

最後に、「LogError」を書いて、表示させる変数分書けば完成です。

これで変数名表記から日本語に変更できました。

おまけ

「GUIContent」には2つの引数があります。

この機能を使えばGUIContentのアイコンを変えることができます。

面白いので是非見やすいように色々と試してみてください。

今回はここまでにします。

次回は、値エラーを回避する拡長編3をして書いていきいます。

Unityで値を触りやすいデータを作ろう -拡張編-

こんにちは。インターン生の東谷太喜です。

本日は、ScriptableObjectのEditor拡張について書いていきます。

前回のデータを見やすく、使いやすいように改良していきます。

拡長編では、最終的にここまで説明していこうと思います。

1.Editorフォルダを作成・Scriptの作成

Editor拡張は必ず「Editor」という名前のフォルダ内にScriptを置かないといけません。

Editorフォルダ内に新しいフォルダを作成し、その中にScriptを置いても大丈夫です。

なので、カテゴリ毎に分けることをお勧めします。

作成したScriptの名前は、自由にして大丈夫です。私は「StageDataEditor」にします。

作成後はScriptを開いてください。

2.Editor拡張の準備

作成し、開いたScriptを編集していきます。

Script内、クラス宣言の上部に書かれている using の欄に新しく1行追加します。

using UnityEditor;
を新しく追加してください。

その後、クラスの宣言の上の行に

[CustomEditor(typeof(拡張したいクラス名))]
を書きます。

拡張したいクラス名 の場所は前回の記事に作成したクラスを書きます。

そして、継承先を「Monobehaviour」から

Editor
にします。

これでエディタ拡張の準備はできました。

3.OnInspectorGUIの作成
インスペクターの表示をしている関数を書きます。

public override void OnInspectorGUI() {}
関数を作成した際に「base.OnInspectorGUI()」が自動生成されます。

3.5では、その説明をしていきます。

3.5. OnInspectorGUI の必要な知識

まずインスペクターのEditor拡張をする上で、知っておく必要がある関数の説明をしていきます。

base.OnInspectorGUI();
元々インスペクターに表示されてた内容をこれで表示させてるという認識で大体はあってると思います。

厳密には、この関数は拡張対象であるクラス内のインスペクター表示処理を呼び出しています。

なので消した場合、拡張対象が表示をしているインスペクター内の表示が全て消えます。

今回は元のインスペクターの表示をする予定はないので、コメントアウトしておきます。

serializedObject.Update();
この関数はシリアライズされたオブジェクトの最新データを取得する関数です。

この関数を書いておかないと、表示されるデータがおかしくなることがあるので書いておきます。

serializedObject.ApplyModifiedProperties();
この関数は内部キャッシュに変更点を保存する関数です。

インスペクター上で値を変更してに、この関数を書いていない場合は値が保存されませんので書いておきます。

4.OnInspectorGUIの編集

最初に、3.5で説明した2つの関数を書きます

serializedObject.Update();
serializedObject.ApplyModifiedProperties();
書く場所はこの2つの関数の間の行です。

処理の順番を間違えた場合に値が変わらない、保存されない可能性があるので注意してください。

まずはこの2行を追加し、スコアを1行だけ表示させてみましょう。

var serialized = serializedObject.FindProperty(“拡張したいクラスに存在する変数名”);
EditorGUILayout.PropertyField(serialized);
私の場合は、「”拡張したいクラスに存在する変数名”」の場所を、「”goalScore”」としました。

今回はここまでにしようと思います。

次回はUnityで値を触りやすいデータを作ろう -拡張編2-です。

Unityで値を触りやすいデータを作ろう -作成編-

こんにちは。インターン生の東谷 太喜です。

本日はScriptableObjectの実際の作成方法について書いていこうと思います。

1.C#Scriptの作成

Unity内の作業を行うフォルダ内で右クリック、Create→C#Scriptを選択。名前を好きに変更しましょう。

私はStage用のデータを作成しますので、「StageData」にします。

Asset直下以外、スクリプト用のフォルダなどに置くことをお勧めします。

2.ScriptableObjectに編集

早速プログラムを書いていくので、1.で作成したScriptを開きます。

継承先を 「Monobehaviour」から

ScriptableObject
に変更します。

Classの前の行に

[CreateAssetMenu(menuName = “メニュー名”)]
を書きます。

私はメニュー名の中身を「Data/StageData」と書きました。

このコードは、Unity内のアセットのメニューに表示させるためのものです。

3.データをアセットフォルダに作成

Unityのエディタに戻り、データを作成したいフォルダ内で右クリック、Create→”メニュー名”で作成でします。

“メニュー名”は2.で作成した ( menuName = “メニュー名” ) の””内の文字列に沿ったものが表記されます。

文字列に「/」を入れた場合折り畳みになりますので、カテゴリ毎に分けることもできます。

私は文字列に「Data/StageData」と書きましたので、折り畳まれて表示されています。

4.作りたいデータの値を書く

現状はまだ何も値を書いていませんので、何もない状態です。

値を作成する際に一つ問題点があります。

private や protectedなど変数をカプセル化して作成した場合、表示されないということです。

public で作成した場合はインスペクター内に表示されます。


そこで、変数の後ろに [SerializeField] を書き足します。

変数の後ろに付けることで、変数をシリアライズ化の対象にすることができます。

対象にすることで、private や protected であってもインスペクター上に編集可能なフィールドで表示されます。

なので作る際は 『 [SerializeField] private int score = 100; 』のように書くことをお勧めします。

最後に他のクラスで取得できるようにGetterを作成すれば完成です。

今回はScriptableObjectの作成について書いていきました。

次回はScriptableObjectのEditor拡張について書いていきます。

Unityで値を触りやすいデータを作ろう -導入編-

こんにちは。インターン生の東谷太喜です。

本日から簡単なゲームを作る際にちょっと便利なUnityのシステムを紹介していこうと思います。

今回はScriptableObjectについて紹介しようと思います。

ゲームがほぼ完成し、ステージセレクトでゲームの難易度を自由に変えたい。出現する敵の種類をステージ毎に変えたい。という経験ありませんか?

そんな時におススメするのがScriptableObjectです。

メリット:

同じ敵でもパラメーターが違う敵を作成できる。

変えたいパラメーターをInspector内で即座に変えられる。

そのためバランス調整が簡単になるため、レベルデザインしやすい。

デメリット:

ゲーム実行中のセーブデータとしては使えないという罠がある。

例.

このような形でまとめておけば、時間制限やBGMなどをステージ毎に簡単に変えられるようになります。

シーンに配置されたオブジェクトの値を1つ1つ別シーンに移動→値を変える作業をするよりは1つのフォルダ内に存在するファイルを変更を行う方が、非常に効率的です。

そして現状、このデータが何を指しているのかがわかりません。理解できているのは作成し、実装した本人だけです。

そこで活躍するのが、UnityのEditor拡張です。

先程のパラメーターは英語で変更をした際、何の値が変わるのかが不明瞭です。

そこでエディター拡張をしてみましょう。

分かりにくいデータを誰でもわかるように書き換えることができました。

レベルデザインを他のプランナーやデザイナーにしてもらう場合はエディター拡張と合わせて実装を行うと非常に喜ばれます。

また、むやみに変更してほしくない値を非表示にすることもできるので、編集するリスクを抑えることもできます。

様々な人が見て触るデータというのは、触りやすく編集しやすいものでなければなりません。

メリットについて話してきましたが、次はデメリットです。

デメリットとして、ゲーム中に読み込みはできても書き込みができません。

書き込む処理にはUnityEditorの参照が必要です。ゲームのビルド後はUnityEditorへの参照ができなくなります。

つまり、ビルド後の書き込み処理が出来ないためプレイデータのセーブなど、セーブデータとしてScriptableObjectを使用することはお勧めできません。

なので、デフォルトの値を渡すなどの用途で使うことをお勧めします。

今回の内容はいかがだったでしょうか。

今回はざっくりとした説明でした。次回からは今回貼られていた画像のように作成の仕方を書いていきたいと思います。

次回は、ScriptableObjectを作成の仕方についてです。

間違っている点や、気になった点などございましたら、コメントにて書いていただければ幸いです。