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

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

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

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

Q&A

1回答

7262閲覧

Unity OnTriggerExitの反応しない場合の解決策を教えて下さい。

yitpr

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

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

0グッド

0クリップ

投稿2021/04/24 03:27

前提・実現したいこと

自分が作ろうしているのは、横スクロール2Dアクションゲームです。HPがあり、敵に当たっている時間でHPが減っていきます。
質問したい事柄が多くなってしまったので、部分的にでも協力して頂きたいです。文字だけじゃわからないと思うのでどうにかして動画を添付します。
###質問内容
・OnTriggerExit問題の解決策
状況を説明すると、OnTriggerExitが、「プレイヤーのtransform.positionを直接書き換える」、又は「敵に当たり続けている時にその敵のcolliderが消える」と呼ばれないです。

現状、敵にプレイヤーの弾が当たると敵のcolliderをfalse(当たり判定を無くす)、死亡演出中の敵に重なってもダメージを受けない様にしているのですが、これだと敵に当たりながら球を当てて倒した場合にOnTriggerExitが呼ばれず、敵に当たり続けていると判定され、死亡してしまいます。理由は自分の敵判定ソースコード(関数chのflagが判定結果)が、

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4public class check : MonoBehaviour{ 5 public string tag1,tag2; 6 private bool enter,stay,exit; 7 private int flag = 0; 8 9 public int ch(){ 10 if (flag >= 0){ 11 if (enter || stay){ 12 flag = 1; 13 } 14 else if (exit){ 15 flag = 0; 16 } 17 18 enter = false; 19 stay = false; 20 exit = false; 21 return flag; 22 } 23 else{ 24 return flag; 25 } 26 } 27 private void OnTriggerEnter2D(Collider2D collision){ 28 if (collision.tag == tag1 || collision.tag==tag2){ 29 enter = true; 30 }else if (collision.tag=="death"){ 31 flag = -1; 32 } 33 } 34 private void OnTriggerStay2D(Collider2D collision){ 35 if (collision.tag == tag1 || collision.tag == tag2){ 36 stay = true; 37 }else if (collision.tag == "death"){ 38 flag = -1; 39 } 40 } 41 private void OnTriggerExit2D(Collider2D collision){ 42 if (collision.tag == tag1 || collision.tag == tag2){ 43 exit = true; 44 } 45 } 46} 47

と言った様に、Exitの判定が無いとtrueになり続けてしまうからです。これは、穴に落ち、[death]というtagを設定したcolliderに当たり、プレイヤーが即死する際も、リスポーン地点にプレイヤーを移動させるとExit判定がもらえないのでまた即死判定になります。敵の判定は諦めて、プレイヤーをプレハブにしてinstantiateで復活させようと思いましたが、それだとカメラが付いて来ず、諦めました。
なにかいい死亡判定、又は問題の解決策はあるでしょうか。

・リスポーン(GameOverでない)、そして敵の再配置
プレイヤーのHPがなくなったらスタート地点(または中間地点)に戻る動きをさせたいです。この際、一度暗転、待ち時間を設けたいです。
現状、OnTriggerExitの仕様を理由に、実現出来ていません。(HPが無くなってから5秒後にスタート地点に移動しますが、そこで無限に死に続けます)

プレイヤーリスポーン時、ステージ上の敵を倒していた場合、それを復活させたいです。スタート時(シーン生成時?)にステージの指定の場所に敵を配置、また、プレイヤーリスポーン時に倒された敵(又は全ての敵)を置き直し、と言った動きはどうすれば良いでしょうか。**もし、シーン読み込み直しでできるのならやり方を教えてくださいお願いします。**その際、残機と中間地点の情報は引き継げるでしょうか。

