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

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

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

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

Q&A

解決済

1回答

994閲覧

取得したコライダーが取得されなくなったときの把握。

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

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

0グッド

0クリップ

投稿2018/12/02 14:10

前提・実現したいこと

PhysicsのOverlap系のメソッドで、
検知領域内に入ったオブジェクト(例えばキャラクター等)には、
そのオブジェクトが持っている振る舞いA(わかりやすくin_method)を実行し続け、
検知領域内に入っていないときは振る舞いB(out_method)を実行し続ける処理について考えています。
(振る舞いAも振る舞いBも、一度、それに対応する振る舞いメソッドが呼ばれたら、振る舞いし続けるものとします。)

この処理に関して、どういった設計で実装できるかご教示お願い致します。
いろいろなやり方があると思うので、この設計が1番良いという正解はないかもしれませんが、
もしベストな方法があれば知りたいですし、なくても、どういった設計があるのか知りたいです。
ご教示お願い致します。

試したこと

自分が考えた設計は下記2点です。

1点目。 UpdateのOverlapで予め検知で取得したコライダー配列を前のフレームの検知取得コライダー配列として保存しておく。 さらにUpdateで前フレームに取得したコライダーの配列と、Overlapで現在のフレームで取得しているコライダーの配列を比較し、 差分要素を抽出する。 差分要素が前フレーム配列に属しているものは、今のフレームで検知外に出たコライダーなので、out_methodを実行する。 差分要素が現在のフレーム配列に属しているものは、今回新たに検知されたコライダーなので、in_methodを実行する。 2点目。 予めフィールドに、検知に関して管理するオブジェクト全てを配列に格納しておく(all_arrという名前の配列にしておきます。) Updateでall_arrと、Overlapで取得したコライダー配列を比較する。 Overlapのコライダー配列に属している要素は、in_methodを呼ぶ。 all_arrの、Overlapのコライダー配列の要素を取り除いた要素は、out_methodを呼ぶ。

2点目に関しては、オブジェクトのフィールドに現在、検知内か検知外かを管理するフラグを立てておいて、
例えば、既に検知内のフラグが立っているのに、in_methodが呼ばれようとしてたら、フラグの条件分岐で、
in_methodは呼ばないことにして、重複呼び出しは避けます。
ただし、Update毎に必ず、all_arrの全ての要素のオブジェクトは、
少なくともフラグによる条件分岐を行わなければならないので、効率的じゃない気がして、
いい設計ではないような気がします。

この他の設計や、または自分が考えた設計に関して改善点等があればご教示お願い致します。

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

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

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

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

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

sakura_hana

2018/12/03 04:54

https://teratail.com/help/avoid-asking 「問題・課題が含まれていない質問」に該当すると思います。前回の質問で回答した通り、設計というのは大抵「プロジェクトによる」が最終結論になりがちです。案1と案2はどこがどうダメなのですか? 「効率的ではない気がする」というのはどんな観点からですか? 動作負荷を掛けていると思うなら本当にそうか実測する、開発やメンテナンス性が下がるというなら具体的なコードを提示して指摘してもらう等が必要でしょう。
退会済みユーザー

退会済みユーザー

2018/12/03 13:15

ご指摘ありがとうございます。 案1に関しては、恥ずかしながら設計はできているものの、コーディングに詰まっている状態です。 最初はこの実装方法について質問させていただこうと思ったのですが、 「設計ができているのに、コーディングができない」というのは質問しづらいと思いまして、 「また、そもそもこの設計で合っているのか?」という疑問もあって、 コーディングの質問をして、誰かにご教示いただいて解決した後に、 前回の質問の内容を覆す設計の質問をすることがしづらくなると思いました。 案2に関しては、Updateで毎回フラグを判定するのはあまりよくない方法ではないか?と 思っていました。 他の回答者様もご指摘いただいたように意図の分からない質問になってしまい、申し訳ないです。
sakura_hana

2018/12/04 07:38

「設計ができているのに、コーディングができない」→その為のteratailです(恥ずかしい等の感情論ならば分からなくもないですが)。/「前回の質問の内容を覆す設計の質問をすることがしづらくなる」→前回回答した人以外は気にしないでしょうし、前回回答した人も「諸事情により設計を変更しました」的な一文があれば「そうですか」で済みます。(無くても気にしない人は気にしないでしょう)/質問の回答としては私もedo_m18さんと同じく「コライダー配列要らないんじゃね?」という意見ですが、別の理由から必要であるというならば「配列を持つ方が設計として正しい(その方針で効率の良いコーディング方法を検討すべき)」になります。(「不特定多数の敵キャラ管理は、PhysicsのOverlap系で得たColliderの配列、全体を管理するオブジェクトが必要になってくるのでは」と思った理由が知りたいです)
退会済みユーザー

退会済みユーザー

2018/12/04 14:24 編集

ご指摘ありがとうございます。 teratailの在り方を理解してませんでした、ご教示いただきありがとうございます。 質問をすることに、ちょっと神経質に考え過ぎていました。 コライダー配列を必要とする理由はないです、それしか案が思い浮かばなかった為です。 コライダー配列を必要としない方法やコードを教えていただきたいです。
guest

