再スタート機能の追加
再スタート機能を追加します。ProjectウィンドウのAssetsフォルダの中、Scenesフォルダ内のSampleSceneをリネームし、GameSceneと名称変更します。(右クリックしてRenameを選択し、名称変更)
Scene全体を管理するスクリプトを作成するため、空のゲームオブジェクトを作成します。
Heerarchyウィンドウの+ボタンを押し、Create Emptyを選択します。GameObjectという名称のゲームオブジェクトが作成されるので、GameSceneControllerという名称に変更します。
ProjectウィンドウのAssetsフォルダの中、ScriptsフォルダにGameSceneControllerという名称のスクリプトを作成し、ゲームオブジェクトGameSceneControllerにアタッチします。
スクリプトGameSceneControllerを開き、スクリプトを記述します。
GameSceneController.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; public class GameSceneController : MonoBehaviour { public static int score = 0; private Text scoreText; void Start() { GameObject gameScoreText = GameObject.Find("ScoreText"); scoreText = gameScoreText.GetComponent<Text>(); score = 0; } public void OnFailed() { Invoke("OnLoadGameScene", 1.5f); } private void OnLoadGameScene() { SceneManager.LoadScene("GameScene"); } public void AddScore(int num) { score += num; scoreText.text = score.ToString(); } }
落下判定の処理をControllerスクリプトに追記します。
Controller.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Controller : MonoBehaviour { private float speed = 3f; private float verticalInput = 0f; private Rigidbody CharacterRigidbody; private bool isStop;//追記 void Start() { CharacterRigidbody = GetComponent<Rigidbody>(); isStop = false;//追記 } void Update() { //追記=====> if (isStop) { return; } if (transform.position.y < 0.5) { isStop = true; GameObject gameSceneController = GameObject.Find("GameSceneController"); GameSceneController script = gameSceneController.GetComponent<GameSceneController>(); script.OnFailed(); }//=====>追記 else//追記 {//追記 verticalInput = Input.GetAxis("Vertical"); if (Input.GetKey("right")) { CharacterRigidbody.transform.Rotate(0, 10, 0); } else if (Input.GetKey("left")) { CharacterRigidbody.transform.Rotate(0, -10, 0); } }//追記 } void FixedUpdate() { //追記=====> if (isStop) { return; } //=====>追記 if (CharacterRigidbody.velocity.sqrMagnitude < 5f) { Vector3 CharacterForward = CharacterRigidbody.transform.forward; Vector3 moveVector = speed * (CharacterForward * verticalInput); moveVector.y = 0; CharacterRigidbody.AddForce(moveVector, ForceMode.Impulse); } } }
キャラクターがステージから落下するとリスタートする機能が追加されました。動作確認してみましょう。
アイテムの作成
報酬となるアイテムを作成します。ゲームオブジェクトを作成し、名称をItemとし、マテリアルを設定しておきます。
Itemゲームオブジェクトをステージに配置し、inspectorウィンドウのColliderコンポーネントのIs Triggerにチェックマークを付けます。
Colliderコンポーネントはアタッチするゲームオブジェクトの形状によって特性が変化します(BoxColliderやSphere Colliderなど)。
ColliderコンポーネントのIs Triggerにチェックを入れることで、オブジェクトは重力などの物理法則を影響を受けなくなり、衝突判定が取得できるようになります。
Is Triggerが有効なゲームオブジェクトが他のゲームオブジェクトに接触すると、OnTriggerEnterメソッドが呼び出されます。
Itemスクリプトの作成
ScriptsフォルダにItemという名称のスクリプトを作成し、ゲームオブジェクトItemにアタッチします。Itemスクリプトに以下の内容を記述します。
Item.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Item : MonoBehaviour { void OnTriggerEnter(Collider other) { Destroy(gameObject);//画面からゲームオブジェクトを消す } }
スクリプトがアタッチされたゲームオブジェクトItemをプレファブ機能を使ってインスタンスとして複製します。
ProjectウィンドウのAssetsフォルダに新しくPrefabsという名称のフォルダを作成します。
PrefabsフォルダにHierarchyウィンドウのItemゲームオブジェクトをドラッグアンドドロップで移動します。
Prefabsフォルダに移動したItemゲームオブジェクトをHierarchyウィンドウにドラッグアンドドロップして戻すと、Itemインスタンスが作成されます。同じようにして、Prefabsフォルダ内のItemゲームオブジェクトをHierarchyウィンドウに必要な数だけドラッグアンドドロップしてItemインスタンスを複数生成します。
アイテムにキャラクターが衝突すると画面から消えるようになりました。動作確認してみましょう。
画面にスコアを表示する
UI(ユーザーインターフェース)のCanvasを作成します。Hierarchyウィンドウの+ボタンを押して、UIからCanvasを選択します。
CanvasのInspectorウィンドウのScale FactorからScale With Screen Sizeを選択し、X 500,Y400に設定します。
次に文字を表示するために、Hierarchyウィンドウの+ボタンを押して、UIからTextを選択します。TextのInspectorウィンドウのRect TransformコンポーネントにPos X 180, Pos Y 110, PosZ 0と入力します。TextエリアにSCOREと入力するとゲーム画面に表示されます。Font Sizeは20〜24ポイントにしておきます。
続けて、HierarchyウィンドウのCanvasの子であるUI要素のTextを複製(Duplicate)します。複製されたText(1)の名称をScoreTextに変更します。
ScoreTextのInspectorウィンドウのRect TransformコンポーネントにPos X 280, Pos Y 110, PosZ 0と入力し、Textエリアに数字の0を入力しておきます。
アイテムを取得するとスコアが加算される処理をItemスクリプトに追記します。
Item.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Item : MonoBehaviour { void OnTriggerEnter(Collider other) { GameObject gameSceneController = GameObject.Find("GameSceneController"); //追記 GameSceneController script = gameSceneController.GetComponent<GameSceneController>();//追記 script.AddScore(100); //追記 Destroy(gameObject); } }
アイテムを取得するとスコアが100点加算されるようになりました。動作確認してみましょう。
参考資料
Unityの2021年以降のバージョンでは、テキストを扱うにはTextMeshProが使用されます。TextMeshProを使ったコードを以下に記載します。
GameSceneController.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; using TMPro;//追記 public class GameSceneController : MonoBehaviour { public static int score = 0; private TextMeshProUGUI scoreText;//変更 void Start() { GameObject gameScoreText = GameObject.Find("ScoreText"); scoreText = gameScoreText.GetComponent<TextMeshProUGUI>();//変更 score = 0; } public void OnFailed() { Invoke("OnLoadGameScene", 1.5f); } private void OnLoadGameScene() { SceneManager.LoadScene("GameScene"); } public void AddScore(int num) { score += num; scoreText.text = score.ToString(); } }
Item.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro;//追記 public class Item : MonoBehaviour { void OnTriggerEnter(Collider other) { GameObject gameSceneController = GameObject.Find("GameSceneController"); GameSceneController script = gameSceneController.GetComponent<GameSceneController>(); script.AddScore(100); Destroy(gameObject); } }