おさらい
こんにちは、しーな。です。
3時間で学ぶUnity 入門 2回目です。
前回は、Unityのインストールからゲーム上にオブジェクトを設置していきました。
今回はゲームの仕組みとなるスクリプトを主に作っていきます。
実装 – 障害物を作ろう
前回、壁や床を設置したように、またCubeを追加します。
障害物となる素材がないのでCubeで粘ります。
設置したらScaleを調整し横に長くして、右クリックで名前を変更します。
wall01など任意で変更してください。
次に今回の主役、scriptを追加します。
追加したら、名前をForwardとして編集します。
using UnityEngine;
using System.Collections;
public class Forward : MonoBehaviour {
private Vector3 mPosition;
// Use this for initialization
void Start () {
mPosition = this.transform.position;
}
// Update is called once per frame
void Update () {
mPosition.z -= 0.2f;
transform.position = mPosition;
}
}
ソースコードは上記になります。
C#の規約でclass名とファイル名が一致するようにしてください。
Startという関数はゲームの最初に1度だけ呼ばれる関数で初期化を行う場所です。
Updateは毎フレーム、つまり1秒間に何度も連続で呼ばれる関数です。
mPosition.z -= 0.2f;とすることでキャラクター手前に障害物が移動します。
transformは位置や回転や大きさを操作するオブジェクトです。
その中のtransform.positionにVector3オブジェクトを代入することで移動させています。
保存したらUnityに戻り、ドラッグアンドドロップでwall01に重ねます。
こうすることでオブジェクトとスクリプトが関連付けされ、スクリプトの中のtransform.positionはCubeから作って設置した障害物と座標になります。
次に、全体をコントロールするオブジェクトを作ります。
GameObject>Create Emptyで空のオブジェクトを作り、そこにスクリプトを適応させてゲーム全体のコントロールを行います。
GameObjectをWallControllerに名前を変更してスクリプトを追加します。
スクリプトの名前もWallControllerでOKです。
using UnityEngine;
using System.Collections;
public class WallController : MonoBehaviour {
private float mTimer = 0.0f;
public GameObject prefabA;
public GameObject prefabB;
public GameObject prefabC;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
mTimer += Time.deltaTime;
if(mTimer > 0.5f)
{
int rand = Random.Range(0,300);
if(rand <= 100)
{
GameObject wall = (GameObject)Instantiate(prefabA, new Vector3(Random.Range(-7.0f,7.0f),1.0f,25.0f), Quaternion.identity);
wall.renderer.material.color = new Color(Random.value, Random.value, Random.value, 1.0f);
}
else if(rand <= 200)
{
GameObject wall = (GameObject)Instantiate(prefabB, new Vector3(Random.Range(-7.0f,7.0f),1.0f,25.0f), Quaternion.identity);
wall.renderer.material.color = new Color(Random.value, Random.value, Random.value, 1.0f);
}
else if(rand <= 300)
{
GameObject wall = (GameObject)Instantiate(prefabC, new Vector3(Random.Range(-7.0f,7.0f),1.0f,25.0f), Quaternion.identity);
wall.renderer.material.color = new Color(Random.value, Random.value, Random.value, 1.0f);
}
mTimer = 0.0f;
}
}
}
一定時間おきに、prefabA、prefabB、prefabCのどれかを生成し、ランダムで物体に色を付けています。
このコードを保存して先ほど作った空のGameObjectに貼り付けます。
今度は逆に、HierarchyからProjectへドラッグアンドドロップします。
そうするとProject内にPrefabと呼ばれるデータができます。
Prefabにする事でスクリプトが張り付いた状態でオブジェクトを保持する事ができ、Hierarchyにドラッグアンドドロップすればいくつでも同じものを複製できます。
障害物のレパートリーを増やすためにCubeを追加して、奥に縦長な物体を設置しましょう。
それをwall02と名前を付けたらProjectからForwardスクリプトをドラッグアンドドロップで、wall02を選択した状態のまま右側に引っ張りスクリプトを適応させます。
これもまたPrefabにするのでHierarchyからProjectへドラッグアンドドロップします。
Hierarchy内のwall01やwall02は複製して使うのでPrefabを作ったら削除しましょう。
同じ要領でwall03をつくりPrefabを3つ作りましょう。
public GameObject prefabA;
public GameObject prefabB;
public GameObject prefabC;
これで先ほどの空のGameObject(WallController)に対応するPrefabがそろいました。
HierarchyのWallControllerを選択して、Projectから右側にのPrefabA~Cにドラッグアンドドロップします。
変数をpublicにする事でこのようにソースコードを修正しなくてもスクリプトにデータを送ることができます。
これで、手前に流れてくる3つのPrefabを一定周期でランダムに出す実装が完成しました。
このままではオブジェクトが消えずに残り、Prefab達はステージから外れた無限世界に旅立ってしまうので、触れたらあたり判定が動作してPrefabを削除してくれるようなストッパーを作ります。
Cubeを出して横に長くし、ComponentからRigidbodyを追加します。
Rigidbodyを追加する事でUnityが自動的にあたり判定をとってくれます。
Cubeから作ったストッパーを選択して、Rigidbodyをこのような設定にします。
更にスクリプトをストッパーに追加します。
using UnityEngine;
using System.Collections;
public class Stopper : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.tag != "Player")
{
Destroy(collision.gameObject);
}
}
}
OnCollisionEnterは衝突した瞬間に1度呼ばれる関数で、引数collisionは衝突したGameObjectを持っています。
次に障害物とプレイヤーキャラクターを 区別するためにUnity-chanを選択してタグをPlayerに直します。
これでソースコードのtag != “Player”で判別できるようになりました。
3つのPrefabにもRigidbodyを追加していきます。
下に落ちないようにUse Gravityのチェックを外し、Is Kinematicをチェックして物理演算をOFFにします。
完成
ゲームを再生してみると、障害物がプレイヤーキャラクターを押し出すように動き、プレイヤーキャラはキー操作で動き回り、ストッパーは障害物と当たると障害物を消してくれるようになりました。
ゲームとしては今一つな感じはありますが、とりあえずUnityの大体の基礎はこんな感じになります。
付け足すとしたら、ゲーム開始の秒読みや、どのくらいステージに滞在できたかをタイマーで測る機能くらいでしょうか。
ここまで読んでくれた方、どうもありがとうございました。