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

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

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

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

Unity3D

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

Unity

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

Q&A

解決済

1回答

616閲覧

Unity2021,3,21f1にて、

musou_ryunen

総合スコア3

C#

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

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2023/04/04 18:42

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • 3Dゲームにて、UnitychanがCubeを子に含む"Item"というColliderに接触することで、アイテムを取得できるようにする

前提

このteratailというサービスを利用するのは初めてですので、技術面およびコミュニケーション面で至らない点があるかもしれませんがご鞭撻いただけますと幸いです。

Unityにて、UnitychanがItemに接触して収集する3Dゲームシステムを作っています。
言語はC#、ソースコードはVisualStudioで書いております。
Unitychanは公式の無料asset、Cube等は「ステップアップUnity プロが教える現場の教科書」のP58以降をほぼそっくりそのまま書いております。
エラーメッセージは表示されていないのですが、UnitychanがItemに接触しても取得することができず、どうしたものかと相談に来ました。

追記できるようでしたら、都度情報を追加していきますが、いったん手持ちのわかる範囲でお見せしております。

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

エラーメッセージ

なし

該当のソースコード

ソースコード // // Mecanimのアニメーションデータが、原点で移動しない場合の Rigidbody付きコントローラ // サンプル // 2014/03/13 N.Kobyasahi // using UnityEngine; using System.Collections; namespace UnityChan { // 必要なコンポーネントの列記 [RequireComponent(typeof(Animator))] [RequireComponent(typeof(CapsuleCollider))] [RequireComponent(typeof(Rigidbody))] public class UnityChanControlScriptWithRgidBody : MonoBehaviour { public float animSpeed = 1.5f; // アニメーション再生速度設定 public float lookSmoother = 3.0f; // a smoothing setting for camera motion public bool useCurves = true; // Mecanimでカーブ調整を使うか設定する // このスイッチが入っていないとカーブは使われない public float useCurvesHeight = 0.5f; // カーブ補正の有効高さ(地面をすり抜けやすい時には大きくする) // 以下キャラクターコントローラ用パラメタ // 前進速度 public float forwardSpeed = 7.0f; // 後退速度 public float backwardSpeed = 2.0f; // 旋回速度 public float rotateSpeed = 2.0f; // ジャンプ威力 public float jumpPower = 3.0f; // キャラクターコントローラ(カプセルコライダ)の参照 private CapsuleCollider col; private Rigidbody rb; // キャラクターコントローラ(カプセルコライダ)の移動量 private Vector3 velocity; // CapsuleColliderで設定されているコライダのHeiht、Centerの初期値を収める変数 private float orgColHight; private Vector3 orgVectColCenter; private Animator anim; // キャラにアタッチされるアニメーターへの参照 private AnimatorStateInfo currentBaseState; // base layerで使われる、アニメーターの現在の状態の参照 private GameObject cameraObject; // メインカメラへの参照 // アニメーター各ステートへの参照 static int idleState = Animator.StringToHash ("Base Layer.Idle"); static int locoState = Animator.StringToHash ("Base Layer.Locomotion"); static int jumpState = Animator.StringToHash ("Base Layer.Jump"); static int restState = Animator.StringToHash ("Base Layer.Rest"); // 初期化 void Start () { // Animatorコンポーネントを取得する anim = GetComponent<Animator> (); // CapsuleColliderコンポーネントを取得する(カプセル型コリジョン) col = GetComponent<CapsuleCollider> (); rb = GetComponent<Rigidbody> (); //メインカメラを取得する cameraObject = GameObject.FindWithTag ("MainCamera"); // CapsuleColliderコンポーネントのHeight、Centerの初期値を保存する orgColHight = col.height; orgVectColCenter = col.center; } // 以下、メイン処理.リジッドボディと絡めるので、FixedUpdate内で処理を行う. void FixedUpdate() { float h = Input.GetAxis ("Horizontal"); // 入力デバイスの水平軸をhで定義 float v = Input.GetAxis ("Vertical"); // 入力デバイスの垂直軸をvで定義 anim.SetFloat ("Speed", v); // Animator側で設定している"Speed"パラメタにvを渡す anim.SetFloat ("Direction", h); // Animator側で設定している"Direction"パラメタにhを渡す anim.speed = animSpeed; // Animatorのモーション再生速度に animSpeedを設定する currentBaseState = anim.GetCurrentAnimatorStateInfo (0); // 参照用のステート変数にBase Layer (0)の現在のステートを設定する rb.useGravity = true; //ジャンプ中に重力を切るので、それ以外は重力の影響を受けるようにする // 以下、キャラクターの移動処理 velocity = new Vector3 (0, 0, v); // 上下のキー入力からZ軸方向の移動量を取得 // キャラクターのローカル空間での方向に変換 velocity = transform.TransformDirection (velocity); //以下のvの閾値は、Mecanim側のトランジションと一緒に調整する if (v > 0.1) { velocity *= forwardSpeed; // 移動速度を掛ける } else if (v < -0.1) { velocity *= backwardSpeed; // 移動速度を掛ける } if (Input.GetButtonDown ("Jump")) { // スペースキーを入力したら //アニメーションのステートがLocomotionの最中のみジャンプできる if (currentBaseState.nameHash == locoState) { //ステート遷移中でなかったらジャンプできる if (!anim.IsInTransition (0)) { rb.AddForce (Vector3.up * jumpPower, ForceMode.VelocityChange); anim.SetBool ("Jump", true); // Animatorにジャンプに切り替えるフラグを送る } } } // 上下のキー入力でキャラクターを移動させる transform.localPosition += velocity * Time.fixedDeltaTime; // 左右のキー入力でキャラクタをY軸で旋回させる transform.Rotate (0, h * rotateSpeed, 0); // 以下、Animatorの各ステート中での処理 // Locomotion中 // 現在のベースレイヤーがlocoStateの時 if (currentBaseState.nameHash == locoState) { //カーブでコライダ調整をしている時は、念のためにリセットする if (useCurves) { resetCollider (); } } // JUMP中の処理 // 現在のベースレイヤーがjumpStateの時 else if (currentBaseState.nameHash == jumpState) { cameraObject.SendMessage ("setCameraPositionJumpView"); // ジャンプ中のカメラに変更 // ステートがトランジション中でない場合 if (!anim.IsInTransition (0)) { // 以下、カーブ調整をする場合の処理 if (useCurves) { // 以下JUMP00アニメーションについているカーブJumpHeightとGravityControl // JumpHeight:JUMP00でのジャンプの高さ(0〜1) // GravityControl:1⇒ジャンプ中(重力無効)、0⇒重力有効 float jumpHeight = anim.GetFloat ("JumpHeight"); float gravityControl = anim.GetFloat ("GravityControl"); if (gravityControl > 0) rb.useGravity = false; //ジャンプ中の重力の影響を切る // レイキャストをキャラクターのセンターから落とす Ray ray = new Ray (transform.position + Vector3.up, -Vector3.up); RaycastHit hitInfo = new RaycastHit (); // 高さが useCurvesHeight 以上ある時のみ、コライダーの高さと中心をJUMP00アニメーションについているカーブで調整する if (Physics.Raycast (ray, out hitInfo)) { if (hitInfo.distance > useCurvesHeight) { col.height = orgColHight - jumpHeight; // 調整されたコライダーの高さ float adjCenterY = orgVectColCenter.y + jumpHeight; col.center = new Vector3 (0, adjCenterY, 0); // 調整されたコライダーのセンター } else { // 閾値よりも低い時には初期値に戻す(念のため) resetCollider (); } } } // Jump bool値をリセットする(ループしないようにする) anim.SetBool ("Jump", false); } } // IDLE中の処理 // 現在のベースレイヤーがidleStateの時 else if (currentBaseState.nameHash == idleState) { //カーブでコライダ調整をしている時は、念のためにリセットする if (useCurves) { resetCollider (); } // スペースキーを入力したらRest状態になる if (Input.GetButtonDown ("Jump")) { anim.SetBool ("Rest", true); } } // REST中の処理 // 現在のベースレイヤーがrestStateの時 else if (currentBaseState.nameHash == restState) { //cameraObject.SendMessage("setCameraPositionFrontView"); // カメラを正面に切り替える // ステートが遷移中でない場合、Rest bool値をリセットする(ループしないようにする) if (!anim.IsInTransition (0)) { anim.SetBool ("Rest", false); } } void OnGUI () { GUI.Box (new Rect (Screen.width - 260, 10, 250, 150), "Interaction"); GUI.Label (new Rect (Screen.width - 245, 30, 250, 30), "Up/Down Arrow : Go Forwald/Go Back"); GUI.Label (new Rect (Screen.width - 245, 50, 250, 30), "Left/Right Arrow : Turn Left/Turn Right"); GUI.Label (new Rect (Screen.width - 245, 70, 250, 30), "Hit Space key while Running : Jump"); GUI.Label (new Rect (Screen.width - 245, 90, 250, 30), "Hit Spase key while Stopping : Rest"); GUI.Label (new Rect (Screen.width - 245, 110, 250, 30), "Left Control : Front Camera"); GUI.Label (new Rect (Screen.width - 245, 130, 250, 30), "Alt : LookAt Camera"); } // キャラクターのコライダーサイズのリセット関数 void resetCollider () { // コンポーネントのHeight、Centerの初期値を戻す col.height = orgColHight; col.center = orgVectColCenter; } void OnCollisionEnter(Collider other) { if (other.gameObject.CompareTag("Item")) { Item item = other.gameObject.GetComponent<Item>(); item.Gotten(); } } } } }

