表題の通りではありますが、オブジェクト(以降A)をドラッグ&ドロップした時に、階段またはスロープ(斜面)を上るようにしたいです。
現在、以前の質問でRigidbody.velocityで壁の通り抜けをしないようにしたのですが、この状態で階段またはスロープのオブジェクト(以降B)にAがさしかかると、ゆっくり高さ(y位置)がBの高さまで上がりはするものの、Bの高さを越えきれずに中に埋もれてしまいます。
その後、ドラッグを止めると弾かれる様にニュイッと上に移動します。
また、そこから段差を降りると非常にゆっくりと降下(毎秒0.015ぐらいの速度)して元の床面に着地します。
高さ自体はMathf.Clanpで制限しているので、その範囲内に高さが収まるのは分かるのですが、上昇下降がゆっくりになってオブジェクト面に沿って移動ができない理由が分からず、どうしていいか行き詰っています。
目的
オブジェクトをドラッグ&ドロップした時、床面に沿うように階段状のオブジェクトまたはスロープ状(傾斜)のオブジェクトを登攀したい。
困ってる事
・登攀時、上昇速度がゆっくりになってオブジェクトに埋まる。
・登攀後落下時、下降速度が非常にゆっくりになって着地までに時間がかかる
実施したこと
・参考サイトを見てPhysics.gravity(またはrigidbody.AddForce)で重力を強く変更したがスロープの抵抗感が強くなるだけで実現せず。
・他の質問を見てvelocityのyの値だけ元の値に戻してみたが実現せず。
・CharacterControllerを追加すると、クリックするだけで明後日の方向にランダムに向かう。
環境
・Unity 2021.1.12f1
・Visual Studio 2019
C#
1public class PlayerMove : MonoBehaviour 2{ 3 /// <summary> 4 /// 現在オブジェクトを掴んでいるかを判定するフラグ 5 /// </summary> 6 private bool isGrabbing; 7 8 /// <summary> 9 /// 3D空間上で位置判定を行う為の不可視の3Dステージ 10 /// </summary> 11 Plane Plane; 12 13 /// <summary> 14 /// プレイヤーオブジェクト(位置変更用) 15 /// </summary> 16 /// <remarks>transformでは位置書き換えはできないので用意</remarks> 17 private Transform PlayerObject; 18 19 /// <summary> 20 /// 移動範囲となる床 21 /// </summary> 22 private GameObject WorldPlane; 23 24 // Start is called before the first frame update 25 void Start() 26 { 27 //原点よりY軸1メートル上にPlaneを作成(配置済みのプレーンより上の位置に配置) 28 Plane = new Plane(Vector3.up, Vector3.up); 29 WorldPlane = GameObject.Find("WorldPlane"); 30 } 31 32 // Update is called once per frame 33 void Update() 34 { 35 //左クリックされたか 36 if (Input.GetMouseButtonDown(0)) 37 { 38 // カーソルからカメラ奥方向へのレイ(不可視の点光線)を定義 39 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 40 41 // レイを発射して照射先にオブジェクトが存在すればRaycastHitで出力 42 if (Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity)) 43 { 44 // タグ名で自機を判定 45 if (hit.collider.CompareTag("Player")) 46 { 47 //マウスドラッグ状態とする 48 isGrabbing = true; 49 // 掴んでいるRigidbodyオブジェクトを保存 50 PlayerObject = hit.rigidbody; 51 52 } 53 } 54 } 55 56 if (isGrabbing) 57 { 58 // カーソルからカメラ奥方向へのレイ(不可視の点光線)を定義 59 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 60 61 // Planeにレイを貫通させる 62 Plane.Raycast(ray, out float rayDistance); 63 64 // レイが当たった交点位置をプレイヤーオブジェクトの位置にする 65 PlayerObject.position = ray.GetPoint(rayDistance); 66 67 //ドラッグを解除したか(左クリックボタンが離れたか) 68 if (Input.GetMouseButtonUp(0)) 69 { 70 isGrabbing = false; 71 } 72 } 73 74 //床の範囲を取得 75 float areaX = WorldPlane.GetComponent<Renderer>().bounds.size.x; 76 float areaZ = WorldPlane.GetComponent<Renderer>().bounds.size.z; 77 78 //プレイヤーの移動範囲を床面だけに制限 79 transform.position = new Vector3( 80 Mathf.Clamp(transform.position.x, -(areaX / 2), areaX / 2 ), 81 Mathf.Clamp(transform.position.y, 0.5f, 10f), 82 Mathf.Clamp(transform.position.z, -(areaZ / 2), areaZ / 2) 83 ); 84 } 85 86 /// <summary> 87 /// 移動をFixedUpdateのタイミングで行う 88 /// </summary> 89 void FixedUpdate() 90 { 91 if (IsMouseGrabbing) 92 { 93 // カーソルからカメラ奥方向へのレイ(不可視の点光線)を定義 94 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 95 96 // プレイヤーの高さにPlaneを更新して、カメラの情報を元に地面判定して距離を取得 97 Plane.SetNormalAndPosition(Vector3.up, transform.localPosition); 98 99 // Planeにレイを貫通させる 100 if (Plane.Raycast(ray, out float rayDistance)) 101 { 102 // レイが当たった交点位置へ1フレームで移動するようにvelocityを設定する(他オブジェクトへの貫通移動制限) 103 PlayerObject.velocity = (ray.GetPoint(rayDistance) - PlayerObject.position) / Time.deltaTime; 104 105 // レイが当たった交点位置をプレイヤーオブジェクトの位置にする 106 //PlayerUnit.position = ray.GetPoint(rayDistance); 107 108 } 109 } 110 } 111}
回答1件
あなたの回答
tips
プレビュー