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

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

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

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

Unity3D

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

Unity

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

Q&A

解決済

1回答

1585閲覧

Unity タッチ入力でオブジェクトの頂点を変形・移動する

Linkins

総合スコア82

C#

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

Unity3D

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

Unity

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

1グッド

1クリップ

投稿2018/11/11 03:15

3Dオブジェクトについて、頂点を画面上でタッチ&ドラッグした時に、その頂点がドラッグに追従して移動し、メッシュが変形する処理を作りたいです。
下記のコードを書いてみたのですが、mesh.verticesに入力した頂点座標と、実際の移動後の頂点座標が一致しません。
コードのどこでミスをしてしまっているのでしょうか?

イメージ説明

public class NewBehaviourScript : MonoBehaviour { public MeshFilter MF;//変形対象である3DオブジェのMeshFilter private Vector3[] AllVertices;//MFのmesh.verticesと対応させる配列 public GameObject p;//目印としてマウスに追従するSphereオブジェクト private VerticesSet nearestVS;//タッチした点に最も近い頂点の情報を入れます public class VerticesSet//ある頂点の「座標」と「その頂点を成すvetice達の、AllVerticesにおけるインデックス番号」を保持するクラス { public Vector3 vec;//その頂点の座標 public List<int> nums;//AllVertices[nums]がvecと同値になる } private List<VerticesSet> VSList;//全頂点分のVerticesSetを保持 // Use this for initialization void Start () { AllVertices = MF.mesh.vertices; VSList = new List<VerticesSet>(); VSListSet(); } // Update is called once per frame void Update () { if (Input.GetMouseButtonDown(0)) { nearestVS= SelectNearestVertice(); } if (Input.GetMouseButton(0)) { Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit = new RaycastHit(); if (Physics.Raycast(mouseRay,out hit)) { Vector3 hitPoint = hit.point;//バックの黒い壁とmouseRayの交点座標 nearestVS.vec = hitPoint; for (int x = 0; x < nearestVS.nums.Count; x++) { AllVertices[nearestVS.nums[x]] = hitPoint; } MF.mesh.vertices = AllVertices; p.transform.position=hitPoint; Debug.Log(hitPoint); Debug.Log(nearestVS.vec); Debug.Log(AllVertices[nearestVS.nums[0]]); } } } private void VSListSet()//全頂点分のVerticesSetを作り、VSListに格納。ここは問題なさそうです。 { List<int> counter = new List<int>(); for(int x = 0; x < AllVertices.Length; x++) { counter.Add(x); } for(int x = 0; 0 < counter.Count; x = counter[0]) { List<int> c = new List<int>(); var vs = new VerticesSet { vec=AllVertices[x],nums=new List<int>() }; for (int y = 0; y < counter.Count; y++) { if (AllVertices[x] == AllVertices[counter[y]]) { c.Add(counter[y]); vs.nums.Add(counter[y]); } } for (int z = 0; z < c.Count; z++) { counter.Remove(c[z]); } VSList.Add(vs); if (counter.Count == 0) { break; } } } private VerticesSet SelectNearestVertice()//タッチした座標と最も近い頂点についてのVerticesSetを出力。ここも問題なさそうです。 { Vector2 MousePos = new Vector2(Input.mousePosition.x, Input.mousePosition.y); Vector3 VecToWP = Camera.main.WorldToScreenPoint(VSList[0].vec); Vector2 v = new Vector2(VecToWP.x, VecToWP.y); float distance=(MousePos-v).sqrMagnitude; int whichVS = 0; for(int x =0; x < VSList.Count; x++) { Vector3 v3 = Camera.main.WorldToScreenPoint(VSList[x].vec); Vector2 v2 = new Vector2(v3.x, v3.y); var d = (MousePos-v2).sqrMagnitude; if (distance >= d) { distance = d; whichVS = x; } } return VSList[whichVS]; } }
salaam👍を押しています

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

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

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

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

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

Bongo

2018/11/11 04:10

確認したいのですが、変形しようとしている八面体のオブジェクトのTransformは移動・変形してはいないでしょうか?オブジェクト自身のTransformだけでなく、もしそのオブジェクトが別のオブジェクトの子になっている場合は、すべての親のTransformが位置(0, 0, 0)、回転(0, 0, 0)、スケール(1, 1, 1)になっているでしょうか。
Linkins

2018/11/11 07:15

お察しの通り、90°回転してしまっていました。大きなヒントになりました、ありがとうございます!
guest

回答1

0

ベストアンサー

おそらく、座標系が違うことによる問題かと。
Meshオブジェクトが保持している頂点配列はローカル座標系の頂点位置になります。
一方、Raycastで得られた点はワールド座標系での点になります。

なので、得られたワールド座標系の位置を対象のメッシュを保持しているGameObjectのローカル座標系に変換してから設定する必要があると思います。

TransformクラスにはworldToLocalMatrixという、ワールド座標系の位置をローカル座標系に変換する行列を持っているので、これを適用することで変換することができます。

cs

1Vector3 localPos = MF.transform.worldToLocalMatrix.MultiplyPoint(hitPoint);

投稿2018/11/11 04:06

edo_m18

総合スコア2283

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

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

Linkins

2018/11/11 07:12

回答ありがとうございます。 これローカル座標だったんですね、スケール1倍で位置(0,0,0)にしていたので気付きませんでした。 Blender産のモデルで、デフォルトから90°回転していたのが異変の原因だったようです。 ご指摘頂いた通り、ワールド座標に変換してから処理することで思い通りの実装ができました。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問