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

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

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

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

1回答

2612閲覧

複雑なキャラクターの構造において、RigidbodyとColliderを共存させる方法

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

0クリップ

投稿2019/07/02 06:31

編集2019/07/03 12:58

全体的な流れと原因

プレイヤーがColliderに侵入したら、別の場所へテレポートするというプログラムを作ろうと思いましたが、上手くいきませんでした。原因は一応わかっているのですが、解決方法がわかりませんでした。
原因はSAColliderBuilderというAssetのせいでした。

イメージ説明
まず、頭、首、体、右腕、左腕、右足、左足のように体を7つに分割しました(ゲームの性質上、7つに分割しなければいけません)
Prim.00000000は、MeshColliderをつけるためのオブジェクト(MeshColliderがアタッチされていました)で、Default-Materialはそれをまとめるためのオブジェクト?だと思われます。
この二つのオブジェクトはSAColliderBuilderによって、自動生成されます。
そして、そのオブジェクトをPlayerというオブジェクトでまとめ、Playerには以下のようなComponentをアタッチしています。
イメージ説明
Controllはプレイヤーを動かすためのスクリプトです。

そして別に、Is Triggerをオンにしたオブジェクトを作りそこのColliderへPlayerが侵入すると、別の場所へテレポートするという仕組みです。

また、Playerオブジェクト自体に別に適当なBoxColliderをアタッチしたところ、正常に動き、テレポートしました。
結論としては、RigidBodyとColliderが別々のオブジェクトにアタッチされていたのが原因でした。
※PlayerにRigidBodyが付いていて、Prim.00000000にMeshColliderが付いていてしまっているということです。

RigidBodyとColliderを同じオブジェクトにアタッチしたいのですが、自分の力ではどうしてもすることが出来ませんでした。
何か解決策を教えていただけるとありがたいです。

プレイヤーをテレポートさせる際に、プレイヤーの侵入を検知し、座標を変えるスクリプト

このスクリプトは、Is Triggerをオンにした球形のコライダーを作り、そこにアタッチしたものです。
また、テレポート先にTptoという名のオブジェクトがあり、プレイヤーの侵入を検知した際に、そのオブジェクトにプレイヤーの座標を設定するという仕組みになっています。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class into1 : MonoBehaviour { 6 public GameObject Player; 7 public GameObject Tpto; 8 // Start is called before the first frame update 9 void Start () { 10 11 } 12 13 // Update is called once per frame 14 void Update () { 15 16 } 17 void OnTriggerEnter (Collider col1) { 18 if (col1.CompareTag ("Player")) { 19 Player.transform.position = Tpto.transform.position; 20 Debug.Log ("true"); 21 } 22 } 23}

試したこと

・Playerの中のBodyなどの一部のオブジェクトにRigidbodyとスクリプトを移動させたがそもそも移動できなくなった。
・MeshColliderを一つにまとめて、Playerに付けちゃおうと思ったが、そもそも一つにまとめてしまうと、オブジェクトごとに当たり判定を消すことができなくなってしまうので断念。

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

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

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

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

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

Bongo

2019/07/03 08:59

ちょっと気になったのですが、テレポートさせる仕組みの方に見直しの余地はなさそうでしょうか? もし差し支えなければテレポートのコードを見てみたいのですが、ご提示可能でしょうか。 個人的な考えでは、現状の「ルートオブジェクトにRigidbody、子オブジェクトにコライダー」の構造は形状の近似精度と調整のしやすさのバランスがよさそうで、これを崩してしまうのはもったいない気がするのですが...
退会済みユーザー

退会済みユーザー

2019/07/03 12:49

そうなんですよ...この構造はあまり崩したくはないんですよね... コードは追記しておきました。よろしくお願いします。
Bongo

2019/07/03 20:54

ご提示ありがとうございます。もう2つ確認させていただきたいのですが、まず現状の構造だとテレポート領域に触れたときどのような現象が起こるのでしょうか(テレポートしない、OnTriggerEnterが発生しない、OnTriggerEnter自体は発生するがコンソールに「true」が出ない...つまり条件判定をクリアできない、など)。もう一つ、ご提示のスクリーンショットではPlayerに「Player」タグがついていますが、それ以下の階層(各部位、Default-Material、Prim.00000000)にも全部「Player」タグを付けていますでしょうか?
退会済みユーザー

退会済みユーザー

2019/07/03 21:18

コンソールにtrueが表示されていなかったので、おそらくOnTriggerEnter自体動作していないと思います。 そして、以下の階層にもPlayerタグをつける必要があったんですね...解決しましたw 本当にありがとうございました! 一応確認させていただきたいのですが、基本的に子要素にColliderもしくはRigidbodyが別れている場合、 その子要素にもタグをつけないとColliderとRigidbodyの両方を検出できないため今回の場合、OnTriggerEnterが動作しなかったという認識でよろしいでしょうか?
退会済みユーザー

退会済みユーザー

2019/07/03 21:21

あとぜひBongoさんの回答をベストアンサーにしたいので、回答欄に今回の解決策を書いていただきたいです。
guest

回答1

0

ベストアンサー

解決されましたようで安心しました。お言葉に甘えまして回答欄にコメントさせていただきますと...

  1. プレイヤーの体のある部位がテレポート領域に触れる。
  2. テレポート領域のOnTriggerEnterが作動し、引数のcol1にはその部位のコライダーが渡される。
  3. たとえ一番上のプレイヤーオブジェクトに「Player」タグを付けていたとしても、今注目しているのはその部位のオブジェクトにアタッチされているコライダーなので(if (col1.CompareTag ("Player"))という風に、col1のタグが「Player」かどうかをチェックしている)、その部位に「Player」タグがついていないとif内に入らず、テレポートが発生しない。

という状況だった様子ですね。タグ設定はあくまでもそのオブジェクト自体にしか影響せず、子オブジェクトは親オブジェクトのタグ設定の影響を受けるわけではないため、このようなことになったものと考えられます。

OnTriggerEnter自体が発生していないのか、あるいは条件判定に失敗しているのかは、現状のコードですとコンソールに「true」が表示されるかどうかだけでは区別できないはずです。
区別するにはifの外にもなにかしらDebug.Logを入れて...

C#

1 void OnTriggerEnter (Collider col1) { 2 Debug.Log("OnTriggerEnter"); // ここはOnTriggerEnterが発生しさえすれば実行される 3 if (col1.CompareTag ("Player")) { 4 Player.transform.position = Tpto.transform.position; 5 Debug.Log ("true"); // ここはOnTriggerEnterが発生、かつ条件判定もクリアしないと実行されない 6 } 7 }

としてやる手があるでしょう。

  • 「OnTriggerEnter」と「true」が両方表示されれば正常
  • 「OnTriggerEnter」だけが表示されるなら条件判定の失敗
  • どちらも表示されないならOnTriggerEnter自体が発生していない(Is Triggerの設定ミスなど)

という風に、原因特定のヒントになるかと思います。

投稿2019/07/03 22:08

Bongo

総合スコア10807

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

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

退会済みユーザー

退会済みユーザー

2019/07/03 22:42

なるほど...細かい解説ありがとうございました!これからの参考にさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問