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

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

新規登録して質問してみよう
ただいま回答率
85.31%
Unity3D

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

Unity

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

Q&A

解決済

1回答

782閲覧

・UnityのMeshから得たvertices(ポリゴンの頂点情報)にGameObjectの回転を適用させたい

Otsj-2325

総合スコア1

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2023/07/27 02:37

実現したいこと

・UnityのMeshから得たvertices(ポリゴンの頂点情報)にGameObjectの回転を適用させたい

前提

Cubeの頂点からRayを打ち続けるようにしたいです。
Meshから得た頂点はGameObjectを回転(スケーリングも)させてもその頂点座標が変化しないので、GameObjectの回転情報は適用されていないことがわかります。

回転行列でどうにか計算するのかな...とか思い、調べながらやってはいたのですが、イマイチ理解に及んでおらず初心者なもので自力で解決が出来ていません。
どなたかご教授いただければと思います。

該当のソースコード

Unity_C#Script

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class SCR_VerticesRaycast : MonoBehaviour 6{ 7 MeshFilter m_mFilter; 8 Mesh m_mesh; 9 10 // Start is called before the first frame update 11 void Start() 12 { 13 m_mFilter = GetComponent<MeshFilter>();//MeshFilterを取得しておいて 14 m_mesh = m_mFilter.sharedMesh;//Meshを取得して 15 16 } 17 18 // Update is called once per frame 19 void Update() 20 { 21 var vertices = m_mesh.vertices;//取得したMeshの頂点情報を取ってきて 22 List<Vector3> calcPoint = new List<Vector3>();//transformを適用させた頂点座標のリスト 23 24 foreach (var point in vertices) 25 { 26 var p = point; 27 28 /*ここで、 vertices に transform.rotation を適用させたい*/ 29 var rot = transform.rotation; 30 p = Quaternion.Euler(rot.x, rot.y, rot.z) * p; 31 32 //transform.Scaleの適用 33 p.x *= transform.localScale.x; 34 p.y *= transform.localScale.y; 35 p.z *= transform.localScale.z; 36 37 //transform.positionの適用 38 p += transform.position; 39 40 calcPoint.Add(p); 41 } 42 43 int i = 0; 44 foreach (var point in calcPoint) { 45 Debug.Log( i++ + " : " + point); 46 47 Debug.DrawRay(point, transform.forward, Color.blue); 48 } 49 } 50}

試したこと

参照サイトの「X:0度、Y:30度、Z:0度の移動ポジションを求める」より、クオータニオンを使って回転後の座標を取得するアルゴリズムを自分なりに試した(ソースコード 29,30行目)のですが、うまくできませんでした。
クオータニオンの扱いが悪いのか、そもそも頓珍漢なことをしているのか...

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

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

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

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

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

guest

回答1

0

自己解決

頂点に回転を適用させるには、Vector3 * Quaternion でOK!

問題だったソースコード部分は、
「任意の点座標」*「回転角度のクオータニオン」で解決しました。
いい勉強になった!覚えておこう!!
最後にChatGPTが生成したサンプルコードと私の解決後ののソースコードを置いておきます。

自己解決の理由

ふと思ってChatGPT-4に聞いてみました。即答・即解決でした。

質問した後で、ふと思ってChatGPT-4に聞いてみました。
即答でサンプルコードを出してくれて、速攻で解決しました。

ChatGPT-4にした質問と、生成したサンプルコード

質問

UnityでMeshの頂点情報にそのオブジェクトの回転を適用させた値が欲しいです。どういうソースコードを書いたらいいですか?

生成されたサンプルコード

UnityC#

1using UnityEngine; 2 3public class ApplyRotationToMesh : MonoBehaviour 4{ 5 // 変更したいMeshFilterコンポーネントを持つGameObjectを指定します 6 public GameObject targetObject; 7 8 // 回転を適用するMeshFilterコンポーネント 9 private MeshFilter meshFilter; 10 11 // 初期状態の頂点情報を保存する配列 12 private Vector3[] originalVertices; 13 14 void Start() 15 { 16 // ターゲットオブジェクトからMeshFilterコンポーネントを取得 17 meshFilter = targetObject.GetComponent<MeshFilter>(); 18 19 // MeshFilterが存在し、メッシュがアサインされていることを確認 20 if (meshFilter == null || meshFilter.sharedMesh == null) 21 { 22 Debug.LogError("Target object doesn't have a valid MeshFilter or Mesh."); 23 return; 24 } 25 26 // 初期状態の頂点情報を保存 27 originalVertices = meshFilter.sharedMesh.vertices.Clone() as Vector3[]; 28 } 29 30 void Update() 31 { 32 // ターゲットオブジェクトの回転を取得 33 Quaternion rotation = targetObject.transform.rotation; 34 35 // 初期状態の頂点情報を複製 36 Vector3[] rotatedVertices = originalVertices.Clone() as Vector3[]; 37 38 // 頂点情報に回転を適用 39 for (int i = 0; i < rotatedVertices.Length; i++) 40 { 41 rotatedVertices[i] = rotation * rotatedVertices[i]; 42 } 43 44 // 回転後の頂点情報をメッシュに適用 45 Mesh mesh = meshFilter.mesh; 46 mesh.vertices = rotatedVertices; 47 mesh.RecalculateNormals(); // 頂点法線を再計算して滑らかな表面を維持 48 49 // オブジェクトのスケールが変更された場合、頂点情報もスケーリングを考慮する必要がある場合があります。 50 // この例ではスケーリングを無視していますが、スケーリングを考慮する場合は追加の計算が必要です。 51 } 52}

解決後のソースコード

UnityC#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class SCR_VerticesRaycast : MonoBehaviour 6{ 7 MeshFilter m_mFilter; 8 Mesh m_mesh; 9 10 // Start is called before the first frame update 11 void Start() 12 { 13 m_mFilter = GetComponent<MeshFilter>();//MeshFilterを取得しておいて 14 m_mesh = m_mFilter.sharedMesh;//Meshを取得して 15 16 } 17 18 // Update is called once per frame 19 void Update() 20 { 21 var vertices = m_mesh.vertices.Clone() as Vector3[];//取得したMeshの頂点情報を取ってきて 22 List<Vector3> calcPoint = new List<Vector3>(); 23 24 var rot = transform.rotation; 25 26 foreach (var point in vertices) 27 { 28 var p = point; 29 30 /*ここで、 vertices に transform.rotation を適用させたい*/ 31 /*ときは、頂点座標にtransform.rotationを掛けるだけ*/ 32 p = rot * p; 33 34 //transform.Scaleの適用 35 p.x *= transform.localScale.x; 36 p.y *= transform.localScale.y; 37 p.z *= transform.localScale.z; 38 39 //transform.positionの適用 40 p += transform.position; 41 42 calcPoint.Add(p); 43 } 44 45 int i = 0; 46 foreach (var point in calcPoint) { 47 Debug.Log( i++ + " : " + point); 48 49 Debug.DrawRay(point, transform.forward, Color.blue); 50 } 51 } 52}

投稿2023/07/27 02:59

Otsj-2325

総合スコア1

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問