前提・実現したいこと
Unityにて2Dシューティングゲームを制作している初心者です。言語はC#です。
左右から落下する隕石を破壊するため、複数の機銃が付いた宇宙船内を移動、隕石を破壊できる位置の機銃で弾を撃つゲームを制作中です
やりたい事は以下です
1.ガンポッドに近づいてボタンを押すと、ガンポッドの手前に自動で移動(瞬間移動)する 2.ボタンを押している間ずっと弾が連射される 3.ボタンを話すと弾が止まる(位置はそのままで、射撃前の位置には戻らない) 4.ガンポッドには同一のscriptをアタッチして使い回す
発生している問題・エラーメッセージ
やりたいことの1~3まではガンポッドが1つだけだった時はクリアしていました
ところが、ガンポッドを複数にした途端どのガンポッド近くでボタンを押しても、特定のガンポッドの前に移動してしまいます
エラーを吐いている訳ではないので、根本的な知識不足による欠陥があるのかもしれませんが、ネットを探しても似たような質問や対策は無かったため質問致します。
ガンポッドのソースコード
ソースコード public class Gunpods : MonoBehaviour { public int PodNum; //ガンポッドのナンバー public Vector3 PodsPos; //ガンポッドの位置 public GameObject bulletPrefab; //弾 [SerializeField] private float interval = 0.2f; // 何秒間隔で撃つか private float timer = 0.0f; // 時間カウント用のタイマー GameObject gameManagerObj; GameManager gameManager; GameObject player; Player playerScript; // Start is called before the first frame update void Start() { gameManagerObj = GameObject.Find("GameManager"); gameManager = gameManagerObj.GetComponent<GameManager>(); player = GameObject.Find("Player"); playerScript = player.GetComponent<Player>(); if (PodNum == 1) { PodsPos = gameManager.PodNo[1].transform.position; } if (PodNum == 2) { PodsPos = gameManager.PodNo[2].transform.position; } if (PodNum == 3) { PodsPos = gameManager.PodNo[3].transform.position; } } // Update is called once per frame void Update() { // タイマーの値を減らす if (timer > 0.0f) { timer -= Time.deltaTime; } if(playerScript.isUse) { Debug.Log("ポッドが使われた(射撃位置に移動)"); player.transform.position = new Vector3(PodsPos.x, PodsPos.y - 0.5f, 0); playerScript.isUse = false; } } public void Machlingun() //射撃 { if (playerScript.isFire == true && timer <= 0.0f) { Instantiate(bulletPrefab, new Vector3(PodsPos.x, PodsPos.y += 0.05f, PodsPos.z), Quaternion.identity); timer = interval; // 間隔をセット } if (playerScript.isFire == true) { GetComponent<Renderer>().material.color = Color.red; } else if (playerScript.isFire == false) { GetComponent<Renderer>().material.color = Color.green; } } void OnTriggerStay2D(Collider2D collision) { if (collision.tag == "Player") { GetComponent<Renderer>().material.color = Color.green; Machlingun(); } } void OnTriggerExit2D(Collider2D collision) { GetComponent<Renderer>().material.color = Color.white; }
プレイヤーのソースコード
ソースコード public class Player : MonoBehaviour { public enum State { Playing, Fire, Pause } public State state; public Vector2 player_pos; public bool isFire = false; //射撃を行っているかのbool public bool isUse = false; //今ガンポッドが使い始めたかどうかを確認するbooi [SerializeField] private float PlayerSpeed; GameObject gameManagerObj; GameManager gameManager; // Start is called before the first frame update void Start() { gameManagerObj = GameObject.Find("GameManager"); gameManager = gameManagerObj.GetComponent<GameManager>(); } // Update is called once per frame void Update() { Range(); if (state == State.Playing) //通常モードなら { float dx = Input.GetAxis("Horizontal"); transform.Translate(PlayerSpeed * dx, 0, 0); float dy = Input.GetAxis("Vertical"); transform.Translate(0, PlayerSpeed * dy, 0); gameManager.FireCount = 0; if (Input.GetKeyDown(KeyCode.G)) //Gキーを押すと { isUse = true; //ガンポッドを使い始める Debug.Log(isUse); } if (Input.GetKey(KeyCode.G)) //Gキーを押している間 { gameManager.FireCount += 1; state = State.Fire; isFire = true; } } if (state == State.Fire) //射撃モードなら { if (Input.GetKeyUp(KeyCode.G)) //Gキーから手を放すと { state = State.Playing; isFire = false; } } } public void Range() //移動範囲制御 { player_pos = transform.position; //プレイヤーの位置を取得 if (player_pos.y > 0 && player_pos.y <= 3) //中央上部にいると { player_pos.x = Mathf.Clamp(player_pos.x, -2.9f, 2.9f); //y位置が常に範囲内か監視 } else if (player_pos.y > -3.5f && player_pos.y <= 0) //中央下部にいると { player_pos.x = Mathf.Clamp(player_pos.x, -6.9f, 6.9f); //x位置が常に範囲内か監視 } if (player_pos.x > -3 && player_pos.x <= 3) //中央部にいると { player_pos.y = Mathf.Clamp(player_pos.y, -3.4f, 2.9f); //y位置が常に範囲内か監視 } else if (player_pos.x > 3 && player_pos.x <= 7) //右側にいると { player_pos.y = Mathf.Clamp(player_pos.y, -3.4f, -0.1f); //y位置が常に範囲内か監視 } else if (player_pos.x > -7 && player_pos.x <= -3) //左側にいると { player_pos.y = Mathf.Clamp(player_pos.y, -3.4f, -0.1f); //y位置が常に範囲内か監視 } transform.position = new Vector2(player_pos.x, player_pos.y); //範囲内であれば常にその位置がそのまま入る }
ゲームマネージャーのソースコード
ソースコード public class GameManager : MonoBehaviour { public int FireCount; public GameObject[] PodNo; // ガンポッドの配列 // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } }
試したこと
ゲームマネージャーで宣言した配列にアタッチした各ガンポッドのゲームオブジェクトからガンポッドスクリプトのスタート関数のところでPodPosを取得しているのですが、それが実際のプレイヤー移動位置に反映されません(再生中のインスペクターで確認すると数値は取得できています)
書き方がおかしいのか、そもそもプログラムの規則に反しているのか、何か少しでもアドバイス頂ける方がおられましたらご助力いただきたく思います。
補足情報(FW/ツールのバージョンなど)
Unity2019.4.13f1
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。