試したこと

ここに問題に対して試したことを記載してください。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

OnCollisionEnterは、FixedUpdate()のメソッドの外に出してあげてください。

コード自体は2Dのですが、参考例:
https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnCollisionEnter2D.html

あとは、デバッグログ仕込んでコリジョンヒット自体が通っているかも確認すると良いかと思います。

cs

1 void OnCollisionEnter(Collider other) 2 { 3 Debug.log("collision hit : " + other.gameObject.name); 4 if (other.gameObject.CompareTag("Item")) 5 { 6 Item item = 7 other.gameObject.GetComponent<Item>(); 8 item.Gotten(); 9 } 10 }

投稿2023/04/05 09:24

編集2023/04/05 09:24
hogefugapiyo

総合スコア3302

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

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

musou_ryunen

2023/04/06 18:59 編集

質問者です。 ご回答ありがとうございます。 ご指摘通り、FixedUpdate()の外に出しました。 またデバッグログを利用して、Item(Clone)としてコリジョンヒット自体が通っていることは確認したのですが、Itemが消える演出は起きない状態になっております。 デバッグログを確認したところ、If文の{}内にデバッグログを配置した場合、反応が起きなかったです。つまり、Itemにタグ付けされた障害物に衝突したという状況がおきていないのではないか、そもそもItemタグが正しく設定されていないのでは?と考えています。 素人考えなのですが、例えばItem(Clone)とItemが別の物として判定されている可能性はあるでしょうか?ただし、デバッグログで衝突した障害物のタグ名がItemとなっている場合でも、If文内のデバッグログは反応しませんでした。 他に、うまくいかない場合のお心当たり等ございますでしょうか?
hogefugapiyo

2023/04/07 02:12 編集

ヒット自体は取れているということなので、あとは細かくDebug.Log仕込んで確認していって潰していくのがいいのかなと思います。 既にやられたのかもですが、デバッグログを書き換えてあたった相手のタグも表示するようにしておく Debug.log("collision hit : " + other.gameObject.name + " / tag: " + other.gameObject.tag); まず、これでアイテムへのヒット判定は取れているか、アイテムのタグは「Item」となっているかなどを確認してみると良いかと思います。 Cubeを子に持つというのもちょっと気にはなっていたので、例えばダミーで良いので素のCubeを作ってタグだけ「Item」に変更し、それに接触したら判定取れるか、など条件を変えて試すのも良いと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.44%

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

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

質問する

関連した質問