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

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

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

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Unity

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

Q&A

解決済

1回答

1035閲覧

Cubeの頂点の座標を取得したい

qoooooo

総合スコア13

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Unity

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

0グッド

0クリップ

投稿2018/01/04 08:26

###前提・実現したいこと
Cubeの頂点の座標を取得したいです。
meshを利用しましたがどうしてこのように出力されるのかがわかりません。
mesh.vertices.Lengthが24の理由もわかりません。(勉強不足ですみません。)
Cubeでの位置ではなくglobalなPositionを出力させたいです。

###エクセルに出力されたもの

0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 0.5 0.5 0.5 0.5 0.5

###該当のソースコード

Javascript

1//コードの一部です 2 3for(var i=0; i<1; i++){ 4 Unit = Units[i]; 5 var mesh : Mesh = Unit.GetComponent.<MeshFilter>().mesh; 6 for(var j = 0; j < mesh.vertices.Length ; j++) { 7 Coordinatex[j] = mesh.vertices[j].x; 8 Coordinatey[j] = mesh.vertices[j].y; 9 Coordinatez[j] = mesh.vertices[j].z; 10 sw.Write(mesh.vertices[j].x+" , "+mesh.vertices[j].z+" , "+mesh.vertices[j].z+" , "); 11 sw.WriteLine(); 12 } 13 }

###補足情報(言語/FW/ツール等のバージョンなど)
CubeはPosition(0,0,0)、Scale(2,2,2)です。

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

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

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

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

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

Bongo

2018/01/04 09:47

mesh.vertices.Lengthが24の件については、Cubeの構造が「一つの面が4頂点を繋いだ2枚の三角形でできていて、それが6面分」ということで4×6=24ということかと思います。これらのグローバル座標が欲しい場合はCubeのtransformのTransformPointを使って座標変換すればいいはずです。欲しい座標についてお伺いしますが、以前のご質問を拝見するとX・Z座標にしか注目されていないようですが、これはたとえば「CubeはY軸周りにだけ回転していて、Cubeの8頂点のうち、真上から見たときの4頂点のX・Z座標だけが分かれば十分」といったことでしょうか?
qoooooo

2018/01/05 01:22

ありがとうございます。おっしゃる通りで、CubeはY軸周りにのみ回転し、真上から見たときの4頂点のxz座標が取得したいデータです。
guest

回答1

0

ベストアンサー

追記修正欄に記入しました条件を前提に、目的の4頂点の座標を調べる実験をしてみました。おそらく下記のような感じで頂点のワールド座標を得られるかと思いますが、いかがでしょうか?
Cubeの各頂点は法線の異なる3つの頂点が重複しているので、それを除外し8頂点に減らして、8頂点のうちモデル座標のYが正の4頂点だけを抜き出し(負の4頂点でも構わないと思います)、ワールド座標に変換して、X成分・Z成分だけを取り出すことにしました。
あいにくJavascriptは不慣れでして、変なコードになってしまったかもしれませんがご容赦ください。

Javascript

1#pragma strict 2 3import System.Linq; 4 5class CubeVertices extends MonoBehaviour { 6 7 var cube : GameObject; 8 9 function Start() { 10 var mesh : Mesh = cube.GetComponent.<MeshFilter>().mesh; 11 12 var vertices : Vector2[] = mesh.vertices // 全24頂点のうち... 13 .Distinct.<Vector3>() // 位置が重複するものを除外(24→8頂点に) 14 .Where.<Vector3>(function(p : Vector3) : boolean 15 { 16 return p.y > 0.0f; // Y座標が+のものだけを抽出(8→4頂点に) 17 }) 18 .Select.<Vector3, Vector2>(function(p : Vector3) : Vector2 19 { 20 var worldPosition : Vector3 = cube.transform.TransformPoint(p); // モデル座標をワールド座標に変換 21 return new Vector2(worldPosition.x, worldPosition.z); // 変換したワールド座標のうちX、ZだけをVector2として返す 22 }) 23 .ToArray.<Vector2>(); // 以上の条件で得られた結果(Vector2型のデータ群)を配列に変換する 24 25 var vertexCount : int = vertices.Length; 26 27 for (var i : int = 0; i < vertexCount; i++) 28 { 29 Debug.Log(vertices[i]); 30 } 31 } 32}

