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

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

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

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

Unity3D

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

Unity

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

Q&A

解決済

1回答

1587閲覧

モーションをアタッチした3Dモデルを操作できず、床との物理判定が適用されない

tsk1999

総合スコア8

C#

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

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2020/09/26 07:39

前提・実現したいこと

AssetStoreの「BasicMotions FREE Pack」を使って、モーションをアタッチした3Dモデルを操作したい(WASDで移動、spaceでジャンプ)
床と接地しているときにジャンプを行えるようにする。

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

AnimationControllerでモーションの遷移を設定し、Rigidbodyなどの設定も行ったが、操作対象のモデルが床を貫通して落下してしまう。接地していないのでモーションが行えない。
イメージ説明
イメージ説明

該当のソースコード

using System.Collections; using System.Collections.Generic; using UnityEngine; public class CharCon : MonoBehaviour { private float walkSpeed = 2.0f; // 歩行速度 private float runSpeed = 4.0f; // 走行速度 private Vector3 movement; // 移動するベクター private float gravity = 20.0f; // キャラへの重力 private float speedSmoothing = 10.0f; // 回頭するときの滑らかさ private float rotateSpeed = 500.0f; // 回頭の速度 private float runAfterSeconds = 0.1f; // 走り終わったとき止まるまでの時間(秒) private Vector3 moveDirection = Vector3.zero; // カレント移動方向 private float verticalSpeed = 0.0f; // カレント垂直方向速度 private float moveSpeed = 0.0f; // カレント水平方向速度 private CollisionFlags collisionFlags; // controller.Move が返すコリジョンフラグ:キャラが何かにぶつかったとき使用 private float walkTimeStart = 0.0f; // 歩き始める速度 // Use this for initialization void Start() { moveDirection = transform.TransformDirection(Vector3.forward); // キャラの移動方向をキャラの向いている方向にセットする } // Update is called once per frame void Update() { Transform cameraTransform = Camera.main.transform; // カメラの向いている方向を得る Vector3 forward = cameraTransform.TransformDirection(Vector3.forward); // camera の x-z 平面から forward ベクターを求める forward.y = 0; // Y方向は無視:キャラは水平面しか移動しないため forward = forward.normalized; // 方向を正規化する Vector3 right = new Vector3(forward.z, 0, -forward.x); // 右方向ベクターは常にforwardに直交 float v = Input.GetAxisRaw("Vertical"); // 垂直方向の値 float h = Input.GetAxisRaw("Horizontal"); // 水平方向の値 float sp = Input.GetAxis("File3"); Vector3 targetDirection = h * right + v * forward; // カメラと連動した進行方向を計算:視点の向きが前方方向 if ((collisionFlags & CollisionFlags.CollidedBelow) != 0 && sp==0) // 接地時 { if (targetDirection != Vector3.zero) { if (moveSpeed < walkSpeed * 0.9) { moveDirection = targetDirection.normalized; } else { moveDirection = Vector3.RotateTowards(moveDirection, targetDirection, rotateSpeed * Mathf.Deg2Rad * Time.deltaTime, 1000); moveDirection = moveDirection.normalized; } } float curSmooth = speedSmoothing * Time.deltaTime; // 向きをスムースに変更 float targetSpeed = Mathf.Min(targetDirection.magnitude, 1.0f); // 最低限のスピードを設定 // 歩く速度と走る速度の切り替え:最初は歩いてで時間がたつと走る if (Time.time - runAfterSeconds > walkTimeStart) targetSpeed *= runSpeed; else targetSpeed *= walkSpeed; // 移動速度を設定 moveSpeed = Mathf.Lerp(moveSpeed, targetSpeed, curSmooth); Animator animator = GetComponent<Animator>(); // Animator コンポーネントを得る animator.SetFloat("speed", moveSpeed); // Animator に移動速度のパラメータを渡す animator.SetBool("air", false); // Animator に落下フラグのパラメータを渡す:落下していない if (moveSpeed < walkSpeed * 0.3) // まだ歩きはじめ walkTimeStart = Time.time; // その時間を保存しておく verticalSpeed = 0.0f; // 垂直方向の速度をゼロに設定 } else // 宙に浮いている { Animator animator = GetComponent<Animator>(); // Animator コンポーネントを得る animator.SetBool("air", true); // Animator に落下フラグのパラメータを渡す:落下している } movement = moveDirection * moveSpeed + new Vector3(0, verticalSpeed, 0); // キャラの移動量を計算 movement *= Time.deltaTime; CharacterController controller = GetComponent<CharacterController>(); // キャラクターコントローラコンポーネントを取得 collisionFlags = controller.Move(movement); // キャラを移動をキャラクターコントローラに伝える if ((collisionFlags & CollisionFlags.CollidedBelow) != 0) // 宙に浮いていない場合 { transform.rotation = Quaternion.LookRotation(moveDirection); // 移動方向に回頭:浮いていると回頭しない } } }

試したこと

3DモデルにColliderコンポーネントの代わりにCharacterControllerを設定。
![イメージ説明

plane(床)のコンポーネント
イメージ説明

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

文献としてUnityゲーム プログラミングバイブルを参考にし、プログラムもNo.3のサンプルを改変したものです。

Unityのバージョンは2020.1.4f1です。

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

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

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

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

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

ayousanz

2020/09/27 16:41

キャラクターにColliderがついていないように見えるのですが,つけていますか?
tsk1999

2020/09/28 15:29

キャラクターの親オブジェクトと子オブジェクトにColiderを加えたのですが変化はありませんでした...。
guest

回答1

0

ベストアンサー

planeのBoxColliderのisTriggerのチェックを外しましょう
isTriggerが有効だとすり抜けます

あとCharacterControllerにColliderついてるので、
キャラクターの親オブジェクトと子オブジェクトに加えたColliderを消してください
Animatorが付いてる3DモデルにCharacterControllerとCharConだけを追加すればサンプルみたいに動作すると思います

ついでにCharacterControllerとRigidbodyは1つのオブジェクトに両方ともつけてしまうと挙動がおかしくなってしまうらしいのでRigidbodyは外した方がいいと思います

追記
① AnimatorウィンドウのParametersの+ → Float を押してパラメータを追加して(CharCon.csにanimator.SetFloat("speed", moveSpeed);ってあるので)"speed"に名前を変えます

② IDLEアニメーションからWALKアニメーションに遷移する矢印を選びます

③ +押して"speed"を選んでGreaterに変えて、適当に数値を入れます

④ Has Exit Timeのチェックを外します

イメージ説明

とりあえずこれで歩くモーションをしてくれると思います
他の遷移は考えてみてください
Has Exit Timeに関してはオンオフしてどう変わるか試したり、調べてみてください

投稿2020/09/30 17:31

編集2020/10/01 14:04
lazh

総合スコア300

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

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

tsk1999

2020/10/01 12:54

モデルをCharacterController、床をColliderのみにしたところ、床を貫通する問題は解決できました。残るはモーションの操作ですが...。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問