protected override unsafe void OnUpdate() { EntityQuery query = GetEntityQuery(ComponentType.ReadWrite <TrailBufferElement>()); NativeArray <Entity> entitis = query.ToEntityArray(Allocator.Persistent); int segmentCount = entitis.Length; int trailElementCount = 0; BufferFromEntity <TrailBufferElement> buffers = GetBufferFromEntity <TrailBufferElement>(); for (int i = 0; i < entitis.Length; ++i) { trailElementCount += buffers[entitis[i]].Length; } if (!m_TrailElements.IsCreated || m_TrailElements.Length < trailElementCount) { if (m_TrailElements.IsCreated) { m_TrailElements.Dispose(); } m_TrailElements = new NativeArray <float3>(CalcWrappingArraySize(trailElementCount), Allocator.Persistent); m_TrailElementBufferInShader?.Dispose(); m_TrailElementBufferInShader = new ComputeBuffer(m_TrailElements.Length, sizeof(TrailBufferElement)); } if (!m_Segments.IsCreated || m_Segments.Length < segmentCount) { if (m_Segments.IsCreated) { m_Segments.Dispose(); } m_Segments = new NativeArray <int3>(CalcWrappingArraySize(segmentCount), Allocator.Persistent); m_SegmentBufferInShader?.Dispose(); m_SegmentBufferInShader = new ComputeBuffer(m_Segments.Length, sizeof(TrailBufferElement)); } int offset = 0; float3 *trailElementsPtr = (float3 *)m_TrailElements.GetUnsafePtr(); int3 * segmentsPtr = (int3 *)m_Segments.GetUnsafePtr(); for (int i = 0; i < segmentCount; ++i) { DynamicBuffer <float3> trailbuffer = buffers[entitis[i]].Reinterpret <float3>(); Entity entity = entitis[i]; int bufferlength = trailbuffer.Length; UnsafeUtility.MemCpy(trailElementsPtr, trailbuffer.GetUnsafePtr(), sizeof(float3) * bufferlength); *segmentsPtr = new int3(offset, bufferlength, entity.Index); offset += bufferlength; segmentsPtr++; trailElementsPtr += bufferlength; for (int j = 0; j < trailbuffer.Length; ++j) { if (trailbuffer[j].x == 0.0f && trailbuffer[j].y == 0.0f && trailbuffer[j].z == 0.0f) { Debug.Log(entity.Index); } } } m_TrailElementBufferInShader.SetData(m_TrailElements); m_SegmentBufferInShader.SetData(m_Segments); m_MaterialPropertyBlock.SetBuffer("_Positions", m_TrailElementBufferInShader); m_MaterialPropertyBlock.SetBuffer("_Segments", m_SegmentBufferInShader); m_MeshInstancedArgs.SetData(m_TrailMesh, (uint)segmentCount); Graphics.DrawMeshInstancedIndirect( m_TrailMesh, 0, m_Material, new Bounds(Vector3.zero, Vector3.one * 1000), m_MeshInstancedArgs.m_Buffer, 0, m_MaterialPropertyBlock ); entitis.Dispose(); }
protected override unsafe void OnUpdate() { // Segmentの個数を計算 var segmentCount = componentGroup.CalculateLength(); // TrailElementの個数を計算 var trailBufferArray = componentGroup.GetBufferArray <TrailBufferElement>(); var trailElementCount = 0; for (var i = 0; i < segmentCount; ++i) { trailElementCount += trailBufferArray[i].Length; } // 配列のサイズが足りなかったら新しく作り直す if (!trailElements.IsCreated || trailElements.Length < trailElementCount) { if (trailElements.IsCreated) { trailElements.Dispose(); } trailElements = new NativeArray <float3>(CalcWrappingArraySize(trailElementCount), Allocator.Persistent); trailElementBuffer?.Dispose(); trailElementBuffer = new ComputeBuffer(trailElements.Length, sizeof(TrailBufferElement)); } if (!segments.IsCreated || segments.Length < segmentCount) { if (segments.IsCreated) { segments.Dispose(); } segments = new NativeArray <int3>(CalcWrappingArraySize(segmentCount), Allocator.Persistent); segmentBuffer?.Dispose(); segmentBuffer = new ComputeBuffer(segments.Length, sizeof(TrailBufferElement)); } // UnsafePtrを取得する var offset = 0; var trailElementsPtr = (float3 *)trailElements.GetUnsafePtr(); var segmentsPtr = (int3 *)segments.GetUnsafePtr(); var entityArray = componentGroup.GetEntityArray(); // あらかじめ計算してあったSegmentの数(=パーティクルの数)だけループを回す for (var i = 0; i < segmentCount; ++i) { var trailBuffer = trailBufferArray[i]; var entity = entityArray[i]; var bufferLength = trailBuffer.Length; // TrailBufferの値をNativeArrayに複製していく UnsafeUtility.MemCpy(trailElementsPtr, trailBuffer.GetBasePointer(), sizeof(float3) * bufferLength); *segmentsPtr = new int3(offset, bufferLength, entity.Index); // Segmentにヘッダ情報を書き込む // ヘッダ用のオフセットを再計算しておく offset += bufferLength; // ポインタを進める segmentsPtr++; trailElementsPtr += bufferLength; } // ComputeBufferにNativeArrayの情報を渡す trailElementBuffer.SetData(trailElements); segmentBuffer.SetData(segments); // MaterialPropertyBlockに生成したBufferを渡す materialPropertyBlock.SetBuffer("_Positions", trailElementBuffer); materialPropertyBlock.SetBuffer("_Segments", segmentBuffer); // Segmentの数を渡しておく meshInstancedArgs.SetData(trailMesh, (uint)segmentCount); // Meshを描画する Graphics.DrawMeshInstancedIndirect( trailMesh, 0, Material, new Bounds(Vector3.zero, Vector3.one * 1000), meshInstancedArgs.Buffer, 0, materialPropertyBlock ); }