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

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

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

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

Q&A

解決済

2回答

3950閲覧

Unity3D 斜面の上り下りを正確に実装するにはどうすればいいのか?

退会済みユーザー

退会済みユーザー

総合スコア0

Unity3D

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

0グッド

0クリップ

投稿2020/02/10 07:37

編集2020/02/15 07:35

坂道を上がり下がりする時のY軸の移動量をする処理がSlope_Mng()関数のコードです。提示画像の線がRayです。

質問1、困っていること、提示画像のようにRayを2方向に飛ばし緑のRayは下がる時に斜面に当たりY軸の移動量を計算しているのですが提示画像2、3、番目のように動いているときと止まっているときで微妙に浮いてしまってキーを離したときにY軸が下がってしまったり、斜面を下がり続けるとだんだん空中に浮いてしまい斜面を下り終えると空中にその分浮いてしまいます。これはどうすればいいのでしょうか?

質問2、またRayの場所や長さはこれいいのか?そもそも実装法が正しいのかどうかなど知りたいです。
質問3、プロだったらどう実装するのか知りたい

参考サイト: https://gametukurikata.com/program/rigidbodyandcollider

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

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Controller : MonoBehaviour { private float input_h; private float input_v; private Vector3 move; private Rigidbody rb; private float walk_speed;//移動速度 private Animator ani;//移動速度 private Vector3 gravity; private bool isJump = false;//ジャンプしてるかどうかを管理する private Vector3 v; private bool isDush; GameObject Ground; /*坂道計算*/ GameObject Slope; [SerializeField] float slope_range; [SerializeField] Vector3 slope_direc = new Vector3(0, 0, 0); [SerializeField] Vector3 slope_direc_b = new Vector3(0, 0, 0); // [SerializeField] Vector3 slope_pos; // Use this for initialization void Start() { Ground = GameObject.Find("GroundCheck"); Slope = GameObject.Find("SlopeCheck"); Slope.transform.position = slope_pos + Slope.transform.position; walk_speed = 100; gravity = Vector3.zero; rb = GetComponent<Rigidbody>(); ani = GetComponent<Animator>(); } void Gravity_Mng()//ジャンプ管理 { } void Slope_Mng()//坂道 { RaycastHit hit; //Vector3 forward = Slope.transform.forward + slope_range; Vector3 forward = (Slope.transform.forward + slope_direc) * slope_range; Vector3 forward_b = (Slope.transform.forward + slope_direc_b) * slope_range; Debug.DrawLine(Slope.transform.position, Slope.transform.position + forward, Color.blue); Debug.DrawLine(Slope.transform.position, Slope.transform.position + forward_b ,Color.green); // float speed = Mathf.Sqrt((move.x * move.x) + (move.z * move.z)); // float speed = Mathf.Abs(Mathf.Sqrt((move.x * move.x) + (move.z * move.z))); float speed = 100; Debug.Log("speed: " + speed); if(move != Vector3.zero){ if(Physics.Linecast(Slope.transform.position, Slope.transform.position + forward, out hit,LayerMask.GetMask("Slope")) == true) { v = new Vector3(0f, (Quaternion.FromToRotation(Vector3.up, hit.normal) * transform.forward * speed).y, 0f) + transform.forward * speed; //Debug.Log("v.y: "+ v.y); Debug.Log("坂道のRayヒット! 上がる" + v.y); }else if(Physics.Linecast(Slope.transform.position, Slope.transform.position + forward_b, out hit, LayerMask.GetMask("Slope")) == true) { v = new Vector3(0f, (Quaternion.FromToRotation(Vector3.up, hit.normal) * transform.forward * speed).y, 0f) + transform.forward * speed; //Debug.Log("v.y: "+ v.y); Debug.Log("坂道のRayヒット! 下がる" + v.y); }else{ v.y = 0; } } else{ v.y = 0; } } void Move_Mng() { input_h = Input.GetAxis("Horizontal"); input_v = Input.GetAxis("Vertical"); Vector3 move_z = new Vector3(); Vector3 move_x = new Vector3(); move_z = Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized * input_v; move_x = Camera.main.transform.right * input_h; move = move_x + move_z; if (move != Vector3.zero) { move.y = 0; transform.rotation = Quaternion.LookRotation(move.normalized); } } // Update is called once per frame void Update() { Gravity_Mng(); Slope_Mng(); Move_Mng(); // Debug.Log("velocity: " + Mathf.Sqrt((rb.velocity.x * rb.velocity.x) + (rb.velocity.z * rb.velocity.z))); Debug.Log("velocity: " + rb.velocity); move *= 100; } ////////////////////////////////////////////////////////////////////////////////////////////// void FixedUpdate() { // rb.AddForce(move.x, v.y, move.z); rb.AddForce(move.x, v.y, move.z); } ////////////////////////////////////////////////////////////////////////////////////////////// }

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

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

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

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

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

guest

回答2

0

ベストアンサー

キャラクターコントローラーを使い常に下に力を入れ続けると上手くできましたので自己解決とさせていただきます。
イメージ説明

投稿2020/02/18 09:15

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

質問 3Dアクションゲームで坂道を上り下りするときに移動速度を一定にするため"平地と等速"にするためにはどうすればいいのでしょうか?

斜面の角度に応じて、速度を調整すれば良いと思います。

質問2、そもそも上る処理のコードは正しいのでしょうか?0.4くらの値がv.yに入っているみたいですが....

質問3,そもそもこのコードの書き方は正しいのか?(Updateに書いてしまっていうのは実験コードだからです。)

プログラムに正解はないので、意図通りに動いているのであれば、それで問題ないのではないでしょうか。

参考:キャラ操作をCharacterControllerからRigidbody+コライダに変更する
https://gametukurikata.com/program/rigidbodyandcollider

また、機能要件によっては「Character Controller」を使った方が簡単かもしれません。

Unity ユーザーマニュアル > Character Controller
https://docs.unity3d.com/ja/2018.4/Manual/class-CharacterController.html

参考:Unityでアニメーションの動きでキャラクターを動かす
https://gametukurikata.com/basic/animationmove

提示コードなのですがこれはプレイヤーの足元に子の空のオブジェクトを設定して坂道を上る時にRayを発射してそこに当たったらY軸の増加量を計算するという処理なのですが"上る処理"は完成しましたが "下る処理"の実装方法がわかりません

「重力」が設定されていないのではないでしょうか?
Rigidbody を使っているのであれば、useGravity で重力の影響を受けるかどうかを設定できます。

投稿2020/02/11 02:32

nskydiving

総合スコア6500

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

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

退会済みユーザー

退会済みユーザー

2020/02/11 03:51

質問ですが 参考サイト:https://gametukurikata.com/program/rigidbodyandcollider の通り坂道を上に上がる方法は実装できましたが下に下がる時の処理を実装したいのですがuse gravityを使うとなぜか攻撃するときに上に上昇してしまいまたゲームを実行すると上に上がってから下がるというバグが起きてしまうのでAddForceでy軸を下げているのですがこの場合だと下に下がるときにガクガクさがってしまい自分が実現したい動作ではありません。ですので”上に上がっているときと下がっているとき”を認識する判定を作ってそれによりY軸を上がる下がるしたいですのがどうすればいいのでしょうか?
nskydiving

2020/02/11 05:37

>なぜか攻撃するときに上に上昇してしまいまたゲームを実行すると上に上がってから下がるというバグが起きてしまう そのバグの原因を突き止めて修正した方が早い気がします。 >”上に上がっているときと下がっているとき”を認識する判定を作って これは地面方向にレイを飛ばして、キャラクターが地面に接地しているかどうかを判定できれば可能だと思います。
退会済みユーザー

退会済みユーザー

2020/02/11 05:54

>”上に上がっているときと下がっているとき”を認識する判定は地面判定用のRayを使って前のフレームに居る時と今のフレームの時とhit.point.yの値を使ってyの値を見て少ない時は下がっているとき上がっている時は登っているときで判定しているます。下がっているときは算出した上る時のy軸の移動量をマイナスすることによって下がる量が計算されるはずなのですが動きません、 質問ですが、rb.velocity();を使っているのですがこれが悪いのでしょうか? velocityは速度を直接触っているという仕組みはしっているのですがそれ以上の仕組みは知りません一応リファレンスを見ましたがそれ以上のことは書かれていないのでわかりませんでした。
nskydiving

2020/02/11 15:01

Rigidbody.velocity ですが、スクリプトリファレンスにはちゃんと「ほとんどの場合、非現実的な挙動になるため速度を直接修正するべきではありません。」と書かれていますね。 スクリプトリファレンス > Rigidbody.velocity https://docs.unity3d.com/ja/2018.2/ScriptReference/Rigidbody-velocity.html 回答欄に書いた参考URLを参照して、どのように実装しているのか見てみてください。
退会済みユーザー

退会済みユーザー

2020/02/14 10:52

質問ですが、参考サイトを見ながら上に登る時の処理は実装できましたが下がる時に空中に浮いてしまいます。これはどうすればいいのでしょうか?また質問を修正しましてAddForceを使うように修正ました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問