表題の通りではありますが、オブジェクト(白立方体)をドラッグ&ドロップした時に、壁(青立方体)を通り抜けしないようにしたいです。
現在のコードでは、カーソル操作と違い、マウスポジションにオブジェクトが瞬間移動するので、通り抜けしてしまう原因自体は理解しているのですが、ここから改善策が思い浮かばずに行き詰っています。
なので、なにか別のやり方やアルゴリズム、もしくはアセットなど、表題の目的を解決できる方法を教えていただきたいです。
目的
・オブジェクト(白立方体)をドラッグ&ドロップした時に、壁(青立方体)を通り抜けしないようにしたい
・最終的には、この壁(青立方体)で四方を囲ったり、通路を作りたい。
困ってる事
・オブジェクト(白立方体)をドラッグ&ドロップした時に、壁(青立方体)を通り抜ける(埋まる)。
気になってる事
・通り抜けする時に抵抗感が若干あるので、この反発力?を増やせば実現できる?(但しそれが何のパラメータなのかは不明)
・下記ソースコードによるマウスによるドラッグ&ドロップでは、現在位置に瞬間移動しているので、このやり方がそもそもダメなのでは?
・壁(青立方体)にスクリプトを適用し、オブジェクト(白立方体)のMathf.Clampを反転してやればできるかもしれないが、範囲の反転方法が分からない。
実施した事
・類似の質問で、「使うとしたらrigidbody.velocity~」とあったので、試しに"壁に触れたらrigidbody.velocityを0にする"としたが、その後に移動できなくなる。
→なんらかのアルゴリズムで実現できそうだけど、アルゴリズムの案が浮かばない。
・Collision Detection」の項目を「Continuous」に設定
→マウスによる移動が指定座標への瞬間移動なので意味がないと理解。
その他
・床(濃紺)の移動範囲の制限はMathf.Clampで実現できた。
・カーソル操作の場合は意図通り、通り抜けできない事は別ソースで確認できた。
環境
・Unity 2021.1.12f1
・Visual Studio 2019
類似質問:https://teratail.com/questions/139884
参考サイト:https://www.ame-name.com/archives/4631
C#
1 2 /// <summary> 3 /// 3D空間上で位置判定を行う為の不可視の3Dステージ 4 /// </summary> 5 Plane Plane; 6 7 /// <summary> 8 /// 現在オブジェクトを掴んでいるかを判定するフラグ 9 /// </summary> 10 private bool isGrabbing; 11 12 /// <summary> 13 /// プレイヤーオブジェクト(位置変更用) 14 /// </summary> 15 /// <remarks>transformでは位置書き換えはできないので用意</remarks> 16 private Transform PlayerObject; 17 18 /// <summary> 19 /// 移動範囲となる床 20 /// </summary> 21 private GameObject WorldPlane; 22 23 // Start is called before the first frame update 24 void Start() 25 { 26 //原点よりY軸1メートル上にPlaneを作成(配置済みのプレーンより上の位置に配置) 27 Plane = new Plane(Vector3.up, Vector3.up); 28 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 // レイを発射 42 if (Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity)) 43 { 44 // タグで見分ける 45 if (hit.collider.tag == "Player") 46 { 47 //マウスドラッグ状態とする 48 isGrabbing = true; 49 50 // 掴んでいるtransformオブジェクトを保存 51 PlayerObject = hit.transform; 52 53 } 54 } 55 } 56 57 if (isGrabbing) 58 { 59 // カーソルからカメラ奥方向へのレイ(不可視の点光線)を定義 60 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 61 62 // Planeにレイを貫通させる 63 Plane.Raycast(ray, out float rayDistance); 64 65 // レイが当たった交点位置をプレイヤーオブジェクトの位置にする 66 PlayerObject.position = ray.GetPoint(rayDistance); 67 68 //左クリックボタンが離れた 69 if (Input.GetMouseButtonUp(0)) 70 { 71 isGrabbing = false; 72 } 73 } 74 75 //床の範囲を取得 76 float areaX = WorldPlane.GetComponent<Renderer>().bounds.size.x; 77 float areaZ = WorldPlane.GetComponent<Renderer>().bounds.size.z; 78 79 //プレイヤーの移動範囲を床面だけに制限 80 transform.position = new Vector3( 81 Mathf.Clamp(transform.position.x, -(areaX / 2), areaX / 2 ), 82 Mathf.Clamp(transform.position.y, 1, 1), 83 Mathf.Clamp(transform.position.z, -(areaZ / 2), areaZ / 2) 84 ); 85 86 87 }
追記_2021/07/11_22:43
Bongoさんのコードを実装してみた結果です。
白立方体のRigitbody>抗力を45にしたところ、マウスの早い動きでも貫通しなくなって想定した動きにかなり近いものになりました。
(抗力が低いと反対方向に跳ねすぎて飛んでいった)
しかし、以下Gifを見てもらうと分かるかと思いますが、ビョンビョンビョンとかなり高速にバウンドしてしまいます。
できればもう少し跳ねないのが理想ですが、悩ましい所。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/07/11 13:49 編集
2021/07/11 13:49
2021/07/11 14:03