まいにちUnity 2023/2/22 Create-with-Code#2
(ほぼ)まいにちUnityチュートリアルをこなしてスキルアップしようの会
Create with Code チュートリアルに挑戦します。
関数の作成
必要なことを実行するために、プログラマー自らが関数を作成する事ができる。
返り値がvoid
void SpawnRandomAnimal(){}
voidの位置に型を表記することで、このメソッドがどのような値を返すかを指定することができる。
「返り値がvoid」とは、「このメソッドが返り値を返さない」
つまり、「ブロック内に書かれた命令を実行するだけ」ということと同義である。
何度も呼び出される可能性のある命令は、メソッドとして定義しておくと、ループ処理やイベント発火時にコードをわざわざ書かなくても良くなり、メンテナンスのしやすさや可読性が向上する。
InvokeRepeatingメソッド
設定した時間(単位は秒)にメソッドを呼び出し、repeatRate 秒ごとにリピートするメソッド。
構文
public void InvokeRepeating (string methodName, float time, float repeatRate);
コライダーとトリガーの追加
「オブジェクト同士が衝突したことを検知する」ためには、コライダーと、その機能のなかのトリガー機能を有効にする必要がある。
Trigger
コライダーを Trigger (Is Trigger プロパティをON) に設定すると、スクリプトのシステムで衝突を検出し OnCollisionEnter 関数を使用してアクションを開始する事ができる。
衝突させるのではなく、あるコライダーが他のコライダーの領域に侵入したことを検出したい場合に使用する。
コライダーを Trigger ( Is Trigger プロパティを使用します) に設定すると、固体オブジェクトとしては動作しなくなり、他のコライダーがすり抜け可能になる。
任意のコライダーがトリガーに設定されたコライダーの領域に侵入すると、トリガーはトリガーオブジェクトのスクリプトにある OnTriggerEnter 関数を呼び出す。
OnCollisionEnterとOnTriggerEnter
OnCollisionEnter
- 物体が衝突したとき(ぶつかったとき)に呼び出される。
- Is TriggerはOFF
OnTriggerEnter
- 物体がすり抜けたときに呼び出される。
- Is TriggerはON
チャレンジ課題に挑戦
ボーナス課題:犬を連続で出さないようにするには?
実装方法を2つ考えてみた。
GameObject.Find関数を使う(非推奨)
public class PlayerControllerX : MonoBehaviour
{
public GameObject dogPrefab;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
//連続で犬を出すことができないようにする
if (GameObject.Find("Dog(Clone)") != null)
{
return;
}
Instantiate(dogPrefab, transform.position, dogPrefab.transform.rotation);
}
}
}
GameObject.Find関数
GameObject Find (string name);
name で指定したアクティブなゲームオブジェクトをHierarchyの上から探索する。
スペースキーが押されたときに、"Dog(Clone)"が生成されるため、Destroyされるまで再生成を防ぐことができるが、Update関数内で毎フレームHierarchyを上から探索する処理が発生するため、パフォーマンス面の低下を招く。できる限り使用は避けたい書き方。
キー押下からの経過時間を計算する方法
public class PlayerControllerX : MonoBehaviour
{
public GameObject dogPrefab;
private float lastTime = 0.0f;
private float interval = 1.0f;
// Update is called once per frame
void Update()
{
// On spacebar press, send dog
if (Input.GetKeyDown(KeyCode.Space))
{
// 現在経過時間 - キー押下時刻 = キー押下からの経過時間
if(Time.time - lastTime < interval)
{
return;
}
Instantiate(dogPrefab, transform.position, dogPrefab.transform.rotation);
lastTime = Time.time;
}
}
}
Time.time
Unityがアプリケーションを開始してからの経過時間(秒)を返します。
つまり、ゲームの開始時点を0秒とし、それ以降の**経過時間*を秒単位で表します。
lastTime = Time.time; で現在時刻をキー押下時刻として代入し、
if(Time.time - lastTime < interval) で経過時間を算出することで命令を制御している。
GameObject.Findのような探索は行われないため、パフォーマンス面ではこちらが優れている。
プリミティブオブジェクトでの制作の重要性
プリミティブオブジェクト
球体、立方体、平面、カプセルなどの簡単なシェイプと、単色のマテリアルを用いたオブジェクト。
なぜプリミティブオブジェクトを使うのか?
リッチで綺麗で豪華なアセットではなく、プリミティブオブジェクトを使用するのは、
グラフィックスを完璧にするために行った小さな調整のために、
開発の際に求められるコア機能性(基本動作・コントロール・ゲームプレイ)の開発時間を減らしてしまったり、要件の変更に伴う余計な修正を行わないようにするためである。
簡単なオブジェクトを用いてコア機能を実装し、その後でグラフィックスを綺麗に仕上げていく流れが望ましいとされる。