🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

Unity3D

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

Q&A

解決済

1回答

1599閲覧

ヒト型のキャラクターがrigidbody colliderで坂や壁をすり抜けないようにしたい

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity3D

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

0グッド

0クリップ

投稿2019/11/01 09:33

編集2019/11/01 13:41

キャラクターがある一定の角度を超えるとすり抜けてしまう現象が起きてしまいます!
もしよろしければ対処方やコードを教えてもらえると幸いです!
using System. Collections;
using System.Collections.Generic;
using UnityEngine;
public class situmonyou: MonoBehaviour
{
[SerializeField]
private CapsuleCollider charaCon;
private Animator animCon; // アニメーションするための変数
private Vector3 moveDirection; // 移動する方向とベクトル(動く力、速度)の変数(最初は初期化しておく)
// レイを飛ばす体の位置
[SerializeField]
private Transform charaRay;
// レイの距離
[SerializeField]
private float charaRayRange = 0.2f;
// レイが地面に到達しているかどうか
private bool isGround;
// rigidbody
private Rigidbody rigid;
private bool isGroundCollider = false;
// 段差を昇る為のレイを飛ばす位置
[SerializeField]
private Transform stepRay;
// レイを飛ばす距離
[SerializeField]
private float stepDistance = 0.5f;
// 昇れる段差
[SerializeField]
private float stepOffset = 0.3f;
// 昇れる角度
[SerializeField]
private float slopeLimit = 65f;
// 昇れる段差の位置から飛ばすレイの距離
[SerializeField]
private float slopeDistance = 1f;
// ステップアップする力
[SerializeField]
private float stepUpPower = 1.5f;
// ヒットした情報を入れる場所
private RaycastHit stepHit;
//public float:インスペクタで調整可能な変数
[SerializeField]
private float idoSpeed = 1.5f; // 移動速度
public float rotateSpeed = 3.0F; // 向きを変える速度
public float kaitenSpeed = 1200.0f; // プレイヤーの回転速度
public float gravity = 10.0F; //重力の強さ
[SerializeField]
public float jumpPower = 5f; //ジャンプのスピード
// キャラの回転スピード
[SerializeField]
private float charaRotateSpeed = 45f;
public Vector3 groundNormal = Vector3.zero;
private Vector3 lastGroundNormal = Vector3.zero;
[System.NonSerialized]
public Vector3 lastHitPoint = new Vector3(Mathf.Infinity, 0, 0);
protected float groundAngle = 0;
// 地面から離れたとする距離
public float distanceToTheGround = 2.5f;
// 着地アニメーションへと変わる距離
public float distanceToLanding = 2.5f;
// 地面との距離を計る為のレイを飛ばす位置
private Transform spine;
void Start()
{
animCon = GetComponent<Animator>(); // アニメーターのコンポーネントを参照する
moveDirection = Vector3.zero;
myStatus = GetComponent<MyStatus>();
spine = animCon.GetBoneTransform(HumanBodyBones.Spine);
isGround = false;
rigid = GetComponent<Rigidbody>();
state = MyState.Normal;
}
void Update()
{
// ▼▼▼カメラの難しい処理▼▼▼
var cameraForward = Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized; // カメラが追従するための動作
Vector3 direction = cameraForward * Input.GetAxis("Vertical") + Camera.main.transform.right * Input.GetAxis("Horizontal");

if (Input.GetAxis("Vertical") == 0 && Input.GetAxis("Horizontal") == 0) // テンキーや3Dスティックの入力(GetAxis)がゼロの時の動作 { } else // テンキーや3Dスティックの入力(GetAxis)がゼロではない時の動作 { MukiWoKaeru(direction); // 向きを変える動作の処理を実行する(後述) } if (state == MyState.Normal) { // ▼▼▼落下処理▼▼▼ if (!isGroundCollider) { if (Physics.Linecast(charaRay.position, (charaRay.position - transform.up * charaRayRange))) { isGround = true; rigid.useGravity = true; } else { isGround = false; rigid.useGravity = false; } Debug.DrawLine(charaRay.position, (charaRay.position - transform.up * charaRayRange), Color.red); } // キャラクターコライダが接地、またはレイが地面に到達している場合 if (isGroundCollider || isGround) { // 地面に接地してる時は初期化 if (isGroundCollider) { rigid.useGravity = true; moveDirection = Vector3.zero; //Y方向への速度をゼロにする moveDirection = direction * idoSpeed; //移動スピードを向いている方向に与える animCon.SetBool("Fall", false); animCon.SetBool("Jump", false); } else { moveDirection = new Vector3(0f, moveDirection.y, 0f); } if (moveDirection.magnitude > 0f) { //着地後移動キーを押したら着地アニメーション終了 animCon.SetBool("Landing", false); animCon.SetFloat("Speed", moveDirection.magnitude); transform.LookAt(transform.position + moveDirection); Debug.DrawLine(transform.position + new Vector3(0f, stepOffset, 0f), transform.position + new Vector3(0f, stepOffset, 0f) + transform.forward * slopeDistance, Color.green); // ステップ用のレイが地面に接触しているかどうか if (Physics.Linecast(stepRay.position, stepRay.position + stepRay.forward * stepDistance, out stepHit, LayerMask.GetMask("Field", "Block"))) { // ステップアップ用のレイが地面と接触していない if (!Physics.Linecast(transform.position + new Vector3(0f, stepOffset, 0f), transform.position + new Vector3(0f, stepOffset, 0f) + transform.forward * slopeDistance, LayerMask.GetMask("Field", "Block"))) { moveDirection = Vector3.up * stepUpPower + transform.forward * idoSpeed; // 接触した地面が登れる坂の角度以下 } else if (Vector3.Angle(transform.up, stepHit.normal) <= slopeLimit) { moveDirection = Quaternion.FromToRotation(Vector3.up, stepHit.normal) * transform.forward * idoSpeed; // それ以外は前進のみ } else { moveDirection += transform.forward * idoSpeed; } // ステップ用のレイが地面に接触していなければ } else { moveDirection += transform.forward * idoSpeed; } } //キーの押しが小さすぎる場合は移動しない else { animCon.SetFloat("Speed", 0f); } if (Input.GetKeyDown("space") || Input.GetButtonDown("Jump") && !animCon.GetCurrentAnimatorStateInfo(0).IsName("Jump") && !animCon.IsInTransition(0))//Spaceキーorジャンプボタンが押されている場合 { moveDirection.y += jumpPower; //Y方向への速度に「ジャンプパワー」の変数を代入する animCon.SetBool("Jump", true); rigid.useGravity = false; } /*else { // ジャンプキーを押していない時は下向きに力を加える moveDirection += addForceDownPower; } } else if (!animCon.GetBool("Fall")) { Debug.DrawLine(spine.position, spine.position + Vector3.down * distanceToTheGround, Color.red); if (!Physics.SphereCast(new Ray(spine.position, Vector3.down), charaCon.radius, distanceToTheGround, LayerMask.GetMask("Field"))) { animCon.SetBool("Fall", true); } } else if (animCon.GetBool("Fall") || animCon.GetBool("Jump")) { Debug.DrawLine(spine.position, spine.position + Vector3.down * distanceToLanding, Color.green); if (Physics.Linecast(spine.position, spine.position + Vector3.down * distanceToLanding, LayerMask.GetMask("Field"))) { animCon.SetBool("Landing", true); } } if (!isGroundCollider && !isGround) //CharacterControllerの付いているこのオブジェクトが接地していない場合の処理 { rigid.useGravity = true; moveDirection.y += Physics.gravity.y * Time.deltaTime;//マイナスのY方向(下向き)に重力を与える if (Input.GetButtonDown("Fire1") && myStatus.GetWeaponStatus() != null && myStatus.GetWeaponStatus().GetWeaponType() == WeaponStatus.WeaponType.Sword) { animCon.SetBool("JumpAttack", true); } else { animCon.SetBool("JumpAttack", false); } } } void FixedUpdate() { // キャラクターを移動させる処理 rigid.MovePosition(transform.position + moveDirection * Time.deltaTime); } void OnCollisionEnter() { Debug.DrawLine(charaRay.position, charaRay.position + Vector3.down, Color.blue); // 他のコライダと接触している時は下向きにレイを飛ばしFieldかBlockレイヤーの時だけ接地とする if (Physics.Linecast(charaRay.position, charaRay.position + Vector3.down, LayerMask.GetMask("Field", "Block"))) { isGroundCollider = true; } else { isGroundCollider = false; } } // 接触していなければ空中に浮いている状態 void OnCollisionExit() { isGroundCollider = false; }

イメージ説明
イメージ説明
イメージ説明
イメージ説明

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

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

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

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

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

KanazawaKureha

2019/11/01 11:08

少なくとも、 ・どのようなキャラクターなのか ・キャラクターのインスペクター をスクショでいいので載せて下さい。
guest

回答1

0

ベストアンサー

余程速いんですか?

確認要項

自身と相手にどちらかにColliderが設定されていないか、どちらかがTriggerでない : 対処法1
キャラの動作がコライダーのカバーする範囲を大幅に超えている : 対処法2

対処法

1.どちらにもColliderを設定し、Triggerにはしない
2.キャラクターに対応するメッシュコライダーを設定する▷参考
その他.キャラクタのRigidBody>InterpolateをInterpolateにする

投稿2019/11/03 11:50

KanazawaKureha

総合スコア368

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

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

退会済みユーザー

退会済みユーザー

2019/11/04 01:11

たぶんそうみたいなのでキャラクターコントロールに戻しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問