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

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

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

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

Unity3D

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

Q&A

解決済

1回答

1171閲覧

Unity マウスドラッグで平面に沿ってプレハブを引き伸ばしたい

SHO1128

総合スコア91

C#

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

Unity3D

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

0グッド

0クリップ

投稿2022/04/26 23:53

やりたいこと

Unityにて、prefab化したオブジェクトを伸縮して配置させ、かつ
次のマウスクリックで新たなオブジェクトを配置させたいです。
操作感としては以下の様にしたいと思っています。

  1. マウスクリック位置に3D平面上に沿ったprefabを生成
  2. マウスドラッグで3D平面に沿って1.のprefabを引き伸ばす
  3. マウスアップで引き伸ばした1.のprefabを配置
  4. 次のマウスクリックで新たなprefabを生成後

1.の操作に戻る

■参考図
イメージ説明

問題点

以下の二つの解説を参考にしているのですが、
マウスドラッグで始点と終点にRayを当て続ける方法と
prefab化したオブジェクトを伸縮させる方法が分からず
ずっと躓いております…。どうぞご教授お願いいたします。

###参考にしたいコード

クリックした位置にオブジェクトを生成
https://futabazemi.net/notes/unity-raycast_click/

C#

1public class ClickPoint : MonoBehaviour 2{ 3 public GameObject cube; 4 5 void Update () { 6 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 7 RaycastHit hit = new RaycastHit(); 8 if (Input.GetMouseButtonDown(0)) 9 { 10 if (Physics.Raycast(ray, out hit)) 11 { 12 Instantiate(cube, hit.point, Quaternion.identity); 13 } 14 } 15 } 16 17}

マウスの位置に向かって伸縮するオブジェクト
https://teratail.com/questions/35150

C#

1private Vector3 m_mouseDownPosition = Vector3.zero; 2 3void OnMouseDown() 4{ 5 // マウスクリックした際の初期位置を保存。 6 m_mouseDownPosition = transform.position; 7} 8 9void OnMouseDrag() 10{ 11 // マウスクリックした場所をワールド座標に変化して、 12 // 初期位置とマウスクリック位置の中間にオブジェクトを配置。 13 // オブジェクトのスケールを初期位置とマウスクリックの距離に。 14 // オブジェクトの向きをマウスクリックした位置に。 15 16 Vector3 inputPosition = new Vector3( Input.mousePosition.x, Input.mousePosition.y, 9.5f ); 17 Vector3 mousePos = Camera.main.ScreenToWorldPoint( inputPosition ); 18 Vector3 mediumPos = ( mousePos - m_mouseDownPosition ) / 2.0f; 19 float dist = Vector3.Distance( mousePos, m_mouseDownPosition ); 20 21 transform.position = mediumPos; 22 transform.localScale = new Vector3( 1.0f, 1.0f, dist ); 23 transform.LookAt( mousePos ); 24} 25 26void OnMouseUp() 27{ 28 // 位置、回転、スケールを元に戻す。 29 transform.position = m_mouseDownPosition; 30 transform.rotation = Quaternion.identity; 31 transform.localScale = Vector3.one; 32}

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

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

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

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

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

guest

回答1

0

ベストアンサー

両者を折衷させるとなりますと、たとえば下記のような形はいかがでしょうか。

C#

1using UnityEngine; 2 3public class ObjectPlacer : MonoBehaviour 4{ 5 // ここにインスペクター上でセットしておいたプレハブをシーン上に設置することにする 6 public GameObject objectPrefab; 7 8 // 現在設置作業中のインスタンスを保持するフィールドを用意しておく 9 private Transform objectInstance; 10 11 // マウスダウン時の座標を保持するフィールドも用意しておく 12 private Vector3 mouseDownPosition; 13 14 private void Update() 15 { 16 // まずマウスダウン時にプレハブをインスタンス化し、その位置を覚えておく 17 if (Input.GetMouseButtonDown(0)) 18 { 19 if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out var hit)) 20 { 21 this.objectInstance = Instantiate(this.objectPrefab, hit.point, Quaternion.identity).transform; 22 this.mouseDownPosition = hit.point; 23 } 24 } 25 else if (Input.GetMouseButton(0)) 26 { 27 if (this.objectInstance == null) 28 { 29 return; 30 } 31 32 // ドラッグ中は「マウスの位置に向かって伸縮するオブジェクトを実装したいのですが、伸縮で躓きました」の 33 // urahimonoさんの方法と同様にインスタンスを伸縮させる 34 if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out var hit)) 35 { 36 this.objectInstance.position = (hit.point + this.mouseDownPosition) * 0.5f; 37 this.objectInstance.localScale = new Vector3(1.0f, 1.0f, Vector3.Distance(hit.point, this.mouseDownPosition)); 38 this.objectInstance.LookAt(hit.point); 39 } 40 } 41 else if (Input.GetMouseButtonUp(0)) 42 { 43 // マウスアップ時にobjectInstanceをnullに戻し、次のオブジェクト設置に備える 44 this.objectInstance = null; 45 } 46 } 47}

図

投稿2022/04/27 11:06

Bongo

総合スコア10807

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

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

SHO1128

2022/04/27 11:59

Bongo様、早急なご回答ありがとうございます。まさしく自分が再現したい動作になりました。すごいです…神様です。大変感謝いたします。自分の作りたいゲームに一歩近づいた気がします。 またどうぞよろしくお願い申し上げます。
SHO1128

2022/04/28 09:39

Bongo様、お世話になっております。 この度はスクリプトを組んでいただきありがとうございました。 早速、自身の環境下に動作させたのですが… Bongo様のサンプルgif画像のような動作になりませんでした。 自身の実装例 https://gyazo.com/1104e1f5a6080a5a9067f9076a3e2aa7 実装について質問があります。 組んでいただいた「ObjectPlacer.cs」これはどのオブジェクトに対して当てるべきでしょうか…? ※ちなみに私は地面となるPlaneオブジェクトにこのスクリプトを読ませました。 初歩的な質問で申し訳ございません。 どうぞご教授お願いいたします。
Bongo

2022/04/28 10:50

私の実験ではヒエラルキー上に空のゲームオブジェクトを作ってアタッチしたのですが、地面でも問題ないだろうと思います。ご提示いただいた図のようになってしまうとなると、さしあたり気になるのはプレハブの作りでしょうかね。 urahimonoさんのやり方をまねて伸縮させてみましたが、あの方法はUnityのキューブのように原点が中心、かつスケールが1倍の時のZ方向のサイズがプラス側もマイナス側も0.5でないと破綻してしまうだろうと思います。 あいにくまだUnityをいじれる時間が取れず、のちほどになってしまうのをご容赦願いたいのですが、何か対策を考えてみたいと思います。それにあたって、ご質問者さんのプレハブの作りがどうなっているかご説明いただけませんでしょうか。あるいは、プレハブが3Dモデルであればモデルのファイルをどこかにアップロードしていただくのでもかまいません。
SHO1128

2022/04/29 11:42

Bongo様、お世話になっております。 不具合の件、解決いたしました。原因はprefab化したオブジェクトに colliderコンポーネントが付与されていたためでした。これを外すことによって Bongo様のサンプルgif画像通り、かつ私自身が望んでいた通りにスクリプトが動いて くれました…!!感謝です!! またお騒がせしました、この度はありがとうございました。。。 またどうぞよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問