UnityのC#のスクリプトの書き方
UnityのC#の書き方を紹介していく。UnityとVisual studioの連携を行っていない場合には先に以下の記事を確認してみてほしい。Visual studioとの連携手順
Visual studioには強力な支援機能が搭載されており、連携しない手はないので、ぜひ確認してみてほしい。
また、Unityの基礎知識や操作などがわからない場合は先に以下の記事を確認してほしい。
Unityの基礎まとめ
この記事ではVisual studioと連携している前提でC#の基本的なスクリプトの書き方を紹介していく(少しくらいわからないところがあっても大丈夫だ。ひとまず読み進めていってほしい)。
UnityのC#の書き方目次
スクリプトを開く参照表示の削除
usingについて
classについて
コメントについて
メソッド・インスタンス化・ログ
プログラムの処理順序
目次にもどる
スクリプトを開く
まずは整理のためにプロジェクトビューにScriptというフォルダを作成するのをおすすめする。そのフォルダの中で右クリックし、「Create」→「C#Script」のように選択しよう。
スクリプトファイルが作成されるので、自分の好きな名前をつけよう(ただし一部使ってはならない名前もある。例えばifという名前をつけるとエラーが出る。if文というものがあらかじめ用意されておりそれと名前が被るためである。名前をつけてエラーが出る場合は新しくスクリプトを作り直そう)。
スクリプトファイルをダブルクリックして開こう。
既に色々書かれているので説明していく。
目次にもどる
参照表示の削除
スクリプトを開くと以下のような3つの表示が出る。この表示は非常に邪魔であり、実用性は皆無なので削除するのをおすすめする。
上部のメニューから「ツール」→「オプション」のように選択する。
「テキストエディター」→「すべての言語」→「CodeLens」のように選択し「CodeLensを有効にする」の項目のチェックを外して「OK」を押す。
これで以下のように参照表示が削除される。
目次にもどる
usingについて
usingは名前空間(クラスを種類ごとに分けて管理するための機構)の呼び出しを行うことができる(他にも使い方はあるがひとまずおいておく)。スクリプトファイルをダブルクリックして開いた際にも以下のようにusingが使われていることがわかる。
まず、最初の2行について。
using System.Collections;
using System.Collections.Generic;
これはC#のSystemという名前空間を利用することを宣言している(あらかじめ構築されている)。
次にその下にある1行について
using UnityEngine;
これはUnityが用意したエンジン(システム)を利用することを宣言している(あらかじめ構築されている)。Unityの機能は大量にあるため、後から機能指定して呼び出す手間を避けるため、この宣言で使えるようにしている。
なお、各行にある最後の;(セミコロン)は1つの命令の終了を意味している。
また、文字はもちろんスペースまで半角であることも覚えてほしい。基本的に全角は使ってはならない。
それから同じ文字でも大文字と小文字では違うことも覚えておこう。大文字小文字が違うと動かない。
目次にもどる
classについて
classは簡単に言えば「設計図」である。 内部の構造を示したり、外部からどのような操作をすることが出来るのかを決定することができる。スクリプトを見ると以下でclassが使われているので解説していく。
public class kihon : MonoBehaviour
まず、classの後にきている「kihon」はクラスの名前だ。ここではスクリプトファイルにつけた名前がそのままクラス名にされている(自分の場合はスクプリト名にkihonとつけたので、それがクラス名になっている)。
最初の「public」は公開することを示している。公開することでそのクラスが他のスクリプトなどのファイルからもアクセスできるようになる。
:から半角スペースを打った後の一番最後に「MonoBehaviour」という記述があるが、それはMonoBehaviourというクラスを元にすることを示す。あるクラスを元にすることを継承という。
「MonoBehaviour」はあらかじめUnity上で定義されている親となるクラスだ。親クラスを継承して様々な子クラスを作成し、後述するメソッド(クラスの中身)を記述していくことで様々な動作を行うことができる。
なお、{ から }までの間がクラスの範囲を示している。
目次にもどる
コメントについて
コメントは// からはじまり、プログラムの動作には関わらない(よって全角で日本語で書いてもOKである)。スクリプトを見ると以下でコメントが使われているが、内容を説明するために書かれている。
/*と*/ではさんでやると複数行のコメントも可能である。
これから学習を進めていけばだんだん複雑な書き方も行っていくことになる。しばらくした後に書いたプログラムを見て意味がわからないということがないようにコメントをしっかり書いておくように心がけよう。
目次にもどる
メソッド・インスタンス化・ログ
メソッドはデータに対しどんな処理を行うかを示すプログラムで、クラスの中身と言える存在である。スクリプトを見るとメソッドが前述したクラスの中に以下のように2つ記述されている。「Start」と「Update」だ。
StartもUpdateも特殊なメソッドであり、Unity側から自動的に呼ばれるのが特徴だ。
Startはクラスがインスタンス化し有効である場合にUnity側から1回だけ呼ばれる
Updateはクラスが有効である場合に毎フレームごとにUnity側から呼ばれる(Unityなどで作られたゲームの多くは1秒が60フレームで構成されている。つまり1/60秒に1回呼ばれると考えていい)
StartとUpdateの前についている「Void」は何も返さないことを示す(これについてはひとまずおいておこう)。
上記の説明を読んでも意味がわからない人もいると思う。そこで以下のように記述してみよう。
{ から }までの間がメソッドの範囲を示している。
Debug.Log("最初の1回だけ");をStartのメソッド範囲内に記述する。
Debug.Log("定期的");をUpdateのメソッド範囲内に記述する。
なお「Debug.Log」はUnityの機能の一つでありログを出してくれる。エラーが出る場合など、どこが悪かったのかを調べる際によく使われる。"と"の間は文字と認識されており全角でも大丈夫である。
作業が終了したらスクリプトを保存する(ファイル→全て保存を選択してもいいし、×ボタンを押して閉じれば保存するかどうか聞かれる。Ctrl+Sキーでも保存でき便利なので覚えておくといい)。
ヒエラルキー欄に例えばCubeのゲームオブジェクトを作ってみよう(何でもいい)。
作ったスクリプトファイルをCubeのインスペクター欄の「Add Component」に向かってドラッグ&ドロップする。
この操作をアタッチという。
アタッチしたことでインスペクター欄に以下のように設計図が実体化した。
これをインスタンス化という。
この状態で再生ボタンを押してみよう。
再生ボタンを少ししたらもう1回押して再生を止めよう。そしてコンソールウィンドウを確認しよう。
Startに配置した「最初の1回だけ」のログは最初の一度出てきている。再生時にはインスタンス化がリセットされ再度インスタンス化が行われる。スクリプトが有効か無効かは以下のチェックで決められる(チェックがついていれば有効。チェックを外してもインスタンス化はしている)。
アタッチ時にデフォルトではチェックがついており、インスタンス化&有効というStartが動く条件を満たしているため、「最初の1回だけ」のログが最初の一度だけ出てきている。
「最初の1回だけ」のログの後にはUpdateに配置した「定期的」のログが大量に表示されている。スクプリトが有効でありUpdateメソッドが動く条件を満たしているため、毎フレーム処理が行われ続ける。
以下のチェックを外した場合、再生ボタンを押しても、コンソールウィンドウにログは流れてこない。
なお、スクリプトのアタッチ状態を解除したい時には点が3つついたボタンを押し、「Remove Component」を選択すればいい。
目次にもどる
プログラムの処理順序
プログラムがどの順番で処理を行うのかを紹介していく。まず、以下のようにStartとUpdateの位置を入れ替え、Updateのメソッドを上に配置してみよう。
この状態で再生してもコンソールウィンドウにログが出る順に変化はない。
Startのほうが先にUnityから呼ばれると決まっており、同じ処理となる。
続いてメソッドに以下のような記述を行おう。
StartとUpdateの両方に複数のDebug.Logを記述した。この状態で再生すると以下のようになる。
Startに書いたログ A、B、C、D、Eが順に流れ、その後はUpdateに書いたログが1、2、3、4、5と順に流れてそれを繰り返す。
メソッド内ではプログラムが上から下へ処理されていくことが確認できる。
続いてスクリプトファイルをもう一つ作成して同じゲームオブジェクトにアタッチする。
何でもいいので2つのスクリプトファイルそれぞれのSTARTとUPDATEに異なるLOGを入力しよう。
自分は1つ目のスクリプトファイルのSTARTからログ「1」、Updateからログ「3」、2つ目のスクリプトファイルのSTARTからログ「2」、Updateからログ「4」が出るようにしてみた。
その上で再生すると以下のようになった。
どちらのスクリプトファイルも呼び出されている。そして自分の環境では先に呼び出されたのは2つ目のスクリプトファイルであった。2つ目のスクリプトのSTART→1つ目のスクリプトのSTART→2つ目のスクリプトのUPDATE→1つ目のスクリプトのUPDATEの順で処理が行われた。どのスクリプトが先に呼び出されるかはランダムである。自分の環境では2つ目のスクリプトから呼び出されたが、別の人のPCなら1つ目から呼び出されることもある。
自分の環境で問題なく動くので問題ないと思って、別の人にゲームをやらせたら動かないといった問題が起こる場合があるので要注意だ。
このランダムなスクリプト実行順序を制御する方法がある。
Unityで「Edit」→「Project Settings」のように選択。
「Script Execution Order」タブを選択する。
ここではスクリプトの実行順を設定でき、上にあるほど優先して実行される。ドラッグ&ドロップでスクリプトファイルを持ってくることができる。
優先して処理したいスクリプトファイルはDefault Timeより上、実行順が遅くていいスクリプトはDefault Timeより下に配置して保存しよう。今回は1つ目に作ったスクリプトファイルの実行を優先するようにして再生した。
1つ目のスクリプトファイルが先に呼び出され、Startのメソッドから出るようにしたログ「1」が一番最初に表示されるようになるのが確認できた。
「Script Execution Order」は便利であるが、使いすぎるとメンテナンスが困難となるので注意だ。できるだけ実行順に左右されないようにスクリプト作成を行っていきたい。