質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

1274閲覧

配列の1番目の敵だけ弾を打ってくれない

aro

総合スコア21

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2020/05/04 13:01

編集2020/05/04 13:20

前提・実現したいこと

イメージ説明
イメージ説明
現在UnityにてSTGを制作しております。(公式チュートリアルの物を改造しております)
画像の通り、
(1)敵が下りてくる
(2)弾を打つ
(3)弾を打つのを止める
(4)画面外に戻っていく
という動きを、12体に割り当てています。

発生している問題・エラーメッセージ

しかし、何故か1体目だけが弾を打ってくれません…。 更に不思議なことに、降りてくるタイミングを0.5秒差ずつに設定しておりますが、1秒にすると、打ってくれます。 2日程コードと睨み合っていますが、詰まっています…。

該当のソースコード

C#

1//public class Departure : MonoBehaviour 2IEnumerator Start() 3 { 4 // Enemy_3コンポーネントをシーン内から探して取得する 5 enemy_3 = FindObjectOfType<Enemy_3>(); 6 7 //配列の1番目から順番に、到達点に移動させる 8 for (int i = 0; i < enemys.Length; i++) 9 { 10 //スタート位置を記憶させる 11 startPoint[i] = enemys[i].transform.position; 12 //引数1動かす敵:引数2到達点:引数3行きか帰りか:を指定して、シーケンスを実行 13 enemy_3.AttackSequence(enemys[i], arrivalPointObj[i].transform.position, go); 14 // 0.5秒待ってから次の敵が移動 15 yield return new WaitForSeconds(0.5f); 16 } 17 18 19 //スタート位置に戻らせる 20 for (int j = 0; j < enemys.Length; j++) 21 { 22 go = false;//帰り 23 //引数1動かす敵:引数2到達点:引数3行きか帰りか:を指定して、シーケンスを実行 24 enemy_3.AttackSequence(enemys[j], startPoint[j], go); 25 // 0.5秒待ってから次の敵が移動 26 yield return new WaitForSeconds(0.5f); 27 } 28 }

C#

1//public class Enemy_3 : MonoBehaviour 2public Sequence AttackSequence(GameObject eN,Vector3 aP, bool Go) 3 { 4 //ここでオブジェクトを指定しないと、何故か配列の最後のオブジェクトが参照されてしまう 5 Transform eNtransform = eN.transform; 6 //子オブジェクト(ShotDirection)を取得 7 GameObject ob = eNtransform.Find("ShotDirection").gameObject; 8 //enemysの配列[i]番目のenemyの子の、ShotDirectionのコンポーネントShotScriptを取得して変数に格納する 9 shotScript = ob.GetComponent<ShotScript>(); 10 11 if(Go == false) 12 { 13 //帰る時打たせなくする 14 shotScript.canShot = false; 15 } 16 17 Sequence seq = DOTween.Sequence(); 18 //DOTweenで到達点まで移動 19 seq.Append(eN.transform.DOMove(aP, 1f).SetEase(Ease.OutCubic)).OnComplete(() => 20 { 21 if (Go == true) 22 { 23 //移動し終わったら、打ち始める 24 shotScript.canShot = true; 25 } 26 }); 27 28 return seq; 29 }

C#

1//public class ShotScript : MonoBehaviour 2 // 弾のPrefab 3 public GameObject bullet; 4 // 弾を撃つ間隔 5 public float shotDelay; 6 // 弾を撃つかどうか 7 public bool canShot; 8 //Update()関数で毎フレーム実行されるのを防ぐため 9 bool isKeepShot = false; 10 11 private void Update() 12 { 13 if (canShot == true && isKeepShot == false) 14 { 15 StartCoroutine("KeepShot"); 16 //実行を一度だけにする用 17 isKeepShot = true; 18 } 19 } 20 21 // Start is called before the first frame update 22 IEnumerator KeepShot() 23 { 24 GameObject Player = GameObject.Find("Player(Clone)"); 25 Vector3 myTransform = transform.position; 26 27 // canShotがfalseの場合、ここでコルーチンを終了させる 28 if (canShot == false) 29 { 30 yield break; 31 } 32 33 //Playerが死ぬか、停止命令まで繰り返す 34 while (Player != null || canShot != false) 35 { 36 37 // 子要素を全て取得する 38 for (int i = 0; i < transform.childCount; i++) 39 { 40 /////////ホーミング角度計算コード/////// 41 Transform shotPosition = transform.GetChild(i); 42 float aim = GetAim(this.transform.position, Player.transform.position); 43 aim += 90; 44 this.transform.rotation = Quaternion.Euler(0.0f, 0.0f, aim); 45 //////////////////////////////////////// 46 //打つ 47 Shot(shotPosition); 48 } 49 // shotDelay秒待つ 50 yield return new WaitForSeconds(shotDelay); 51 } 52 }

補足情報(FW/ツールのバージョンなど)

【司令塔】---動け---→【敵】---打て/打つな--→【弾】
という構造のつもりです。
わかりづらくてすみません…。
弾のコードは不要かもしれませんが、コルーチンも怪しいので一応載せました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nskydiving

2020/05/05 00:28

以下のような問題の切り分けをしてください。 ・敵が1体だけにしても再現するのか? ・「弾を打ってくれない」とはどういう状況なのか?(canShot が true にならないのか、Shot メソッドが呼ばれているのか)
aro

2020/05/05 08:11

ご返信ありがとうございました! 自力でどうにか解決出来ました。 ご質問に対しては、前者は試していません。次回問題が起こったらやってみます。 後者は、canShotがTrueになりませんでした。
guest

回答1

0

自己解決

ShotScriptを大改造して、Enemy_3から直接打つ命令を下せるようにしたのですが、(今まではShotScriptから更に打つ命令をしていたので)それでも1体目だけ弾を打たない現象は変わりませんでした。
なので、原因はShotScript内ではないとわかり、Enemy_3を色々改造していたら、治りました…。

C#

1//ここでオブジェクトを指定しないと、何故か配列の最後のオブジェクトが参照されてしまう 2 Transform eNtransform = eN.transform; 3 //子オブジェクト(ShotDirection)を取得 4 GameObject ob = eNtransform.Find("ShotDirection").gameObject; 5 //enemysの配列[i]番目のenemyの子の、ShotDirectionのコンポーネントShotScriptを取得して変数に格納する 6 shotScript = ob.GetComponent<ShotScript>();

上記のコードを、弾を打つスクリプトを実行する関数に入れたところ、治りました。
改造したので、ここに記載したコードには存在しませんが、ここでいうなら、KeepShot()に入れた感じですかね…?

(1)配列の1番目の敵を取得→(2)その敵の弾を打つスクリプトを検索→(3)弾を打つ関数を実行
を実現したかったのですが、(2)できちんと特定の敵を指定してるのに、スクリプトは(1)の敵にアタッチされているものじゃないのが実行されていたんでしょうか…
完全に原因は解明出来ていないですが、このコードの移動で治りました。

投稿2020/05/05 08:08

aro

総合スコア21

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問