###[追記]
もうすでにご自身で複数キューブの場合に書き換え済みかもしれませんが、ご参考までに例を追記します。
コメントで申し上げた、「最初に1回だけ頂点モデル座標を求めて、以後はワールド座標変換だけ行う」方式にしてみました。

Javascript

1#pragma strict 2 3import System.Linq; 4 5class CubeVertices extends MonoBehaviour { 6 7 var Units : GameObject[]; 8 9 private static var CubeTopVertices : Vector3[]; 10 private static var CubeTopVerticesLength : int; 11 12 private var Coordinatex : float[]; 13 private var Coordinatez : float[]; 14 private var UnitsLength : int; 15 16 function Start() { 17 UnitsLength = Units.length; 18 19 if (UnitsLength == 0) { 20 return; 21 } 22 23 InitCubeTopVertices(Units[0]); // オブジェクトを代表して、Units[0]からメッシュを取得しCubeTopVertices・CubeTopVerticesLengthを求める 24 Coordinatex = new float[UnitsLength * CubeTopVerticesLength]; 25 Coordinatez = new float[UnitsLength * CubeTopVerticesLength]; 26 27 // 実験のため、各オブジェクトをランダムに移動・回転させる 28 for (var i : int = 0; i < UnitsLength; i++) { 29 var unitRigidbody = Units[i].GetComponent.<Rigidbody>(); 30 31 unitRigidbody.AddForce(Random.value * 2 - 1, 0, Random.value * 2 - 1, ForceMode.VelocityChange); 32 unitRigidbody.AddTorque(0, Random.value * 2 - 1, 0, ForceMode.VelocityChange); 33 } 34 } 35 36 function Update() { 37 // スペースキー押下で一時停止、頂点ワールド座標を調べる 38 if (Input.GetKeyDown(KeyCode.Space)) { 39 if (Time.timeScale > 0) { 40 Time.timeScale = 0; 41 UpdateCoordinates(); 42 PrintCoordinates(); 43 } else { 44 Time.timeScale = 1; 45 } 46 } 47 } 48 49 private function UpdateCoordinates() { 50 // 各オブジェクトのtransformでキューブの頂点モデル座標をワールド座標に変換し、Coordinatex・Coordinatezを更新する 51 for (var i : int = 0; i < UnitsLength; i++) { 52 var unitTransform : Transform = Units[i].transform; 53 var offset : int = i * CubeTopVerticesLength; 54 55 for (var j : int = 0; j < CubeTopVerticesLength; j++) { 56 var worldPosition : Vector3 = unitTransform.TransformPoint(CubeTopVertices[j]); 57 58 Coordinatex[offset + j] = worldPosition.x; 59 Coordinatez[offset + j] = worldPosition.z; 60 } 61 } 62 } 63 64 private function PrintCoordinates() { 65 // Coordinatex・Coordinatezの内容をコンソールに表示してみる 66 Debug.Log("Coordinates:"); 67 for (var i : int = 0; i < UnitsLength; i++) { 68 var offset : int = i * CubeTopVerticesLength; 69 70 Debug.LogFormat(Units[i], 71 "Unit {0} ({1}) ... ({2:F4}, {3:F4}), ({4:F4}, {5:F4}), ({6:F4}, {7:F4}), ({8:F4}, {9:F4})", 72 i, Units[i].name, 73 Coordinatex[offset + 0], Coordinatez[offset + 0], 74 Coordinatex[offset + 1], Coordinatez[offset + 1], 75 Coordinatex[offset + 2], Coordinatez[offset + 2], 76 Coordinatex[offset + 3], Coordinatez[offset + 3]); 77 } 78 } 79 80 private static function InitCubeTopVertices(meshSource : GameObject) { 81 // 上面の頂点抽出までをあらかじめやっておく 82 if (CubeTopVertices == null) { 83 CubeTopVertices = meshSource.GetComponent.<MeshFilter>().sharedMesh.vertices 84 .Distinct.<Vector3>() 85 .Where.<Vector3>(function(p : Vector3) : boolean { 86 return p.y > 0.0f; 87 }) 88 .ToArray.<Vector3>(); 89 CubeTopVerticesLength = CubeTopVertices.length; 90 } 91 } 92}