Tilemapの引っかかりについて
これはもうほとんど諦めているのですが、「プレイヤーの前方に地面判定があるとその方向に進めなくする」というプログラムを組んで、壁に向かって走れない様にしているのですが、何故か判定する時としない時があり、プレイヤーより大きい壁は殆ど反応しません。そして、さらに時々、何故か頭がTilemapに引っかかります。頭判定のスクリプトを切っても引っかかるので、box colliderがぶつかってるのかと思いますが、そんな筈ない作りで、もうお手上げです。摩擦0、Tilemapの colliderはCompositeにしてこれです。
なにか「これしてないんじゃ無い?」というものはあるでしょうか。

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

プレイヤーと敵が衝突してほくしなかったので

プレイヤーの当たり判定オブジェクト(is Trigger)(レイヤーdefault)
↓子オブジェ
地面、頭、敵、前方の判定用オブジェクト(is Trigger)(レイヤーdefault)
↓子オブジェ
Tilemapの上に乗る為だけの当たり判定オブジェクト(istriggerなし)(敵と重ならず下に落ちないレイヤー)

という作りのゲームオブジェクトにしてます。
基本的にゲームの作りはリンク内容この方のものを参考にして作っています。
unity バージョン2020.3.3f1

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

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

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

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

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

guest

回答1

0

OnTriggerExitが、「プレイヤーのtransform.positionを直接書き換える」、又は「敵に当たり続けている時にその敵のcolliderが消える」と呼ばれない

質問者さんは、起きている状況を上記のように捉えているわけですが、実際は逆です(断定してますが、考え方はいろいろあると思います)。

どういうことかというと、この状況は

「プレイヤーのtransform.positionを直接書き換えた」時、又は「敵に当たり続けている時にその敵のcolliderが消えた」時にも、フラグをリセットする必要がある

と考えられるということです。

となると、コードのなかのOnTriggerExit2D内でやっているフラグの処理を別の関数として独立させて、その関数を、OnTriggerExit2Dと「プレイヤーのtransform.positionを直接書き換えた」時、又は「敵に当たり続けている時にその敵のcolliderが消えた」時に呼び出すようにすれば良いと思います。

コードにすると以下のような感じですね。

csharp

1 public void ResetFlag(){ 2 exit = true; 3 } 4 5 private void OnTriggerExit2D(Collider2D collision){ 6 if (collision.tag == tag1 || collision.tag == tag2){ 7 ResetFlag() 8 } 9 }

で、ResetFlag()を「プレイヤーのtransform.positionを直接書き換えた」時、又は「敵に当たり続けている時にその敵のcolliderが消えた」時に呼び出すようにするわけです。

後は、「敵に当たり続けている時にその敵のcolliderが消えた時に呼び出す」方法ですが、敵キャラのほうで、OnTriggerEnter2Dでプレイヤーキャラ(のオブジェクト)を取得しておいて、敵のcolliderを消す処理をするときに、プレイヤーキャラのResetFlag()を呼び出す感じでしょうか。
(あくまで例なのでこの説明どおりにする必要はないです。)

余談ですが、変数enter,stay,exitは同時にtrueになることはないので、列挙型(enum)にしてしまったほうが良いです。

投稿2021/04/27 03:14

JunSuzukiJapan

総合スコア314

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

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

yitpr

2021/05/02 16:23

すみません、実装出来てから「ありがとうございます!できました!」と返信したかったのですが、手こずってしまい、先に返信をします。 お陰様で、当たりながら倒した時など、Exitの判定を正しくできる様になりました。enumを使って上記のプログラムを書き換え、動作させることもできました。enumは知らない事だったので、勉強になりました。ありがとうございます。  …、こういった問題は、本来自分で解決策を見つけるべき所、この様な分かりづらい質問をしてしまい、さらに回答までして頂いて本当に申し訳ないです。 これからは、新たに出てきた問題と上記の問題3つを解決できる様頑張ります。 またここに変な質問をしに来ていた時はすみません。どうかお力添えを…。 本当にありがとうございました!!
JunSuzukiJapan

2021/05/03 01:25 編集

回答を「受付中」になっているので、一度、「解決済み」にしたほうが良いかもしれません。 まだ解決できてない問題は、改めて質問するということで。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問