前回はプレイヤーや敵のスコアをリアルタイムで表示するUIを作成しました。
前回の記事:
今回の記事ではタイトルを作ってから勝敗判定とゲームの流れを作成していきます。
タイトルの作成
それではまずタイトルの方を作成してきます。
スクリプトの作成
「RunAndJoinSceneMangaer」コンポーネントを次のように修正して下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
// RunAndJoinSceneMangaer.cs タイトル処理の追加 //次のものを修正 public void StartGame() { if(_currentCoroutine != null) { StopCoroutine(_currentCoroutine); } UI.gameObject.SetActive(true); TitleUI.gameObject.SetActive(false); _currentCoroutine = StartCoroutine(GameLoop()); } IEnumerator GameLoop() { var map = Object.FindObjectOfType<Map>(); map.InitMap(); var player = Player; player.transform.position = PlayerStartPos; player.MemberCount = 0; while (true) { UpdateMemberCountUI(); yield return null; } } //次のものを追加 [SerializeField] Canvas TitleUI; [SerializeField] Vector3 PlayerStartPos = new Vector3(0, 0, -5); public void StartTitle() { if (_currentCoroutine != null) { StopCoroutine(_currentCoroutine); } TitleUI.gameObject.SetActive(true); UI.gameObject.SetActive(false); _currentCoroutine = StartCoroutine(TitleLoop()); } IEnumerator TitleLoop() { while (true) { UpdateMemberCountUI(); yield return null; } } // Start is called before the first frame update void Start() { StartTitle(); } |
「GameLoop」コルーチンの開始時にプレイヤーの位置を「PlayerInitPos」フィールドの場所に移動させています。
この変更に合わせて「Map」コンポーネントのマップ生成処理もメソッドを呼び出す形に変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Map.cs マップ生成処理のメソッド化 //次のものを修正 void Awake() { } //次のものを追加 public void InitMap() { foreach(Transform child in transform) { if (child.gameObject == Ground) continue; Object.Destroy(child.gameObject); } BuildMap(); InitJoinableCharacter(); InitEnemy(); } |
GameObjectの作成
スクリプトの準備ができましたので、次はGameObjectの方を作成していきます。
次の手順を行って下さい。
- メニューからGameObject > UI > Canvasをクリックし、「TitleUI」というGameObjectを作成して下さい。
- 「TitleUI」の子GameObjectとして、メニューのGameObject > UI > Textをクリックし、「Title」というGameObjectを作成して下さい。
- 同じく「TitleUI」の子GameObjectとして、メニューのGameObject > UI > Buttonをクリックし、「StartButton」というGameObjectを作成して下さい。
GameObject階層は次のようになっています。
- TitleUI : UI > Canvas
- – Title : UI > Text
- – StartButton : UI > Button
これらのGameObjectの設定内容は次のものにして下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
// GameObjectの設定内容 ## TitleUI : UI > Canvas - Canvasコンポーネント SortOrder : 100 - CanvasScalerコンポーネント UIScaleMode : ScaleWithScreenSize ReferenceResolution : X=800, Y=600 他のCanvasと基本的な設定は合わせて下さい。 ## TitleUI > Title : UI > Text - RectTransformコンポーネント Anchors Min: 0, 0.5 Anchors Max: 1, 1 Pivot : 0.5, 0.5 Left=0, Top=0, Right=0, Bottom=0 - Textコンポーネント Text : Run And Join!! Alignment : 横=中央揃え, 縦=中央揃え BestFit : true, MinSize=10, MaxSize=72 Color :白色 ## TitleUI > StartButton : UI > Button - RectTransformコンポーネント Anchors Min: 0.5, 0.25 Anchors Max: 0.5, 0.25 Pivot : 0.5, 0.5 PosX=0, PosY=0, Width=100, Height=40 - Button コンポーネント OnClick : シーンの「RunAndJoinScene」の「RunAndJoinSceneManager」コンポーネントの「StartGame()」メソッドを設定 ## JudgeUI > StartButton > Text : UI > Button - Textコンポーネント Text : Start Alignment : 横=中央揃え, 縦=中央揃え BestFit : true, MinSize=10, MaxSize=32 Color :黒色 |
最後に、「RunAndJoinScene」オブジェクトのTitleUIコンポーネントに「TitleUI」をアタッチしてください。GameObjectの設定ができましたので、再生してみて動作を確認して下さい。
再生直後にタイトルが表示されていればOKです。
もし、開始時にプレイヤーと他のキャラクターが重なっていたら「RunAndJoinSceneManager」コンポーネントの「PlayerInitPos」フィールドを調整して下さい。
勝敗判定の組み込み
次にプレイヤーと敵が当たった時にお互いの集団の数を比べ勝敗を決定するようにします。
スクリプトの作成
まず、「RunAndJoinSceneManager」コンポーネントに勝敗判定処理を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
// RunAndJoinSceneManager.cs 勝敗判定処理の追加 //次のものを追加 [SerializeField] Canvas JudgeUI; [SerializeField] Text JudgeText; public bool IsFinishGame { get => JudgeUI.gameObject.activeSelf; } public void JudgeGame(CharacterBase a, CharacterBase b) { if (JudgeUI.gameObject.activeSelf || IsFinishGame || a.MemberCount == b.MemberCount) return; JudgeUI.gameObject.SetActive(true); JudgeText.text = $"{(a.MemberCount > b.MemberCount ? a.name : b.name)} Win!!"; a.IsStop = true; b.IsStop = true; } //次のものを修正 IEnumerator GameLoop() { var map = Object.FindObjectOfType<Map>(); map.InitMap(); var player = Player; player.transform.position = PlayerStartPos; player.MemberCount = 0; player.IsStop = false; while (true) { UpdateMemberCountUI(); yield return null; } } public void StartTitle() { if (_currentCoroutine != null) { StopCoroutine(_currentCoroutine); } TitleUI.gameObject.SetActive(true); UI.gameObject.SetActive(false); JudgeUI.gameObject.SetActive(false); _currentCoroutine = StartCoroutine(TitleLoop()); } |
「JudgeGame()」メソッドで勝敗判定を行っています。
互いの所属しているメンバーの数に差異があった時に勝敗がつくようにしています。
その際に記事では手軽に勝った方のGameObjectの名前を画面に表示するようにしていますが、この辺りは専用のパラメータを「CharacterBase」コンポーネントに追加して、そちらを表示するようにしてもいいでしょう!
プレイヤーと敵の当たり判定は「CharacterBase」コンポーネントで行っているのでそちらも修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// CharacterBase.cs 勝敗判定の追加 //次のものを追加 public bool IsStop { get; set; } = false; //次のものを修正 protected virtual void OnTriggerEnter(Collider other) { if (IsStop) return; var character = other.gameObject.GetComponent<CharacterBase>(); if (character != null && character.IsJoinableCharacter) { if (!(this is JoinableCharacter)) { var joinableChar = character as JoinableCharacter; if (joinableChar.FollowedTarget != null) joinableChar.FollowedTarget.MemberCount--; joinableChar.FollowedTarget = this; MemberCount++; } } if(this is Player && character is Enemy) { var manager = Object.FindObjectOfType<RunAndJoinSceneManager>(); manager.JudgeGame(this, character); } } |
勝敗判定用のゲームオブジェクトの作成
次に勝敗判定後にその結果を表示するGameObjectを作成します。
次の手順を行って下さい。
- メニューからGameObject > UI > Canvasをクリックし、「JudgeUI」というGameObjectを作成して下さい。
- 「JudgeUI」の子GameObjectとして、メニューのGameObject > UI > Textをクリックし、「JudgeText」というGameObjectを作成して下さい。
- 同じく「JudgeUI」の子GameObjectとして、メニューのGameObject > UI > Buttonをクリックし、「EndButton」というGameObjectを作成して下さい。
GameObject階層は次のようになっています。
- JudgeUI : UI > Canvas
- – JudgeText : UI > Text
- – EndButton : UI > Button
これらのGameObjectの設定内容は次のものにして下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
// GameObjectの設定内容 ## JudgeUI : UI > Canvas シーン上では再生時に非アクティブにして下さい。 - Canvasコンポーネント SortOrder : 100 - CanvasScalerコンポーネント UIScaleMode : ScaleWithScreenSize ReferenceResolution : X=800, Y=600 他のCanvasと基本的な設定は合わせて下さい。 ## JudgeUI > JudgeText : UI > Text - RectTransformコンポーネント Anchors Min: 0, 0.5 Anchors Max: 1, 1 Pivot : 0.5, 0.5 Left=0, Right=0, Top=0, Bottom=0 - Textコンポーネント Text : XXX Win! Alignment : 横=中央揃え, 縦=中央揃え BestFit : true, MinSize=10, MaxSize=72 Color :白色 ## JudgeUI > EndButton : UI > Button - RectTransformコンポーネント Anchors Min: 0.5, 0.25 Anchors Max: 0.5, 0.25 Pivot : 0.5, 0.5 PosX=0, PosY=0, Width=100, Height=40 - Button コンポーネント OnClick : シーンの「RunAndJoinScene」の「RunAndJoinSceneManager」コンポーネントの「StartTitle()」メソッドを設定 シーンの「JudgeUI」の「GameObject」の「SetActive」をfalseに設定 ## TitleUI > StartButton > Text : UI > Button - Textコンポーネント Text : Go Title Alignment : 横=中央揃え, 縦=中央揃え BestFit : true, MinSize=10, MaxSize=32 Color :黒色 |
最後に、「RunAndJoinScene」オブジェクトのJudgeUIコンポーネントに「JudgeUI」と「JudgeText」をアタッチしてください。GameObject側の設定ができたら、再生して動作を確認して下さい。
プレイヤーと敵が当たった時に勝敗判定を行い、その結果を画面に表示するようになっていればOKです。
敵が勝ったときにEnemy(Clone) Winとなっていると思います。Cloneを消したい場合はJudgeGame()メソッドの条件分岐と表示文を変更すればOKです。
まとめ
今回の記事ではゲームの流れを作成していきました。
この講座ではプレイヤーをシーンに残すようにしていますが、プレハブ化して敵やキャラクターと同じ感じで毎回生成すると処理が簡単になるかと思います。
タイトル画面および、勝敗がついた後でもプレイヤーが移動できるようにしていますが、その辺りはお好みで操作できなくしたりするのもいいかもしれません。
講座では操作できた方が楽しいのでそのままにしています。が、その分余分な処理を追加しています。
まとめると以下のようになります。
- タイトル画面の作成
- 勝敗判定の追加と結果を画面に表示するようにした
この講座はここまでになります。このあとはあなたが自由に改良していくといいでしょう。
オンライン機能を付けて友達と対戦!なんてのも面白いかもしれないですね^^
ここまでのスクリプトまとめ
お疲れ様でした!
今回はミニゲームタイプのチュートリアル講座でしたが、うまく作れましたか?
もしわからないことなど出てきた時のためにスクリプト全文の完成形を掲載しておきますね。
Camera.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
using System.Collections; using System.Collections.Generic; using UnityEngine; class Camera : MonoBehaviour { public Vector3 Direction = new Vector3(0, -0.5f, 1); [Range(0.1f, 100)] public float Distance = 5f; public void LookAt(Transform Target) { transform.position = Target.position - Direction.normalized * Distance; transform.LookAt(Target); } } |
CharacterBase.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
using System.Collections; using System.Collections.Generic; using UnityEngine; class CharacterBase : MonoBehaviour { [Range(0, 20)] public float SpeedPerSeconds = 5f; Map Map { get => Object.FindObjectOfType<Map>(); } [SerializeField] int _memberCount = 0; public int MemberCount { get => _memberCount; set => _memberCount = value; } public bool IsJoinableCharacter = false; [SerializeField] Color _teamColor = Color.red; public Color TeamColor { get => _teamColor; } public Vector3 Pos { get => transform.position; private set => transform.position = value; } public Vector3 Forward { get => transform.forward; } public bool IsStop { get; set; } = false; public void Move(Vector3 velocity) { Pos += velocity * Time.deltaTime; Pos = Map.ClampPos(Pos); transform.LookAt(Pos + velocity, Vector3.up); } protected virtual void FixedUpdate() { var rigidBody = GetComponent<Rigidbody>(); var vec = rigidBody.velocity; vec.x = 0; vec.z = 0; rigidBody.velocity = vec; rigidBody.angularVelocity = Vector3.zero; } protected virtual void Awake() { ChangeTeamColor(_teamColor); } protected virtual void Start() { } protected void ChangeTeamColor(Color color) { _teamColor = color; var model = transform.Find("Model"); if (model != null) { var renderer = model.GetComponent<Renderer>(); renderer.material.color = _teamColor; } } protected virtual void OnTriggerEnter(Collider other) { if (IsStop) return; var character = other.gameObject.GetComponent<CharacterBase>(); if (character != null && character.IsJoinableCharacter) { if (!(this is JoinableCharacter)) { var joinableChar = character as JoinableCharacter; if (joinableChar.FollowedTarget != null) joinableChar.FollowedTarget.MemberCount--; joinableChar.FollowedTarget = this; MemberCount++; } } if (this is Player && character is Enemy) { var manager = Object.FindObjectOfType<RunAndJoinSceneManager>(); manager.JudgeGame(this, character); } } } |
Enemy.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
using System.Collections; using System.Collections.Generic; using UnityEngine; class Enemy : CharacterBase { public Map Map; Coroutine _currentCoroutine; public void StartMove() { if (_currentCoroutine != null) { StopCoroutine(_currentCoroutine); } _currentCoroutine = StartCoroutine(MoveCoroutine()); } IEnumerator MoveCoroutine() { var buildingGridSize = Map.GridSize - new Vector3Int(1, 0, 1); var massSize = new Vector3( Map.Size.x / buildingGridSize.x, 1, Map.Size.z / buildingGridSize.z); var start = new Vector3(-Map.Size.x / 2, 0, -Map.Size.z / 2); var oneLoopCount = (Map.GridSize.x * Map.GridSize.z); var offset = new Vector3(1, 0, 1); var rnd = new System.Random(); while (true) { var startXIndex = (int)((transform.position.x - start.x + massSize.x * 0.5f) / massSize.x); var startZIndex = (int)((transform.position.z - start.z + massSize.z * 0.5f) / massSize.z); var nextXIndex = startXIndex; var nextZIndex = startZIndex; var i = rnd.Next(4); switch (i) { case 0: nextXIndex--; break; case 1: nextXIndex++; break; case 2: nextZIndex--; break; case 3: nextZIndex++; break; } nextXIndex = Mathf.Clamp(nextXIndex, 0, Map.GridSize.x - 1); nextZIndex = Mathf.Clamp(nextZIndex, 0, Map.GridSize.z - 1); var targetPos = new Vector3( start.x + massSize.x * nextXIndex, 0, start.z + massSize.z * nextZIndex ); yield return null; while (true) { var vec = (targetPos - transform.position); vec.y = 0; if (vec.magnitude < 1f) break; Move(vec.normalized * SpeedPerSeconds); yield return null; } } } protected override void Start() { StartMove(); } } |
JoinableCharacter.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
using System.Collections; using System.Collections.Generic; using UnityEngine; class JoinableCharacter : CharacterBase { public enum State { Free, Joined, } [SerializeField] CharacterBase _followedTarget; [SerializeField] State CurrentState; [Range(0.5f, 15f)] public float FreeMoveSeconds = 3f; [Range(0.5f, 15f)] public float FreeWaitSeconds = 3f; public CharacterBase FollowedTarget { get => _followedTarget; set { if (_followedTarget == value) return; _followedTarget = value; if (value == null) { StartFree(); } else { ChangeTeamColor(_followedTarget.TeamColor); StartJoined(); } } } public bool IsJoinable(CharacterBase other) { return other != FollowedTarget && !(other is JoinableCharacter); } Coroutine _currentCoroutine; public void StartFree() { if (_currentCoroutine != null) { StopCoroutine(_currentCoroutine); } CurrentState = State.Free; _currentCoroutine = StartCoroutine(FreeCoroutine()); } IEnumerator FreeCoroutine() { var rnd = new System.Random(gameObject.GetInstanceID() + System.DateTime.Now.Millisecond); while (true) { var t = 0f; var vec = Vector3.zero; vec.x = (float)rnd.NextDouble() * 2 - 1; vec.z = (float)rnd.NextDouble() * 2 - 1; vec.Normalize(); vec *= SpeedPerSeconds; while (t < FreeMoveSeconds) { t += Time.deltaTime; Move(vec); yield return null; } yield return new WaitForSeconds(FreeWaitSeconds); } } public void StartJoined() { if (_currentCoroutine != null) { StopCoroutine(_currentCoroutine); } CurrentState = State.Joined; _currentCoroutine = StartCoroutine(JoinedCoroutine()); } IEnumerator JoinedCoroutine() { while (true) { var vec = (FollowedTarget.transform.position - transform.position); vec.y = 0; Move(vec.normalized * SpeedPerSeconds); yield return null; } } protected override void Start() { StartFree(); } } |
Map.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
using System.Collections; using System.Collections.Generic; using UnityEngine; class Map : MonoBehaviour { public GameObject BuildingPrefab; public GameObject Ground; public Vector3 Size = new Vector3(10, 1, 10); public Vector3Int GridSize = new Vector3Int(5, 1, 5); public Enemy EnemyPrefab; public void BuildMap() { Ground.transform.localScale = Size / 10 + Vector3.one * 0.5f; var buildingGridSize = GridSize - new Vector3Int(1, 0, 1); var massSize = new Vector3( Size.x / buildingGridSize.x, 1, Size.z / buildingGridSize.z); var start = new Vector3(-Size.x / 2, 0, -Size.z / 2) + massSize * 0.5f; for (var z = 0; z < buildingGridSize.z; ++z) { for (var x = 0; x < buildingGridSize.x; ++x) { var inst = Object.Instantiate(BuildingPrefab, transform); inst.transform.localPosition = start + new Vector3( x * Size.x / buildingGridSize.x, 0, z * Size.z / buildingGridSize.z ); } } } void Awake() { } public bool IsInMap(Vector3 pos) { var min = -Size / 2; var max = min + Size; return min.x <= pos.x && pos.x <= max.x && min.z <= pos.z && pos.z <= max.z; } public Vector3 ClampPos(Vector3 pos) { var min = -Size / 2; var max = min + Size; pos.x = Mathf.Clamp(pos.x, min.x, max.x); pos.z = Mathf.Clamp(pos.z, min.z, max.z); return pos; } public JoinableCharacter JoinableCharacterPrefab; [Range(0, 100)] public int InitJoinableCharacterCount = 20; public Vector3 SpawnOffset = new Vector3(0.5f, 0, 0.5f); public void InitJoinableCharacter() { var buildingGridSize = GridSize - new Vector3Int(1, 0, 1); var massSize = new Vector3( Size.x / buildingGridSize.x, 1, Size.z / buildingGridSize.z); var start = new Vector3(-Size.x / 2, 0, -Size.z / 2); var oneLoopCount = (GridSize.x * GridSize.z); for (var i = 0; i < InitJoinableCharacterCount; ++i) { var obj = Object.Instantiate(JoinableCharacterPrefab, transform); var xIndex = (i % oneLoopCount) % GridSize.x; var zIndex = (i % oneLoopCount) / GridSize.x; var loopCount = i / oneLoopCount; obj.transform.localPosition = new Vector3( start.x + massSize.x * xIndex, 0, start.z + massSize.z * zIndex ) + SpawnOffset * loopCount; } } public void InitEnemy() { var buildingGridSize = GridSize - new Vector3Int(1, 0, 1); var massSize = new Vector3( Size.x / buildingGridSize.x, 1, Size.z / buildingGridSize.z); var start = new Vector3(-Size.x / 2, 0, -Size.z / 2); var oneLoopCount = (GridSize.x * GridSize.z); var rnd = new System.Random(); var i = rnd.Next(oneLoopCount); var obj = Object.Instantiate(EnemyPrefab, transform); obj.Map = this; var xIndex = i % GridSize.x; var zIndex = i / GridSize.x; obj.transform.localPosition = new Vector3( start.x + massSize.x * xIndex, 2, start.z + massSize.z * zIndex ); } public void InitMap() { foreach (Transform child in transform) { if (child.gameObject == Ground) continue; Object.Destroy(child.gameObject); } BuildMap(); InitJoinableCharacter(); InitEnemy(); } } |
Player.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
using System.Collections; using System.Collections.Generic; using UnityEngine; class Player : CharacterBase { Camera Camera { get => Object.FindObjectOfType<Camera>(); } Coroutine _currentCoroutine; public void StartMove() { if (_currentCoroutine != null) { StopCoroutine(_currentCoroutine); } _currentCoroutine = StartCoroutine(MoveCoroutine()); } IEnumerator MoveCoroutine() { while (true) { var velocity = GetVelocity(); Move(velocity); Camera.LookAt(transform); yield return null; } } Vector3 GetVelocity() { var move = Vector3.zero; move.x = Input.GetAxis("Horizontal"); move.z = Input.GetAxis("Vertical"); move *= SpeedPerSeconds; return move; } protected override void Start() { StartMove(); } } |
RunAndJoinSceneManager.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; class RunAndJoinSceneManager : MonoBehaviour { [SerializeField] Canvas UI; [SerializeField] Text PlayerMemberCountText; [SerializeField] Text EnemyMemberCountText; Player Player { get => Object.FindObjectOfType<Player>(); } Enemy Enemy { get => Object.FindObjectOfType<Enemy>(); } [SerializeField] Canvas TitleUI; [SerializeField] Vector3 PlayerStartPos = new Vector3(0, 0, -5); [SerializeField] Canvas JudgeUI; [SerializeField] Text JudgeText; public bool IsFinishGame { get => JudgeUI.gameObject.activeSelf; } public void UpdateMemberCountUI() { var player = Player; PlayerMemberCountText.text = player != null ? player.MemberCount.ToString() : "--"; var enemy = Enemy; EnemyMemberCountText.text = enemy != null ? enemy.MemberCount.ToString() : "--"; } Coroutine _currentCoroutine; public void StartGame() { if (_currentCoroutine != null) { StopCoroutine(_currentCoroutine); } UI.gameObject.SetActive(true); TitleUI.gameObject.SetActive(false); _currentCoroutine = StartCoroutine(GameLoop()); } IEnumerator GameLoop() { var map = Object.FindObjectOfType<Map>(); map.InitMap(); var player = Player; player.transform.position = PlayerStartPos; player.MemberCount = 0; player.IsStop = false; while (true) { UpdateMemberCountUI(); yield return null; } } // Start is called before the first frame update void Start() { StartTitle(); } public void StartTitle() { if (_currentCoroutine != null) { StopCoroutine(_currentCoroutine); } TitleUI.gameObject.SetActive(true); UI.gameObject.SetActive(false); JudgeUI.gameObject.SetActive(false); _currentCoroutine = StartCoroutine(TitleLoop()); } IEnumerator TitleLoop() { while (true) { UpdateMemberCountUI(); yield return null; } } public void JudgeGame(CharacterBase a, CharacterBase b) { if (JudgeUI.gameObject.activeSelf || IsFinishGame || a.MemberCount == b.MemberCount) return; JudgeUI.gameObject.SetActive(true); JudgeText.text = $"{(a.MemberCount > b.MemberCount ? a.name : b.name)} Win!!"; a.IsStop = true; b.IsStop = true; } } |
コメント