投稿2018/01/05 02:08

編集2018/01/05 21:50
Bongo

総合スコア10807

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

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

qoooooo

2018/01/05 02:48

ありがとうございます!できれば、Cubeが複数になったときのコードも作っていただけたら嬉しいのですが、、可能でしょうか?
Bongo

2018/01/05 03:13

すみません、これから私用で出かけるところでして、しばらくUnityをいじれないのです... 複数のキューブの場合でも同じことでして、mesh.verticesに入っているのはローカル座標での各頂点の位置ですので、たとえば全キューブについてループさせ、各ループ内で頂点座標をローカルからワールドに変換するときに「Unit.transform.TransformPoint(...」とすれば、その時のUnitに関するワールド座標が得られるかと思います。 一つ補足しますと、各キューブはメッシュ自体の形状は同一で、ワールド空間内の位置・回転・拡縮が違うだけなのではないかと想像します。ですので「mesh.vertices」で出てくる24頂点の座標はどのキューブについても毎回同じなのではないでしょうか? もし余力がありましたら、「キューブメッシュ上面4頂点のローカル座標を取り出す」ところまでをStart内などで1回だけ行うようにして、それ以降頂点のワールド座標が必要になった時は、あらかじめ取り出した4頂点について「各キューブのtransformで4頂点をワールド座標に変換し、そのxとzを調べる」だけにするよう書き換えてみるのもいいと思います。 この方が計算量が削減されて、動作が少し軽くなるかもしれません。
qoooooo

2018/01/08 02:26

追記ありがとうございます!実はもうCubeは動く前提で、10秒後の頂点(Coordinatex[],Coordinatez)を取得したいだけなのです。ファイルに出力するコードも作ってあるので、頂点取得の部分だけ入れ込みたいのですが、その場合、追記のコードで必要なのはStart,Update,UpdateCoordinatesの3つの一部で間違い無いでしょうか?
Bongo

2018/01/08 02:34

はい、PrintCoordinatesやStart内のキューブランダム移動は、動きの確認のために入れてみたものですので不要です。InitCubeTopVerticesとUpdateCoordinatesを適宜組み合わせればいいかと思います。
qoooooo

2018/01/08 02:41

ありがとうございます。頑張って組み込んでみます!
qoooooo

2018/01/09 02:38

なんども失礼します。function InitCubeTopVertをそのまま使わせていただいたのですが、'Distinct' is not a member of 'UnityEngine.Vector3[]'というエラーが出てしまいました。その他の場所にミスがあるのでしょうか?
Bongo

2018/01/09 03:24

「Distinct」や「Where」を使うには、例示しましたコードの頭の方にある「import System.Linq;」が必要なのですが、記入されていますでしょうか? もし書いてあるのにダメだとなると、ちょっとすぐには原因が思いつきません... LINQの機能を使ったのは、この方がコードがシンプルになるかと思ってのことでして、LINQに頼らなくとも自前でループを回して頂点を比較抽出することも可能なはずですので、ダメな場合はそのような形に書き換える必要があるかもしれません。
qoooooo

2018/01/09 05:13

importし忘れていましたすみません。。うまく組み込んでコードを完成することができました!何度もご親切に回答していただき、本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問