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

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

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

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

Unity

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

Q&A

解決済

1回答

912閲覧

unityでのメッシュの作成でエラーが出ます。

meJ15

総合スコア55

C#

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

Unity

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

0グッド

0クリップ

投稿2018/09/08 08:35

前提・実現したいこと

unityでスクリプトを使ってたくさんのメッシュがある直方体を作りたい。

このサイトのソースを参考にして6角柱から左図のような直方体を作ることができたのですが、これをさらに手書きの下図のように細かくメッシュを入れたいと考えています
イメージ説明
イメージ説明

しかし直方体の点をfor文で生成した後、それらをつなげるところでエラーがでるのですがどのように変えればうまく動きますか?

6角柱のメッシュ
:http://simplestar-tech.hatenablog.com/entry/2017/10/08/162753

発生している問題・エラーメッセージ

イメージ説明

for文のなかで作ったはずのpositionsを参照できない。

C#

using System.Collections; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(MeshRenderer))] [RequireComponent(typeof(MeshFilter))] public class kaku : MonoBehaviour { [SerializeField] private Material _mat; // Use this for initialization void Start() { var mesh = new Mesh(); float root3 = Mathf.Sqrt(3f); Vector3[] positions = new Vector3[] { //天板 new Vector3 (0f, 1f, 0f), new Vector3 (0f, 1f, 1f), new Vector3 (1f, 1f, 1f), new Vector3 (1f, 1f, 0f), //new Vector3 (0f, 1f, -2f), //new Vector3 (-root3, 1f, -1f), //new Vector3 (-root3, 1f, 1f), new Vector3 (0f, -1f, 0f), new Vector3 (0f, -1f, 1f), new Vector3 (1f, -1f, 1f), new Vector3 (1f, -1f, 0f), // new Vector3 (0f, -1f, -2f), //new Vector3 (-root3, -1f, -1f), //new Vector3 (-root3, -1f, 1f), }; mesh.vertices = new Vector3[] { // 天板 positions[0], positions[ 1], positions[ 2], positions[ 0], positions[ 2], positions[ 3], //positions[ 0], positions[ 3], positions[ 4], positions[ 0], positions[ 4], positions[ 5], positions[ 0], positions[ 5], positions[ 6], positions[ 0], positions[ 6], positions[ 1], // 底板 positions[4], positions[ 7], positions[ 6], positions[ 4], positions[6], positions[ 5], //positions[ 7], positions[11], positions[10], positions[ 7], positions[12], positions[11], positions[ 7], positions[13], positions[12], positions[ 7], positions[ 8], positions[13], // 側面 positions[1], positions[ 5], positions[ 2], positions[2], positions[ 6], positions[ 3], positions[3], positions[7], positions[ 0], positions[0], positions[4], positions[ 1], // positions[5], positions[12], positions[ 6], // positions[6], positions[13], positions[ 1], // 側面2 positions[1], positions[4], positions[ 5], positions[2], positions[ 5], positions[ 6], positions[3], positions[ 6], positions[7], positions[0], positions[7], positions[4], // positions[5], positions[11], positions[12], // positions[6], positions[12], positions[13] }; int[] triangles = new int[mesh.vertices.Length]; for (int i = 0; i < mesh.vertices.Length; i++) { triangles[i] = i; } mesh.triangles = triangles; mesh.RecalculateNormals(); var filter = GetComponent<MeshFilter>(); filter.sharedMesh = mesh; var renderer = GetComponent<MeshRenderer>(); renderer.material = _mat; } // Update is called once per frame void Update() { } } ↑これがソースを参考にして作成できた直方体 -------------------------------------------------------------- ↓これがエラーが出るソースコード メッシュがたくさんある直方体のコード (エラーがでたので、ポリゴンを書く部分はノータッチです。) using System.Collections; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(MeshRenderer))] [RequireComponent(typeof(MeshFilter))] public class manymesh: MonoBehaviour { [SerializeField] private Material _mat; // Use this for initialization void Start() { var mesh = new Mesh(); float root3 = Mathf.Sqrt(3f); for (int a = 0; a < 10; a++) { Vector3[] positions = new Vector3[] { new Vector3(0f, 1f+a, 0f), new Vector3(0f, 1f+a, 1f), new Vector3(1f, 1f+a, 1f), new Vector3(1f, 1f+a, 0f), }; } mesh.vertices = new Vector3[] { // 天板 positions[0], positions[ 1], positions[ 2], positions[ 0], positions[ 2], positions[ 3], // 底板 positions[4], positions[ 7], positions[ 6], positions[ 4], positions[6], positions[ 5], // 側面 positions[1], positions[ 5], positions[ 2], positions[2], positions[ 6], positions[ 3], positions[3], positions[7], positions[ 0], positions[0], positions[4], positions[ 1], // 側面2 positions[1], positions[4], positions[ 5], positions[2], positions[ 5], positions[ 6], positions[3], positions[ 6], positions[7], positions[0], positions[7], positions[4], }; int[] triangles = new int[mesh.vertices.Length]; for (int i = 0; i < mesh.vertices.Length; i++) { triangles[i] = i; } mesh.triangles = triangles; mesh.RecalculateNormals(); var filter = GetComponent<MeshFilter>(); filter.sharedMesh = mesh; var renderer = GetComponent<MeshRenderer>(); renderer.material = _mat; } // Update is called once per frame void Update() { } }

試したこと

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

C#では定義した{}の中でしか、その変数を使うことはできません。
これはforループなどの{}でも同様です。
具体的には、以下の通りになります。

C#

1 for (int a = 0; a < 10; a++) 2 { // (a) 3 // ↓の変数は(a)~(b)の中でしか使えない 4 Vector3[] positions = new Vector3[] { 5 // …(省略) 6 }; 7 } // (b) 8 9 mesh.vertices = new Vector3[] { 10 // ↓positionsは使えない位置に定義されているため、エラーが出る 11 // 天板 12 positions[0], positions[ 1], positions[ 2], positions[ 0], positions[ 2], positions[ 3], 13 // …(省略) 14 };

エラーを修正するには、以下のようにすればよいです。

C#

1 // 使用できる位置に定義しておく 2 Vector3[] positions; 3 for (int a = 0; a < 10; a++) 4 { 5 // (※) 6 positions = new Vector3[] { 7 // …(省略) 8 }; 9 } 10 11 mesh.vertices = new Vector3[] { 12 // 天板 13 positions[0], positions[ 1], positions[ 2], positions[ 0], positions[ 2], positions[ 3], 14 // …(省略) 15 };

とはいえ、上記ソースの(※)では配列を毎回新規作成(≠追加)してしまっているので、このままだと意図した通りに動作しないと思いますので、適宜修正してください。


追記:

このようなプログラムを書いたのですが、 mesh.vertices = new Vector3[] {
の中のposition1で未割り当てのローカル変数"position1"が使われましたと出てきて、コンパイルできません。

提示のソースは「position『s』1」になっているので、単純に名前間違いだと思います。

またこのコードでposition1の配列は意図する通りの配列になっていますか?

positions1 = positions;としても、positions1がpositionsになるだけで追加になりません。
また、そもそも配列は基本的に要素を追加することは出来ません。
最初に必要な分の配列を生成しておくか、Listを使ってください。

なお、「意図する通りの配列」になっているかどうかは、VisualStudioなどにあるデバッガを使うか、Debug.Log()で出力させれば、確認することができます。

ほかに良い書き方があれば教えてほしいです。

「最初に必要な分の配列を生成しておく」場合、以下のようになります。

C#

1 Vector3[] positions = new Vector3[10 * 4]; 2 for (int a = 0; a < 10; a++) 3 { 4 positions[a * 4] = new Vector3(0f, 1f+a, 0f); 5 positions[a * 4 + 1] = new Vector3(0f, 1f+a, 1f); 6 positions[a * 4 + 2] = new Vector3(1f, 1f+a, 1f); 7 positions[a * 4 + 3] = new Vector3(1f, 1f+a, 0f); 8 } 9 10 // 以降は変更前のソースと同じ 11 // positions1は使う必要なし

「Listを使う」場合、以下のようになります。

C#

1 List<Vector3> positionsList = new List<Vector3>(); 2 for (int a = 0; a < 10; a++) 3 { 4 // 個別に追加する場合(例) 5 // positionsList.Add(new Vector3(0f, 1f, 0f)); 6 7 // まとめて追加する場合は、AddRange()が使える 8 positionsList.AddRange(new Vector3[] { 9 new Vector3(0f, 1f+a, 0f), 10 new Vector3(0f, 1f+a, 1f), 11 new Vector3(1f, 1f+a, 1f), 12 new Vector3(1f, 1f+a, 0f), 13 }); 14 } 15 // Listから配列に変換 16 Vector3[] positions = positionsList.ToArray(); 17 18 19 // 以降は変更前のソースと同じ 20 // positions1は使う必要なし

投稿2018/09/08 09:35

編集2018/09/09 03:19
fiveHundred

総合スコア9739

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

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

meJ15

2018/09/09 01:07

回答ありがとうございます。そのような定義があるのですね。今のままだと配列が新規作成されるということで、一晩考えて void Start() { var mesh = new Mesh(); float root3 = Mathf.Sqrt(3f); Vector3[] positions; Vector3[] positions1;//要素追加用の配列 for (int a = 0; a < 10; a++) { positions = new Vector3[] { new Vector3(0f, 1f+a, 0f), new Vector3(0f, 1f+a, 1f), new Vector3(1f, 1f+a, 1f), new Vector3(1f, 1f+a, 0f), }; positions1 = positions; } mesh.vertices = new Vector3[] { // 天板 positions1[0], positions1[ 1], positions1[ 2], positions1[ 0], positions1[ 2], positions1[ 3], //positions[ 0], positions[ 3], positions[ 4], positions[ 0], positions[ 4], positions[ 5], positions[ 0], positions[ 5], positions[ 6], positions[ 0], positions[ 6], positions[ 1], //略 このようなプログラムを書いたのですが、 mesh.vertices = new Vector3[] { の中のposition1で未割り当てのローカル変数"position1"が使われましたと出てきて、コンパイルできません。 どこを変えればよいのでしょうか? またこのコードでposition1の配列は意図する通りの配列になっていますか? プログラムの考え方が弱くて、あってるか不安です。ほかに良い書き方があれば教えてほしいです。
fiveHundred

2018/09/09 03:19

回答に追記しました。
meJ15

2018/09/09 09:12

ご返信ありがとうございます。詳しい説明でわかりやすいです。 最初に必要な分の配列を用意するという手段で上手くコンパイルできました。この続きなのですが for (int a = 0; a < 10; a++) { mesh.vertices = new Vector3[] { positions[a+1],positions[a+5],positions[a+2], positions[a + 2],positions[a + 6],positions[a + 3], positions[a + 3],positions[a + 7],positions[a + 0], positions[a + 0],positions[a + 4],positions[a + 1], }; } その続きで上のようなコードを書いたのですが、これではまた新規作成になると考え、どうにかしなければといろいろ考えて下のようなコードになりました。 しかしmesh.verticesに位置ベクトルを代入する部分でつまってしまいました。 mesh.vertices = new Vector3[10*4]; Vector3[] vert = new Vector3[10 * 4];//vertは頂点座標を入れる用の配列 for (int a = 0,b = 0; a < 10 ; a++,b++) { vert[a*24]= new Vector3[] { positions[a * 4 + 1],positions[a * 4 + 5],positions[a * 4 + 2],//側面1の positions[a * 4 + 2],positions[a * 4 + 6],positions[a * 4 + 3], positions[a * 4 + 3],positions[a * 4 + 7],positions[a * 4 + 0], positions[a * 4 + 0],positions[a * 4 + 4],positions[a * 4 + 1], positions[a * 4 + 1],positions[a * 4 + 4],positions[a * 4 + 5],//側面2の positions[a * 4 + 2],positions[a * 4 + 5],positions[a * 4 + 6], positions[a * 4 + 3],positions[a * 4 + 6],positions[a * 4 + 7], positions[a * 4 + 0],positions[a * 4 + 7],positions[a * 4 + 4], }; } mesh.vertices = vert;//その頂点をmesh.verticesに代入 このようなコードを書いてコンパイルしようとすると for文の中のnew Vector3[] {の部分からずっと赤線でエラーになり、 「UnityEngine.Vector3[]をUnityEngine.Vector3に暗黙的に変換できません」とでてきて、詰まってしまいました。 vertという配列にfor文を使って頂点を保存していき最後に mesh.vertices = vert;として代入しようと考えました。 どこを改善すればよいでしょうか? Vector3[] vert = new Vector3[10 * 4]; と定義して vert[a*24]= new Vector3[] { とするのがおかしい気もするのですが、よくわかりません。 改善を教えてください。 何度も何度も申し訳ないです。
fiveHundred

2018/09/09 09:49

> vert[a*24]= new Vector3[] { 上記ですが、vert[a*24]は配列の要素なので、Vector3型です。 よって、Vector3[]型は代入できず、エラーとなります。 1つずつ代入するか、Array.Copy()(https://www.sejuku.net/blog/40212)などを使ってください。 また、エラー以外の指摘になりますが、 > mesh.vertices = new Vector3[10*4]; これは「mesh.vertices = vert;」で他の配列を代入することになるので、不要になります。 > Vector3[] vert = new Vector3[10 * 4]; 今回の場合、10ループ×24個必要なので「10 * 4」では足りません。
meJ15

2018/09/11 05:48

配列の勉強を一回本で挟んでからまた質問させていただきます。 回答ありがとうございました。 またよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問