前提・実現したいこと
Graphics.DrawMeshInstancedを使い、一つのマテリアルで複数の画像を描画したい。
該当のソースコード
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using System.Linq; 5 6public class World_P : MonoBehaviour 7{ 8 public Tile_P tile_P; 9 public Tile_P tile_P2; 10 11 public Material material; 12 13 Mesh mesh; 14 15 Matrix4x4[][] matrices; 16 int count; 17 18 int rows; 19 int columns; 20 21 public static World_P instance { get; private set; } 22 23 private List<Vector2> posList = new List<Vector2>(); 24 25 void Awake() 26 { 27 instance = this; 28 } 29 30 private void Start() 31 { 32 CreateTiles(); 33 GenerateMesh(); 34 } 35 36 public void CreateTiles() 37 { 38 tile_P = new Tile_P(Tile_P.Type.Tree); 39 tile_P2 = new Tile_P(Tile_P.Type.Grass); 40 for(var i = 0;i < 100; i++) 41 { 42 for(var j = 0;j < 100; j++) 43 { 44 Vector2 pos = new Vector2(i, j); 45 posList.Add(pos); 46 } 47 } 48 } 49 50 public void GenerateMesh() 51 { 52 mesh = new Mesh(); 53 54 MeshData_P meshData = new MeshData_P(tile_P); 55 mesh.vertices = meshData.vertices.ToArray(); 56 mesh.triangles = meshData.triangles.ToArray(); 57 mesh.uv = meshData.UVs.ToArray(); 58 59 mesh.RecalculateNormals(); 60 mesh.RecalculateBounds(); 61 62 rows = 100; 63 columns = 100; 64 65 count = rows * columns; 66 var flatMatrices = new Matrix4x4[count]; 67 68 for (var i = 0; i < posList.Count; i++) 69 { 70 var index = i; 71 72 var position = posList[i]; 73 74 var rotation = Quaternion.identity; 75 76 var scale = Vector3.one; 77 78 flatMatrices[index] = Matrix4x4.TRS(position, rotation, scale); 79 } 80 81 matrices = flatMatrices.Select((m, i) => (m, i / 1023)) 82 .GroupBy(t => t.Item2) 83 .Select(g => g.Select(t => t.Item1).ToArray()).ToArray(); 84 } 85 86 void Update() 87 { 88 foreach (var m in matrices) 89 { 90 Graphics.DrawMeshInstanced(mesh, 0, material, m); 91 } 92 } 93} 94
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class MeshData_P 6{ 7 public List<Vector3> vertices; 8 public List<int> triangles; 9 public List<Vector2> UVs; 10 11 public MeshData_P(Tile_P data) 12 { 13 vertices = new List<Vector3>(); 14 triangles = new List<int>(); 15 UVs = new List<Vector2>(); 16 17 CreateSquare(data); 18 } 19 20 void CreateSquare(Tile_P tile_P) 21 { 22 vertices.Add(new Vector3(0,0)); 23 vertices.Add(new Vector3(1,0)); 24 vertices.Add(new Vector3(0,1)); 25 vertices.Add(new Vector3(1,1)); 26 27 triangles.Add(vertices.Count - 1); 28 triangles.Add(vertices.Count - 3); 29 triangles.Add(vertices.Count - 4); 30 31 triangles.Add(vertices.Count - 2); 32 triangles.Add(vertices.Count - 1); 33 triangles.Add(vertices.Count - 4); 34 35 UVs.AddRange(SpriteLoader_P.instance.GetTileUVs(tile_P)); 36 } 37} 38
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class SpriteLoader_P : MonoBehaviour 6{ 7 public static SpriteLoader_P instance; 8 9 Dictionary<string, Vector2[]> tileUVMap; 10 11 void Awake() 12 { 13 instance = this; 14 15 tileUVMap = new Dictionary<string, Vector2[]>(); 16 17 Sprite[] sprites = Resources.LoadAll<Sprite>("Plants"); 18 19 float imageWidth = 0f; 20 float imageHeight = 0f; 21 22 foreach(Sprite s in sprites) 23 { 24 if(s.rect.x + s.rect.width > imageWidth) 25 { 26 imageWidth = s.rect.x + s.rect.width; 27 } 28 29 if(s.rect.y + s.rect.height > imageHeight) 30 { 31 imageHeight = s.rect.y + s.rect.height; 32 } 33 } 34 35 foreach(Sprite s in sprites) 36 { 37 Vector2[] uvs = new Vector2[4]; 38 39 uvs[0] = new Vector2(s.rect.x / imageWidth, s.rect.y / imageHeight); 40 uvs[1] = new Vector2((s.rect.x + s.rect.width) / imageWidth, s.rect.y / imageHeight); 41 uvs[2] = new Vector2(s.rect.x / imageWidth, (s.rect.y + s.rect.height) / imageHeight); 42 uvs[3] = new Vector2((s.rect.x + s.rect.width) / imageWidth, (s.rect.y + s.rect.height) / imageHeight); 43 44 tileUVMap.Add(s.name, uvs); 45 } 46 } 47 48 public Vector2[] GetTileUVs(Tile_P tile_P) 49 { 50 string key = tile_P.type.ToString(); 51 52 if(tileUVMap.ContainsKey(key) == true) 53 { 54 return tileUVMap[key]; 55 } 56 else 57 { 58 Debug.Log("There is no UV map for tile type : " + key); 59 return tileUVMap["Void"]; 60 } 61 } 62} 63
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Tile_P 6{ 7 public enum Type { Tree,Grass,Void } 8 public Type type; 9 10 public Tile_P(Type type) 11 { 12 this.type = type; 13 } 14} 15
試したこと
Multipleな画像をマテリアルに適応し、World.csで指定することで描画出来るように書きましたが、二種類以上の画像を描画することが出来ません。出来るのは一種類のみです。
Graphics.DrawMeshInstancedを一度だけ使用し、一つのマテリアルで複数の画像を描画出来るように試行錯誤しましたが、どうしても出来なかったため質問しました。
使用した画像↓
回答お願いします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2019/04/27 13:26