前提・実現したいこと
ブロックの積み上げゲーム
現状ではブロックを縦一列にしか積み上げていくことができず、遊びの幅が狭い状態です。
またブロック積み上げに伴うカメラ位置の上昇も、ブロックが3つ落とされるごとに一定間隔で上昇するという仕組みになっており、あまり柔軟性がない状態です。
上記の問題を以下の方法で解決したいと思っています。
●シーン内のブロックで"DroppedBlock"タグがついたものをリストまたは配列に格納
●格納されたGameObjectそれぞれのTransform.position.yを比較し、最大の値を出力
●出力された最大値をもとにカメラの上昇下降をコントロール
現状の仕組み
●メインカメラの子にGameOverトリガー(画面下部に配置されています)があり、ブロックがそのトリガーに触れるとゲームオーバー
●ブロックを3つ落とすごとにカメラ位置上昇
●落とす前のブロックのタグは"Block"、地面またはブロックに接地したブロックは"DroppedBlock"に変更
###わからないところ
シーン内のブロックで"DroppedBlock"タグを配列に格納するために
GameObject.FindGameObjectsWithTag("DroppedBlock");
を用いたのですが、格納されたオブジェクトそれぞれのTransform.position.yを比較する方法がわかりません。
最大値となるTransform.position.yさえ取得できてしまえば、カメラの位置を動的に変更することは可能だと思うのですが。。。
該当のソースコード
GameplayController.cs
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5using DG.Tweening; 6using UnityEngine.SceneManagement; 7 8public class GameplayController : MonoBehaviour 9{ 10 11 public static GameplayController instance; 12 13 public BlockSpawner block_Spawner; 14 15 [HideInInspector] 16 public BlockScript currentBox; 17 18 public CameraFollow cameraScript; 19 private int moveCount; 20 21 public float blockSpeed; 22 23 GameObject[] stackedBlocks; 24 25 bool isChecked; 26 27 public Text text; 28 29 GameObject pauseMenu; 30 public RectTransform pause; 31 32 GameObject gameOverMenu; 33 34 void Awake() 35 { 36 if (instance == null) 37 instance = this; 38 39 blockSpeed = 5f; 40 } 41 42 void Start() 43 { 44 block_Spawner.SpawnBox(); 45 46 pauseMenu = GameObject.Find("PauseMenu"); 47 pauseMenu.SetActive(false); 48 gameOverMenu = GameObject.Find("GameOverMenu"); 49 gameOverMenu.SetActive(false); 50 } 51 52 void Update() 53 { 54 DetectInput(); 55 56 GameObject[] blocks = GameObject.FindGameObjectsWithTag("DroppedBlock"); 57 58 59 } 60 61 void DetectInput() 62 { 63 if (Input.GetKeyDown(KeyCode.Space)) 64 { 65 currentBox.DropBox(); 66 } 67 } 68 69 70 public void SpawnNewBox() 71 { 72 Invoke("NewBox", 2f); 73 } 74 75 void NewBox() 76 { 77 block_Spawner.SpawnBox(); 78 } 79 80 public void MoveCamera() 81 { 82 83 moveCount++; 84 85 if (moveCount == 3) 86 { 87 moveCount = 0; 88 cameraScript.targetPos.y += 2.5f; 89 } 90 91 } 92 93 public void PauseButton() 94 { 95 96 } 97 98 public void RestartGame() 99 { 100 UnityEngine.SceneManagement.SceneManager.LoadScene( 101 UnityEngine.SceneManagement.SceneManager.GetActiveScene().name); 102 } 103 104 public void ShowGameOverMenu() 105 { 106 gameOverMenu.SetActive(true); 107 } 108 109 public void StageList() 110 { 111 SceneManager.LoadScene("StageList"); 112 } 113 114}
BlockScript.cs(このスクリプトが各ブロックオブジェクトに付いています)
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class BlockScript : MonoBehaviour 6{ 7 private bool canMove; 8 9 private Rigidbody2D myBody; 10 11 private bool gameOver; 12 private bool ignoreCollision; 13 private bool ignoreTrigger; 14 15 private bool isDropped; 16 17 Rigidbody2D rb2D; 18 19 public AudioClip drop; 20 public AudioClip dropped; 21 AudioSource audiosource; 22 23 24 25 void Awake() 26 { 27 myBody = GetComponent<Rigidbody2D>(); 28 myBody.gravityScale = 0f; 29 } 30 31 void Start() 32 { 33 canMove = true; 34 35 GameplayController.instance.currentBox = this; 36 37 rb2D = GetComponent<Rigidbody2D>(); 38 39 audiosource = GetComponent<AudioSource>(); 40 41 } 42 43 void Update() 44 { 45 MoveBox(); 46 } 47 48 void MoveBox() 49 { 50 if (canMove) 51 { 52 Vector3 horizontal = new Vector3(Input.GetAxis("Horizontal"), 0.0f, 0.0f); 53 transform.position += horizontal * GameplayController.instance.blockSpeed * Time.deltaTime; 54 } 55 } 56 57 public void DropBox() 58 { 59 canMove = false; 60 myBody.gravityScale = 1; 61 62 audiosource.PlayOneShot(drop); 63 } 64 65 void Landed() 66 { 67 68 if (gameOver) 69 return; 70 71 72 ignoreCollision = true; 73 ignoreTrigger = true; 74 75 GameplayController.instance.SpawnNewBox(); 76 GameplayController.instance.MoveCamera(); 77 78 } 79 80 void RestartGame() 81 { 82 GameplayController.instance.RestartGame(); 83 } 84 85 void ShowGameOverMenu() 86 { 87 GameplayController.instance.ShowGameOverMenu(); 88 } 89 90 void OnTriggerEnter2D(Collider2D target) 91 { 92 if (ignoreTrigger) 93 return; 94 95 if (target.tag == "GameOver") 96 { 97 98 CancelInvoke("Landed"); 99 gameOver = true; 100 ignoreTrigger = true; 101 102 Invoke("ShowGameOverMenu", 2f); 103 } 104 } 105 106 void OnCollisionEnter2D(Collision2D target) 107 { 108 109 if (ignoreCollision) 110 return; 111 112 if (target.gameObject.tag == "Platform") 113 { 114 115 this.tag = "DroppedBlock"; 116 Invoke("Landed", 2f); 117 //ignoreCollision = true; 118 119 audiosource.PlayOneShot(dropped); 120 } 121 122 if (target.gameObject.tag == "DroppedBlock") 123 { 124 this.tag = "DroppedBlock"; 125 Invoke("Landed", 2f); 126 //ignoreCollision = true; 127 128 audiosource.PlayOneShot(dropped); 129 } 130 } 131}
補足情報(FW/ツールのバージョンなど)
実際の挙動を録画し、Youtubeに載せましたので、参考にしてください。
<挙動動画>
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/19 05:53