回答1

0

ベストアンサー

ちょっと、やりたいことが詳細すぎてよく分からないのですが、達成したいことってなんでしょうか?
「とある範囲にキャラクターが入ったら動きを変える」みたいな動作で認識あってますか?

シンプルに考えるのであれば、全体を管理するオブジェクトを用意するのではなく、キャラクター自身で「とある範囲に入ったかどうか」を検知して振る舞いを変えるのがいいかなと思いました。
いわゆるAI的な感じで挙動を変えるってことですね。

質問を見ていると、全体を管理するオブジェクトの必要性をあまり感じなかったので。

投稿2018/12/02 15:08

edo_m18

総合スコア2283

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

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

退会済みユーザー

退会済みユーザー

2018/12/03 13:16

ご回答ありがとうございます。 分かりづらい質問で申し訳ないです。 「とある範囲にキャラクターが入ったら動きを変える」みたいな動作で合っていますし、 なおかつ、「とある範囲からキャラクターが出ても動きを変える」ことを考えています。 例えば、プレイヤー対不特定多数の敵キャラがいて、 プレイヤーの指定半径以内に敵キャラが入ったら、 敵キャラがプレイヤーに近づく(振る舞いA)、 プレイヤーの指定半径以内でなくなったら、 適当に辺りを散策する(振る舞いB)といったことをしたいです。 そうすると、プレイヤーの指定範囲以内という検知は、PhysicsのOverlap系のメソッドで、 不特定多数の敵キャラ管理は、PhysicsのOverlap系で得たColliderの配列、 全体を管理するオブジェクトが必要になってくるのではと考えました。 ただ、設計はできていて、コーディングできていないので、そもそも設計の時点から考え直そうと思い、 質問致しました。
edo_m18

2018/12/03 16:10

なるほど。その場合でも、逆に「とある範囲から出た」というタイミングであたりを散策する状態に戻せばいいかな、と思うのですがどうでしょうか。 全体を管理する必要が他にもありますか?
退会済みユーザー

退会済みユーザー

2018/12/04 14:24 編集

ご回答ありがとうございます。 全体を管理する必要はないです、それしか案が思い浮かばなかった為です。 「とある範囲から出た」というタイミング等は、どのようなコードを書けばよいでしょうか?
edo_m18

2018/12/05 01:37

やり方は色々ありますが、一番シンプルにやるなら、Triggerモードのコライダを設置して範囲を表現し、その範囲に「入った」「出た」を判定すればいいかな、と思います。 OnTriggerEnter / OnTriggerExitでそれぞれ検知が可能です。
退会済みユーザー

退会済みユーザー

2018/12/05 12:17

ご回答ありがとうございます。 プレイヤーが範囲検知する側だとしたら、プレイヤー側でTriggerモードのコライダを設置して範囲を表現し、敵のコライダーを検知するということですね。 2つの範囲を検知したい場合は、プレイヤーを親子構造にして、それぞれにTriggerモードのコライダをアタッチしなくてはダメですか? 例えば、プレイヤーの半径5メートル以内にいたら、敵キャラはプレイヤーに近づいてくる、プレイヤーの半径1メートル以内にいたら、敵キャラはプレイヤーに攻撃してくる、という実装をしたい場合です。 プレイヤーの1つのゲームオブジェクトに、2つの検知範囲のTriggerモードのコライダをアタッチしても、OnTriggerEnterやOnTriggerExitで、どっちの検知範囲のTriggerモードのコライダで検知したか区別することはできないですか?
edo_m18

2018/12/06 18:07

トリガーだと複数のコライダでの判定はできないですね。 ただ、プレイヤーに追従する検知エリア用オブジェクトを複数作って、それとの衝突判定を検知する、というやり方で複数範囲での検知はできると思います。
退会済みユーザー

退会済みユーザー

2018/12/07 17:21 編集

ご回答ありがとうございます。 すみません、プレイヤーに追従する検知エリア用オブジェクトとはどのようなオブジェクトですか? (コライダーオブジェクトなのか、それとも違うオブジェクトなのか考えましたがわかりませんでした。) スクリプトはそれぞれのオブジェクトにアタッチする形ですか? できればプレイヤーのヒエラルキーの構造とスクリプトのアタッチの構造の具体例を教えていただけませんか?
edo_m18

2018/12/10 01:40

このあたりは様々なやり方があり、どちらかというと発想の勝負となるところかなと思います。 Unityの基本的な構造とコンセプトを把握すると作りやすくなるかなと思ってます。 考えた手法としては、「判定用オブジェクト」を作り、そこにコライダと感知処理(コンポーネント)を追加。 それを、必要とするオブジェクト(今回の場合だとプレイヤー?)に「追従」する処理(コンポーネント)を入れる、という感じです。 追従に関しては、Updateでtransformをプレイヤーと同じ位置になるようにすることで可能です。
退会済みユーザー

退会済みユーザー

2018/12/10 12:52

ご回答ありがとうございます。 勉強になりました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問