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

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

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

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

Q&A

解決済

1回答

2043閲覧

移動する足場に乗っている敵の弾が飛んでいかない+1発目の弾が飛んで行かずに消える

unity_user_a

総合スコア23

Unity

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

0グッド

0クリップ

投稿2020/05/03 18:11

編集2020/05/05 16:56

Unityで2Dの横スクロールアクションゲームを制作しています。

左方向に弾を発射する敵を設置し、移動しない足場の上にいる敵の弾はちゃんと飛んで行くのですが、
移動する足場の上にいる敵の弾が、出現した位置から飛んで行かずに消えてしまいます。出現した位置に留まるのではなく、消えるまで発射した敵と一緒に移動しています。

イメージ説明
イメージ説明

弾の位置を他のオブジェクトのコライダーと被らない様にしても、飛んで行く方向を変えても変化はありませんでした。
何処を直せば良いでしょうか?

また、これは移動しない足場にいる敵にも言えるのですが、発射される1発目が飛んで行かずに、出現してすぐに消えてしまいます。その後の2発目はちゃんと飛んで行くのですが。
可能であれば、1つ目の問題と併せてご回答・アドバイス頂きたいです。

↓敵のスクリプト

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Enemy_Zako9 : MonoBehaviour { [Header("攻撃オブジェクト")] public GameObject attackObj; [Header("攻撃間隔")] public float interval; [Header("重力")] public float gravity; [Header("やられた時に鳴らすSE")] public AudioClip deadSE; private Rigidbody2D rb = null; private SpriteRenderer sr = null; private ObjectCollision oc = null; private BoxCollider2D col = null; private bool isDead = false; private float deadTimer = 0.0f; private Animator anim; private float timer; // Start is called before the first frame update void Start() { rb = GetComponent<Rigidbody2D>(); sr = GetComponent<SpriteRenderer>(); oc = GetComponent<ObjectCollision>(); col = GetComponent<BoxCollider2D>(); anim = GetComponent<Animator>(); if (anim == null || attackObj == null) { Debug.Log("設定が足りません"); Destroy(this.gameObject); } else { attackObj.SetActive(false); } } // Update is called once per frame void Update() { AnimatorStateInfo currentState = anim.GetCurrentAnimatorStateInfo(0); //通常の状態 if (currentState.IsName("zako-9_idle")) { if (timer > interval) { anim.SetTrigger("attack"); timer = 0.0f; } else { timer += Time.deltaTime; } } } void FixedUpdate() { if (!oc.playerStepOn) { if (sr.isVisible ) { } } else { if (!isDead) { anim.Play("zako-9_dead"); rb.velocity = new Vector2(0, -gravity); isDead = true; col.enabled = false; if (GManager.instance != null) { GManager.instance.PlaySE(deadSE); } } else { if (deadTimer > 1.0f) { Destroy(this.gameObject); } else { deadTimer += Time.deltaTime; } } } } public void Attack() { GameObject g = Instantiate(attackObj); g.transform.SetParent(transform); g.transform.position = attackObj.transform.position; g.SetActive(true); } }

↓敵が発射する弾のスクリプト

using System.Collections; using System.Collections.Generic; using UnityEngine; public class EnemyAttack : MonoBehaviour { [Header("スピード")] public float speed = 3.0f; [Header("最大移動距離")] public float maxDistance = 100.0f; private Rigidbody2D rb; private Vector3 defaultPos; // Start is called before the first frame update void Start() { rb = GetComponent<Rigidbody2D>(); if (rb == null) { Debug.Log("設定が足りません"); Destroy(this.gameObject); } defaultPos = transform.position; } // Update is called once per frame void FixedUpdate() { float d = Vector3.Distance(transform.position, defaultPos); //最大移動距離を超えている if (d > maxDistance) { Destroy(this.gameObject); } else { rb.MovePosition(transform.position + Vector3.left * Time.deltaTime * speed); } } private void OnTriggerEnter2D(Collider2D collision) { Destroy(this.gameObject); } }

↓移動する足場にいる敵の情報
イメージ説明
イメージ説明
イメージ説明

↓上記敵の子オブジェクトにしている弾の情報
イメージ説明
イメージ説明
イメージ説明

Unityバージョン:Unity 2019.2.15f1 (64-bit)

<追記>
↓Debug.Logを入れた弾のスクリプト

using System.Collections; using System.Collections.Generic; using UnityEngine; public class EnemyAttack : MonoBehaviour { [Header("スピード")] public float speed = 3.0f; [Header("最大移動距離")] public float maxDistance = 100.0f; private Rigidbody2D rb; private Vector3 defaultPos; // Start is called before the first frame update void Start() { rb = GetComponent<Rigidbody2D>(); if (rb == null) { Debug.Log("設定が足りません"); Destroy(this.gameObject); } defaultPos = transform.position; Debug.Log(defaultPos); } // Update is called once per frame void FixedUpdate() { float d = Vector3.Distance(transform.position, defaultPos); Debug.Log(transform.position); //最大移動距離を超えている if (d > maxDistance) { Debug.Log("超えました"); Destroy(this.gameObject); } else { rb.MovePosition(transform.position + Vector3.left * Time.deltaTime * speed); } } private void OnTriggerEnter2D(Collider2D collision) { Debug.Log("ぶつかりました"); Destroy(this.gameObject); } }

↓移動しない足場の敵で確認 (親オブジェクトである敵の座標:(10.9,-2.5,0))
イメージ説明
イメージ説明
生成されてすぐにぶつかり消滅、
イメージ説明
イメージ説明
2発目は、y座標の数値が-0.1違う状態で生成され、移動距離の限界まで移動している様です。

↓移動する足場の敵で確認 (親オブジェクトである敵の座標:(22.9,-2.5,0))
イメージ説明
イメージ説明
同じく、生成されてすぐにぶつかり消滅、
イメージ説明
イメージ説明
その後、移動する足場の関係で上下に移動している敵から生成され、
イメージ説明
イメージ説明
イメージ説明
しばらくの間、y座標の数値だけ0.1ずつ変化し続け、
再びぶつかり判定で消滅していました。

↓移動する足場のスクリプト

using System.Collections; using System.Collections.Generic; using UnityEngine; public class MoveObject : MonoBehaviour { [Header("移動経路")] public GameObject[] movePoint; [Header("速さ")] public float speed = 1.0f; private Rigidbody2D rb; private int nowPoint = 0; private bool returnPoint = false; private Vector2 oldPos = Vector2.zero; private Vector2 myVelocity = Vector2.zero; private void Start() { rb = GetComponent<Rigidbody2D>(); if (movePoint != null && movePoint.Length > 0 && rb != null) { rb.position = movePoint[0].transform.position; oldPos = rb.position; } } public Vector2 GetVelocity() { return myVelocity; } private void FixedUpdate() { if (movePoint != null && movePoint.Length > 1 && rb != null) { //通常進行 if (!returnPoint) { int nextPoint = nowPoint + 1; //目標ポイントとの誤差がわずかになるまで移動 if (Vector2.Distance(transform.position, movePoint[nextPoint].transform.position) > 0.1f) { //現在地から次のポイントへのベクトルを作成 Vector2 toVector = Vector2.MoveTowards(transform.position, movePoint[nextPoint].transform.position, speed * Time.deltaTime); //次のポイントへ移動 rb.MovePosition(toVector); } //次のポイントを1つ進める else { rb.MovePosition(movePoint[nextPoint].transform.position); ++nowPoint; //現在地が配列の最後だった場合 if (nowPoint + 1 >= movePoint.Length) { returnPoint = true; } } } //折返し進行 else { int nextPoint = nowPoint - 1; //目標ポイントとの誤差がわずかになるまで移動 if (Vector2.Distance(transform.position, movePoint[nextPoint].transform.position) > 0.1f) { //現在地から次のポイントへのベクトルを作成 Vector2 toVector = Vector2.MoveTowards(transform.position, movePoint[nextPoint].transform.position, speed * Time.deltaTime); //次のポイントへ移動 rb.MovePosition(toVector); } //次のポイントを1つ戻す else { rb.MovePosition(movePoint[nextPoint].transform.position); --nowPoint; //現在地が配列の最初だった場合 if (nowPoint <= 0) { returnPoint = false; } } } myVelocity = (rb.position - oldPos) / Time.deltaTime; oldPos = rb.position; } } }

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

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

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

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

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

guest

回答1

0

ベストアンサー

Attackメソッド内、Instantiate後にpositionを書き換えているので、
EnemyAttack内の「最大移動距離を超えている」判定を満たして直後にDestroyしているのではないでしょうか。

GameObject g = Instantiate(attackObj, attackObj.transform.position, Quaternion.identity, transform);
で、生成時点で親オブジェクトと位置の指定が出来るので試してみてください。
Object-Instantiate - Unity スクリプトリファレンス

2つ目の質問も同じ理由ではないかと推測されます。
1発目と2発目の間でattackObjの位置が変わったりしていないでしょうか。
とりあえず「Debug.Log」を用いて各値を確認しながら何が起こっているか把握してください。


なお、質問内のコードは画像ではなくテキストで入力してください。コピペも出来ず面倒臭いです。
参考→質問するときのヒント|teratail(テラテイル)

投稿2020/05/04 00:21

編集2020/05/04 07:36
sakura_hana

総合スコア11427

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

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

unity_user_a

2020/05/04 07:30

ご回答、ありがとうございます!スクリプトも、画像から「コードの挿入」に変更しました。 敵スクリプトのAttackメソッド内のGameObject g = を教えて頂いたものに変更した所、 error CS1061: 'GameObject' does not contain a definition for 'transfrom' and no accessible extension method 'transfrom' accepting a first argument of type 'GameObject' could be found (are you missing a using directive or an assembly reference?) と出ました。 始めたばかりで、自分で調べても具体的にどうすれば良いか分かりませんでした。 敵も弾も、Sceneビュー上のTransformは当然あるのですが、そのことではないのでしょうね。 何でも質問して申し訳ないのですが、何が原因で、どう修正すれば良いでしょうか?
sakura_hana

2020/05/04 07:35

attackObj.transfrom.position でスペルミスしてました、申し訳無いです。 transfrom→transform
unity_user_a

2020/05/04 17:31

こちらこそ、自分で気づくことが出来ず、お手を煩わせました。申し訳ありません。 エラーメッセージは表示されなくなりました。 まだ解決に向けて取り組んでいるところです。現時点で分かるのは、 ・1発目と2発目でattackObjの生成位置は変わっていない様子  1発目生成→直後に移動もせず消滅→1発目と同じ位置から2発目生成→設定した距離分移動して消滅 ・動く足場にいる敵の場合は、その2発目も生成位置で止まっており、その影響か、動かない足場の敵の2発目より消えるのが遅く、次に敵が攻撃モーションをするまで残っている ということです。 また、教えて頂いたコードですが、あれをそのままスクリプトに追加するだけでなく、transform.position,の部分や、);の前のtransformの部分に、特定の数値を自分で書き加えないといけないのでしょうか? 教えて頂いたことも理解しきれていない様で、申し訳ないです。
sakura_hana

2020/05/05 00:24

まずは「何が起こっているか」の把握に努めてください。 弾が消える条件は「最大移動距離を超えている」か「何かと衝突した(OnTriggerEnter2D)」時です。 この2つのどちらが起こっているのかDebug.Logで確認してください。(前者については、transform.positionとdefaultPosの値を確認してください) 「動く足場にいる敵の場合は、その2発目も生成位置で止まっており」というのはおかしいです。このコードだと消えるか動くかどちらかのはずなので。 動く足場のコードが影響していないか(例えば子オブジェクトの位置を強制的に指定しているとか)等を確認してみてください。 回答内に書いたコードは何かの追記は必要ありません。 リファレンス読み返しましたが元コードと処理自体は変わり無い気がしてきたので無視してもらってもいいです。
unity_user_a

2020/05/12 08:37

ご回答、ありがとうございました! あれからしばらく他の作業と並行して取り組み、敵のスクリプトを少し変えた所、「移動する足場の敵の弾が飛んで行かない」問題は解決しました。 「1発目が一瞬で消えて2発目が飛んで行く」のはどうにも出来なかったので、SEでチャージビーム的な効果音をつけることで、それっぽくすることで自己完結しました。 長々と手間をお掛けして、すみませんでした。高評価とベストアンサー、フォローもさせて頂きました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問