using System.Collections; using System.Collections.Generic; using UnityEngine; public class PanelCreater : MonoBehaviour { public int maxArrow; public int waitTime; public int maxColumn; public int maxRow; public int maxWaveCount; private int currentWaveCount = 0; //private float timer; public int oneWaveTimeLimit; private float waveTimer; public AnimalPanelItem animalPanelItemPrefab; public Transform animalPanelGenerateTran; public PanelItem panelItemPrefab; public Transform panelGenerateTran; public List<PanelItem> panelItemList = new List<PanelItem>(); public List<AnimalPanelItem> animalPanelList = new List<AnimalPanelItem>(); public PlayerController playerController; public UIController uIController; public enum GameState { Wait, Play, Game_Up, } public GameState gameState; IEnumerator Start() { yield return new WaitForSeconds(0.5f); gameState = GameState.Wait; StartCoroutine(NextWave()); } void Update() { if (gameState == GameState.Game_Up) { return; } if (gameState == GameState.Wait) { return; } waveTimer -= Time.deltaTime; uIController.txtWaveTimer.text = waveTimer.ToString("F0"); if (waveTimer <= 0) { if (currentWaveCount >= maxWaveCount) { gameState = GameState.Game_Up; uIController.DisplayaGameUp(); return; } gameState = GameState.Wait; StartCoroutine(NextWave()); } } public void NextPanels() { DestroyPanels(); GenerateArrowPanels(); } /// <summary> /// PanelItemの破棄 /// </summary> private void DestroyPanels() { if (panelItemList.Count <= 0) { return; } for (int i = 0; i < panelItemList.Count; i++) { Destroy(panelItemList[i].gameObject); } panelItemList.Clear(); } /// <summary> /// PanelItemの生成 /// </summary> private void GenerateArrowPanels() { for (int i = 0; i < maxArrow; i++) { PanelItem panelItem = Instantiate(panelItemPrefab, panelGenerateTran, false); panelItem.SetupPanel(playerController, this); panelItemList.Add(panelItem); } } private IEnumerator NextWave() { if (currentWaveCount != 0) { DestroyAnimalPanels(); DestroyPanels(); playerController.ResetPosition(); } uIController.ActivateReloadButton(false); yield return StartCoroutine(GenerateAnimalPanaels()); waveTimer = oneWaveTimeLimit; currentWaveCount++; StartCoroutine(uIController.DisplayWaveStart(currentWaveCount)); yield return new WaitForSeconds(1.5f); GenerateArrowPanels(); uIController.ActivateReloadButton(true); gameState = GameState.Play; } /// <summary> /// AnimalPanelItemの破棄 /// </summary> private void DestroyAnimalPanels() { for (int i = 0; i < animalPanelList.Count; i++) { Destroy(animalPanelList[i].gameObject); } animalPanelList.Clear(); } /// <summary> /// AnimalPanelItemの生成 /// </summary> private IEnumerator GenerateAnimalPanaels() { for (int x = 0; x < maxColumn; x++) { for (int y = 0; y < maxRow; y++) { AnimalPanelItem animalPanelItem = Instantiate(animalPanelItemPrefab, animalPanelGenerateTran, false); animalPanelItem.SetUpAnimalPanel(Random.Range(0,7), 100); animalPanelList.Add(animalPanelItem); yield return new WaitForSeconds(0.2f); } } } }
using UnityEngine; using UnityEngine.UI; public class PanelItem : MonoBehaviour { public Button btnPanel; public Image imgPanel; public ArrowDirectionType ArrowDirectionType; private bool isClickable; private PlayerController playerController; private PanelCreater panelCreater; public void SetupPanel(PlayerController playerController, PanelCreater panelCreater) { isClickable = true; this.playerController = playerController; this.panelCreater = panelCreater; FetchArrowDirection(); btnPanel.onClick.AddListener(OnClickPanel); isClickable = false; } /// <summary> /// 矢の方向情報とイメージの方向を一致させる /// </summary> private void FetchArrowDirection() { // 矢の方向をランダムで決定 int randomDirection = Random.Range(0, (int)ArrowDirectionType.Count); // 矢のイメージと方向の情報を一致 imgPanel.transform.rotation = Quaternion.Euler(0, 0, randomDirection * 45); ArrowDirectionType = (ArrowDirectionType)randomDirection; } private void OnClickPanel() { if (isClickable) { return; } isClickable = true; btnPanel.interactable = false; playerController.JudgeMove(ArrowDirectionType); panelCreater.NextPanels(); } }
public enum ArrowDirectionType { Right_Middle, // 0 東 Right_Top, // 1 北東 Center_Top, // 2 北 Left_Top, // 3 北西 Left_Middle, // 4 西 Left_Bottom, // 5 南西 Center_Bottom, // 6 南 Right_Bottom, // 7 南東 Count }
using UnityEngine; using UnityEngine.UI; public class AnimalPanelItem : MonoBehaviour { public Image imgAnimal; public int animalNo; public int score; public bool isGetPanel; public BoxCollider2D boxCollider2D; public void SetUpAnimalPanel(int no, int score) { animalNo = no; this.score = score; imgAnimal.sprite = Resources.Load<Sprite>("animal_" + animalNo); } public void GetPanel() { imgAnimal.color = new Color(1, 1, 1, 0.25f); isGetPanel = true; boxCollider2D.enabled = false; } }
using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { private int currentAnimalNo = 0; // 現在のAnimalPanelのNo。コンボ判定に使用する private int comboCount; // 現在のコンボ数。異なるAnimalNoのAnimalPanelを通過するとアップ。同じNoを通過するとリセット private int totalScore; // 現在のトータルスコア。Wave共通 private Vector3 startPos; // Playerのスタート地点登録用。Waveが切り替わる度にこの地点に戻る private float moveAmount; // Playerのパネルの移動量 public BoxCollider2D boxCol; // PlayerのBoxCollier2Dをアサインする public UIController uIController; // ヒエラルキー上にあるUIControlerをアサインする public LayerMask wallLayer; // Wallレイヤーをアサインする Dictionary<ArrowDirectionType, Vector3> moveDirection; // Dictionaryの宣言 void Start() { // スタート地点を登録 startPos = transform.position; // Playerの移動量をPlayerオブジェクトの大きさから取得 moveAmount = GetComponent<RectTransform>().sizeDelta.x; // 移動判定用のDictionayを用意 SetUpMoveDirection(); } /// <summary> /// 向きのEnumと、それに対応する方向情報をセットしてDictionayに順次登録 /// </summary> private void SetUpMoveDirection() { // 初期化 moveDirection = new Dictionary<ArrowDirectionType, Vector3>(); // 向きのEnumと方向情報を1セット単位で登録 moveDirection.Add(ArrowDirectionType.Right_Middle, new Vector3(moveAmount, 0, 0)); moveDirection.Add(ArrowDirectionType.Right_Top, new Vector3(moveAmount, moveAmount, 0)); moveDirection.Add(ArrowDirectionType.Center_Top, new Vector3(0, moveAmount, 0)); moveDirection.Add(ArrowDirectionType.Left_Top, new Vector3(-moveAmount, moveAmount, 0)); moveDirection.Add(ArrowDirectionType.Left_Middle, new Vector3(-moveAmount, 0, 0)); moveDirection.Add(ArrowDirectionType.Left_Bottom, new Vector3(-moveAmount, -moveAmount, 0)); moveDirection.Add(ArrowDirectionType.Center_Bottom, new Vector3(0, -moveAmount, 0)); moveDirection.Add(ArrowDirectionType.Right_Bottom, new Vector3(moveAmount, -moveAmount, 0)); } /// <summary> /// Wave切り替え時にPlayerをスタート地点に戻す /// </summary> public void ResetPosition() { transform.position = startPos; } /// <summary> /// 矢印パネルの方向に移動可能かどうかを判定 /// </summary> /// <param name="arrowDirectionType"></param> public void JudgeMove(ArrowDirectionType arrowDirectionType) { // 戻り値を利用して、作成したDictionaryの中から、向きのEnumから方向情報を取得 Vector3 judgeDirection = SearchDirectionFromDictionary(arrowDirectionType); // Playerの位置と方向を取得 Vector3 playerPos = transform.position; // Rayを使って移動先に壁があるか判定 RaycastHit2D raycastHit2D = Physics2D.Raycast(playerPos, judgeDirection, 1, wallLayer); // RayをSceneプレビュー内に可視化 Debug.DrawRay(playerPos, judgeDirection, Color.red, 1); // Wallであった場合、Debugとして内容を表示する Debug.Log(raycastHit2D.collider); // 移動先が壁の場合、移動失敗の判定をする(raycast2D変数内にゲームオブジェクトが格納されるので、移動処理をしない) if (raycastHit2D.collider != null) { // 移動失敗のSE鳴らす return; } // 移動判定に成功したのでPlayerを移動 ActionMove(judgeDirection); } /// <summary> /// DicitonayであるmoveDirectionを検索して、向きのEnumからVector3の方向情報を取得して戻す /// </summary> /// <param name="arrowDirectionType"></param> /// <returns></returns> private Vector3 SearchDirectionFromDictionary(ArrowDirectionType arrowDirectionType) { // 変数を用意 Vector3 direction = new Vector3(0, 0, 0); // Dicitonayを検索し、引数のEnumとKeyのEnumが一致したら、その方向情報(Value)を取得 foreach (KeyValuePair<ArrowDirectionType, Vector3> item in moveDirection) { if (item.Key == arrowDirectionType) { // 値を代入して戻す(ここで処理は終了) return direction = item.Value; } } return direction; } /// <summary> /// Playerを移動する /// </summary> /// <param name="currentMoveDirection"></param> private void ActionMove(Vector3 currentMoveDirection) { // Playerを移動 transform.localPosition += currentMoveDirection; // Playerの当たり判定をオンにする(移動後にオンにすることで、その間は当たり判定を取らないようにする) boxCol.enabled = true; } private void OnTriggerEnter2D(Collider2D col) { // 当たり判定に入った移動先のパネルがAnimalPanelItemを持っているか確認して変数に代入 if (col.gameObject.TryGetComponent(out AnimalPanelItem animalPanelItem)) { // AnimalPanelItemクラスを持っていないパネルなら処理を止める if (animalPanelItem.isGetPanel) { return; } // コンボ判定を行う。今までいたパネルのAnimalNoと新しく移動した先のパネルのAnimalNoを比べて違う場合にはコンボ成功 if (currentAnimalNo != animalPanelItem.animalNo) { comboCount++; } else { // 同じAnimalNoならコンボ失敗。次のコンボに向けて初期化する currentAnimalNo = animalPanelItem.animalNo; comboCount = 1; } // スコアを更新(TODO アニメ処理する) totalScore += animalPanelItem.score * comboCount; // スコアの画面表示を更新 uIController.UpdateDisplayScore(totalScore); // 通過したパネルは重複して通過できないように処理をする animalPanelItem.GetPanel(); } // Playerの当たり判定をオフ boxCol.enabled = false; } }
using System.Collections; using UnityEngine; using UnityEngine.UI; using DG.Tweening; public class UIController : MonoBehaviour { public Text txtScore; public Text txtWaveCount; public Text txtWaveTimer; public Text txtInfo; public Button btnReload; public PanelCreater panelCreater; public bool isClickable; private float waitTime = 0.5f; private Sequence sequence; void Start() { sequence = DOTween.Sequence(); btnReload.onClick.AddListener(() => StartCoroutine(OnClickReloadArrowPanels(waitTime))); } public void DisplayaGameUp() { txtInfo.text = "Game Up!"; sequence.Append(txtInfo.transform.DOLocalMoveX(0, 1.0f)).SetEase(Ease.Linear).SetRelative(); } public IEnumerator DisplayWaveStart(int waveCount) { txtWaveCount.text = waveCount.ToString(); txtInfo.text = "Wave : " + waveCount + " Start!"; sequence.Append(txtInfo.transform.DOLocalMoveX(0, 1.0f)).SetEase(Ease.Linear).SetRelative(); yield return new WaitForSeconds(2.0f); sequence.Append(txtInfo.transform.DOLocalMoveX(700, 1.0f)).SetEase(Ease.Linear).SetRelative(); yield return new WaitForSeconds(1.0f); txtInfo.text = ""; sequence.Append(txtInfo.transform.DOLocalMoveX(-700, 1.0f)).SetEase(Ease.Linear).SetRelative(); } public void UpdateDisplayScore(int score) { // アニメさせる txtScore.text = score.ToString(); } private IEnumerator OnClickReloadArrowPanels(float waitTime) { if (isClickable) { yield break; } isClickable = true; ActivateReloadButton(false); panelCreater.NextPanels(); yield return new WaitForSeconds(waitTime); isClickable = false; ActivateReloadButton(true); } public void ActivateReloadButton(bool isSwitch) { btnReload.interactable = isSwitch; } }