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

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

詳細はこちら
Unity3D

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

Q&A

解決済

1回答

1040閲覧

坂道を上る方法 ベクトルの内積とspeedを掛けたらy軸の上昇量がでるはず?

退会済みユーザー

退会済みユーザー

総合スコア0

Unity3D

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

0グッド

0クリップ

投稿2019/10/27 08:26

編集2019/10/27 11:51

坂道を画像のように上る方法が知りたいです。とりあえず次のスクリプトのうに組ましたがうまくできません何を間違えたのか知りたいです。
ベクトルの内積のようなものを取りそこにwalk_speedをかけるとy軸の移動量が判明すると思ったのですがこれはどう違うのでしょうか?
※コメント/////部のコードです。

やりたいこと "平地と同じ移動速度で坂道を上る処理を作りたい。"

質問ですがrayを飛ばすやり方だとその線に反応しない場合はこのコードではうまくいかないため何か別のやり方を考える方法がるのでしょうか?
イメージ説明

キャラクターにカプセルコライダー(足元)Rigidbodyも入っています。

質問2、停止中または画像から見て横に動くと下(地面に向かって)下がってしまう原因がしりたい。
提示画像その2
イメージ説明

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { const float walk_speed_max = 3.0f; Rigidbody rb; Vector3 move; float input_h; float input_v; Vector3 move_x; Vector3 move_y; public GameObject gGround; ground spt_g; bool isJump; bool isDush; bool isRay; float jump_force = 200.0f; float move_speed = walk_speed_max; Animator ani; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private Transform StepHit; private Transform Hit; private RaycastHit ray; const float ray_range = 0.3f;//レイを飛ばす距離 // 昇れる段差 private float stepOffset = 0.3f; // 昇れる角度 private float slopeLimit = 65f; // 昇れる段差の位置から飛ばすレイの距離 private float slopeDistance = 1f; private Vector3 v; // GameObject go = GameObject.Find("GameObject"); void move_step() { //y軸は逆にしてるプラスが下 Debug.DrawLine(transform.position + new Vector3(0f, stepOffset, 0f), transform.position + new Vector3(0f, stepOffset, 0f) + transform.forward * slopeDistance , Color.green); // Debug.Log(transform.forward * slopeDistance); if (spt_g.isGround == true) { if (Physics.Linecast(StepHit.position, StepHit.position + StepHit.forward * ray_range, out ray)) { Debug.Log("レイ"); if (Vector3.Angle(transform.up, ray.normal) <= slopeLimit || (Vector3.Angle(transform.up, ray.normal) > slopeLimit && !Physics.Linecast(transform.position + new Vector3(0f, stepOffset, 0f), transform.position + new Vector3(0f, stepOffset, 0f) + transform.forward * slopeDistance)) ) { v = new Vector3(0f, (Quaternion.FromToRotation(Vector3.up, ray.normal) * transform.forward * move_speed).y, 0f) + transform.forward * move_speed; isRay = true; } else { //move += transform.forward * move_speed; } } } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Start is called before the first frame update void Start() { rb = GetComponent<Rigidbody>(); spt_g = gGround.GetComponent<ground>(); ani = GetComponent<Animator>(); isJump = false; isDush = false; StepHit = transform.Find("StepRay"); } // Update is called once per frame void Update() { input_h = Input.GetAxis("Horizontal"); input_v = Input.GetAxis("Vertical"); move_y = 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_y; //move.x *= move.x * move_speed; //move.z *= move.z * move_speed; if (move != Vector3.zero) { transform.rotation = Quaternion.LookRotation(move.normalized); } /*走る*/ if(Input.GetKey(KeyCode.RightControl)) { isDush = true; move_speed = 15.0f; } else { isDush = false; move_speed = walk_speed_max; } if(Input.GetKey(KeyCode.Space)) { if(spt_g.isGround == true && isJump == false) { isJump = true; } } move_step(); Animation_Mng(); } /*アニメーション管理*/ void Animation_Mng() { float speed = Mathf.Sqrt((move.x * move.x) + (move.z * move.z)); ani.SetFloat("Move_Speed",speed); ani.SetBool("isDush",isDush); } private void FixedUpdate() { rb.velocity = new Vector3(move.x, rb.velocity.y, move.z); if(isJump == true) { rb.AddForce(rb.velocity.x,jump_force,rb.velocity.z); isJump = false; } rb.AddForce(new Vector3(0, -10.0f, 0)); } private void OnCollisionEnter(Collision c) { // Debug.Log("プレイヤーcollision"); } }

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

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

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

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

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

KanazawaKureha

2019/10/27 09:18

完成形はどういったものをイメージしており、どう「うまくいかない」のでしょうか? ベクトル成分x,zの積をとってもyの移動量は地面のx,z方向の傾きに依存するので、 y=移動量x*地面のx方向の傾き+移動量z*地面のz軸方向の傾きとする必要がありますが、
退会済みユーザー

退会済みユーザー

2019/10/27 09:24

画像のゆに坂道を上って下るときも地面にくっついて移動するとなると単に地面に押し付けるだけでは無理なので坂道の上るときに同じ速度で上るための処理を書く必要が出てきました。そこで前に進んでいるときにyの移動量を計算してればスーっと平地と同じ速度で上がる(y)のではないかと考えたのですが
KanazawaKureha

2019/10/27 09:34 編集

うまくいかない、というのはどううまくいかないのでしょうか? 具体的にお願いします。
退会済みユーザー

退会済みユーザー

2019/10/27 09:39

なぜかrotationは触っていなのになぜかキャラクタがその分?の角度に傾いてしまいます。参考サイトにもありました通りキャラクタの角度は変わらない上昇量の話なのでちょっと困惑しています。
KanazawaKureha

2019/10/27 09:52

思いもよらない内容でこちらも困惑しております(°_°) 解決に繋がるかは分かりませんが ・どの方向に移動した時に、どの軸にどのぐらい傾くのか? ・コライダーの形状は何か? を質問に追記していただけると幸いです。
退会済みユーザー

退会済みユーザー

2019/10/27 10:25

質問ですが参考サイトは正しいのでしょうか?
KanazawaKureha

2019/10/27 11:14 編集

ざっとみた限り、おかしな点はありませんでしたが、少々回りくどい且つ分かりにくい方法でコードを書いていると感じました。 コード自体を精査はしてませんがコピペではなく、理解して参考にする程度に留めた方が賢明です。
退会済みユーザー

退会済みユーザー

2019/10/27 11:34

質問ですが坂道に上っているときに横に動くとすこしずつ下がってしまうのですがこれはどうすればいいのでしょうか?
KanazawaKureha

2019/10/27 11:44

画像を見る限り軸に平行に傾いている様ですが、これをy軸方向に傾けて、異変が無いかもう一度確認してみてください。
退会済みユーザー

退会済みユーザー

2019/10/27 11:52

ちょっと内容が食い違ってるみたいですので提示画像を追加しました。画像のように坂道に上っているときにy軸が小数点以下の値がすこしずつ下にがってしまっていてz軸もすこしずつ数字が変わっていてすこしずつ 地面に向かって下がっていると見たいです。これは何をしたのでしょうか?
退会済みユーザー

退会済みユーザー

2019/10/27 11:54

今更ですが坂道を上るコードを編集しました。 float s = Mathf.Sqrt((move.x * move.x) + (move.z * move.z)); if (spt_g.isGround == true && s > 0) { if (Physics.Linecast(StepHit.position, StepHit.position + StepHit.forward * ray_range, out ray)) { if (Vector3.Angle(transform.up, ray.normal) <= slopeLimit) { v = new Vector3(0f, (Quaternion.FromToRotation(Vector3.up, ray.normal) * transform.forward * move_speed).y, 0f) + transform.forward * move_speed; isRay = true; } else { //move += transform.forward * move_speed; } } }
KanazawaKureha

2019/10/27 12:01

坂道が横に傾いているわけでは無いですよね? Scaleメソッドの戻り値が問題だと思うので、x、z共に傾きがある状態で再度検証していただきたい→坂をy軸に傾けて欲しいのです。
KanazawaKureha

2019/10/27 12:03

長くなったので、新たな質問として別の人にも回答を促した方がいいと思います。
guest

回答1

0

ベストアンサー

まずはRayに関しての回答ですが、
確かにRayで適切な処理が行えるという状況は限定的ですので、それ1つでキャラクターの移動処理を扱おうとするのは無理があります。

どの様なゲームを製作しようと考えていらっしゃるのか分かりませんが、物理演算も適切に処理に加えるべきでしょう。

Rayの当たった場所によって、移動するのか、落ちるのか、はたまた動かないのか、その様な処理が必要です。


しかし、そもそも物理演算で何故坂道が登れないかが私には謎なのです。
もし原因がわかればもっと良い解決策が見つかるかも知れませんし、この記事を行く行くみる方の参考ともなりますので、今更ではありますが、動画など様々な情報で再議論する事も或は必要かと思います。

投稿2019/10/27 10:45

編集2019/10/27 10:48
KanazawaKureha

総合スコア368

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

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

退会済みユーザー

退会済みユーザー

2019/10/27 10:56

if (spt_g.isGround == true && 移動量 > 0) 移動中で地面に居る間というif文に編集を加えました。そこで斜めになるというバグは解消されました。 坂道は登れるのですが移動量が平地と違ってすこし遅めになるのでそれを平地と同じようにするという処理が完成しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問