再スタート機能の追加
再スタート機能を追加します。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);
}
}
