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

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

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

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

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

ドラッグ&ドロップ

コンピューターのGUIにおいて、バーチャルなものを「つかむ」ことによって選択し、別の場所や他のバーチャルなものの上に動かす行為、またはその行為に対応していることを指す。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

2888閲覧

Unity 3Dゲーム オブジェクトをz軸方向にドラッグ&ドロップしたい

wamikan

総合スコア1

C#

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

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

ドラッグ&ドロップ

コンピューターのGUIにおいて、バーチャルなものを「つかむ」ことによって選択し、別の場所や他のバーチャルなものの上に動かす行為、またはその行為に対応していることを指す。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2021/04/05 03:30

Unity 3Dゲーム

オブジェクトをマウスでz軸方向にドラッグ&ドロップしたい

unity,C#共に初心者です。現在このような3Dゲームを作っています。
イメージ説明
卵のオブジェクトをマウスでz軸方向にドラッグ&ドロップできるようにしたいです。
具体的には、卵を持った状態でカーソルを下に移動するとオブジェクトが手前に移動し、ドラッグをやめるとオブジェクトが消えるようにしたいです。

http://believeinyourself.hateblo.jp/entry/2014/05/11/074756
こちらのページを参考に以下のようなコードを書きましたが、xy方向にしか動きません。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class sc : MonoBehaviour 6{ private Vector3 screenPoint; 7 private Vector3 offset; 8 9 void OnMouseDown() 10 { 11 //カメラから見たオブジェクトの現在位置を画面位置座標に変換 12 screenPoint = Camera.main.WorldToScreenPoint(transform.position); 13 14 //取得したscreenPointの値を変数に格納 15 float x = Input.mousePosition.x; 16 float y = Input.mousePosition.y; 17 18 //オブジェクトの座標からマウス位置(つまりクリックした位置)を引いている。 19 //これでオブジェクトの位置とマウスクリックの位置の差が取得できる。 20 //ドラッグで移動したときのずれを補正するための計算だと考えれば分かりやすい 21 offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(x, y, screenPoint.z)); 22 } 23 24 void OnMouseDrag() 25 { 26 //ドラッグ時のマウス位置を変数に格納 27 float x = Input.mousePosition.x; 28 float y = Input.mousePosition.y; 29 30 Debug.Log(x.ToString() + " - " + y.ToString()); 31 32 //ドラッグ時のマウス位置をシーン上の3D空間の座標に変換する 33 Vector3 currentScreenPoint = new Vector3(x, y, screenPoint.z); 34 35 //上記にクリックした場所の差を足すことによって、オブジェクトを移動する座標位置を求める 36 Vector3 currentPosition = Camera.main.ScreenToWorldPoint(currentScreenPoint) + offset; 37 38 //オブジェクトの位置を変更する 39 transform.position = currentPosition; 40 } 41 42 // Start is called before the first frame update 43 void Start() 44 { 45 46 } 47 48 // Update is called once per frame 49 void Update() 50 { 51 52 } 53} 54

試したこと

決まったルートしか通れないようにしたり、球体状の軌道を通るようにしたりしてみましたが、上手くいきませんでした。いい方法を知っている方がいらっしゃったら教えていただきたいです。よろしくお願いします。

補足情報(FW/ツールのバージョンなど)

unity バージョン2020.3.1f1 Personal

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

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

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

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

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

guest

回答1

0

ベストアンサー

結構難しい内容で初心者さんという事なのでそのままコードを送ります。
是非参考にしてみてください。

コードの使い方

1. メインのCameraにPhysics Raycasterをアタッチ

イメージ説明

2. Hierarchy上にEvent Systemを生成

すでにある場合は生成する必要はありません。
イメージ説明

3. 卵にColliderとDraggableObj.csスクリプトをアタッチ

  • 参考画像ではBox ColliderですがColliderであれば何でも良いです。すでに設定済みであればそのまま使ってください。
  • 既に卵に貼り付けてあるスクリプトがある場合は一旦削除するか、チェックボックスをオフにしてください。

イメージ説明

DraggableObj.cs

[簡単な仕組みの説明]

  • 見えない地面をY座標8の位置に生成 位置を変えたければOffsetYを変更してください。
  • 画面のタップ位置から見えない地面に当たるまで一直線に光線を飛ばして当たった位置を取得
  • 取得した位置を卵のTransform.positionに代入 (滑らかに動くようにVector3.Lerpを使っています)

[使用したもの]
UnityEngine.EventSystemsを使っています。
メリットはUIなどとの前後関係を考えてくれるのでUI表示中は卵をドラッグできないようになり便利です。
デメリットは特に無いので是非使って欲しいです。

C#

1 2using UnityEngine; 3using UnityEngine.EventSystems; 4 5public sealed class DraggableObj : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler 6{ 7 /// <summary> 8 /// 地面からどの程度浮かばせるか? 9 /// </summary> 10 const float OffsetY = 8; 11 /// <summary> 12 /// ドラッグの速度 13 /// </summary> 14 const float DragSpeed = 10f; 15 16 Plane plane = new Plane(Vector3.up, new Vector3(0, OffsetY, 0)); 17 Rigidbody rigid; 18 bool isKinematic; 19 Camera cam; 20 Transform tr; 21 22 void Awake() 23 { 24 // 頻繁に呼ばれるものは変数にキャッシュすると高速に動作します 25 rigid = GetComponent<Rigidbody>(); 26 cam = Camera.main; 27 tr = transform; 28 } 29 30 /// <summary> 31 /// ドラッグの開始 32 /// </summary> 33 /// <param name="eventData"></param> 34 public void OnBeginDrag(PointerEventData eventData) 35 { 36 // ドラッグ中は物理演算が働かないようにする 37 if (rigid != null) 38 { 39 isKinematic = rigid.isKinematic; 40 rigid.isKinematic = true; 41 } 42 } 43 44 /// <summary> 45 /// ドラッグ中 46 /// </summary> 47 /// <param name="eventData"></param> 48 public void OnDrag(PointerEventData eventData) 49 { 50 var ray = cam.ScreenPointToRay(eventData.position); 51 Vector3 pos = default; 52 if (plane.Raycast(ray, out float hit)) 53 { 54 pos = ray.GetPoint(hit); 55 } 56 else if( hit < -1.0f ) 57 { 58 pos = ray.GetPoint(-hit); 59 } 60 61 if (pos != default) 62 { 63 tr.position = Vector3.Lerp(tr.position, pos, DragSpeed * Time.deltaTime); 64 } 65 } 66 67 /// <summary> 68 /// ドラッグの終了 69 /// </summary> 70 /// <param name="eventData"></param> 71 public void OnEndDrag(PointerEventData eventData) 72 { 73 // ドラッグ後は物理演算を元に戻す 74 if (rigid != null) 75 { 76 rigid.isKinematic = isKinematic; 77 } 78 } 79}

投稿2021/04/05 12:33

編集2021/04/05 12:39
IShix

総合スコア1724

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

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

wamikan

2021/04/09 00:20 編集

IShixさん、ありがとうございます。大変参考になりました。気になったことがあったので、質問させていただきたいです。こちらの方法は、Rigidbodyがついているオブジェクトでないと正しく動かないのでしょうか。それと、手前にドラッグした時下に沈んでしまうのですが、何か間違ったことをしているのでしょうか。 何度も質問すみません。ご回答いただけたら嬉しいです。
IShix

2021/04/10 10:33

> Rigidbodyがついているオブジェクトでないと正しく動かないのでしょうか 無くても回答の1〜3が正しく設定されていれば必ず動きます。 > 手前にドラッグした時下に沈んでしまう const float OffsetY = 8; <- この数値をめり込まなくなるまで上げてください。 例) const float OffsetY = 15; 具体的には、見えない床をワールドに対して水平に生成していて、その見えない床の上を卵が移動する仕組みです。なのでOffsetYの値が小さすぎれば床に置いてあるオブジェクトにめり込み、OffsetYの値が大きすぎるとドラッグ中のオブジェクトが見えなくなります。 いい塩梅になるようにめり込まない位置までOffsetYの値を上げてください。
wamikan

2021/04/11 16:00

丁寧に回答していただきありがとうございます。 OffsetYの値を変えたところ、うまく動くようになりました。 大変お世話になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問