93 lines
3.9 KiB
C#
93 lines
3.9 KiB
C#
#nullable enable
|
|
|
|
using System.Collections.Generic;
|
|
using Demo2.Domain;
|
|
using Demo2.ECS;
|
|
using Unity.Collections;
|
|
using UnityEngine;
|
|
|
|
namespace Demo2.Runtime
|
|
{
|
|
public sealed class Demo2ItemBatchRenderer : MonoBehaviour
|
|
{
|
|
[SerializeField] private Texture2D? itemTexture;
|
|
private readonly List<Matrix4x4>[] _matrices = { new(), new(), new(), new(), new(), new() };
|
|
private readonly Material[] _materials = new Material[6];
|
|
private Mesh? _quad;
|
|
private Demo2EcsWorld? _world;
|
|
|
|
public void Bind(Demo2EcsWorld? world) => _world = world;
|
|
public void SetTexture(Texture2D texture) { itemTexture = texture; RebuildMaterials(); }
|
|
|
|
private void Awake()
|
|
{
|
|
if (Application.isBatchMode)
|
|
{
|
|
enabled = false;
|
|
return;
|
|
}
|
|
|
|
_quad = CreateQuad();
|
|
RebuildMaterials();
|
|
}
|
|
|
|
private void LateUpdate()
|
|
{
|
|
if (_world == null || _quad == null) return;
|
|
for (var i = 0; i < _matrices.Length; i++) _matrices[i].Clear();
|
|
var manager = _world.EntityManager;
|
|
var query = manager.CreateEntityQuery(typeof(Demo2GridPosition), typeof(Demo2MaterialState));
|
|
using var entities = query.ToEntityArray(Allocator.Temp);
|
|
using var positions = query.ToComponentDataArray<Demo2GridPosition>(Allocator.Temp);
|
|
using var materials = query.ToComponentDataArray<Demo2MaterialState>(Allocator.Temp);
|
|
for (var i = 0; i < entities.Length; i++)
|
|
{
|
|
var material = materials[i];
|
|
var x = positions[i].X + 0.5f;
|
|
var y = Demo2Protocol.GridHeight - positions[i].Y - 0.5f;
|
|
var offset = material.SubCellProgress / 1000f;
|
|
switch (material.Direction & 3) { case 0: x += offset; break; case 1: y += offset; break; case 2: x -= offset; break; case 3: y -= offset; break; }
|
|
var kind = Mathf.Clamp((int)material.Kind, 0, _matrices.Length - 1);
|
|
if (_matrices[kind].Count < 1023) _matrices[kind].Add(Matrix4x4.TRS(new Vector3(x, y, -0.2f), Quaternion.identity, Vector3.one * 0.34f));
|
|
}
|
|
for (var i = 0; i < _matrices.Length; i++)
|
|
if (_materials[i] != null && _matrices[i].Count > 0)
|
|
Graphics.DrawMeshInstanced(_quad, 0, _materials[i], _matrices[i]);
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (_quad != null) Destroy(_quad);
|
|
for (var i = 0; i < _materials.Length; i++) if (_materials[i] != null) Destroy(_materials[i]);
|
|
}
|
|
|
|
private void RebuildMaterials()
|
|
{
|
|
var colors = new[] { new Color(0.52f, 0.66f, 0.78f), new Color(0.42f, 0.32f, 0.28f), new Color(0.82f, 0.82f, 0.76f), new Color(0.86f, 0.68f, 0.22f), new Color(0.84f, 0.23f, 0.18f), new Color(0.16f, 0.82f, 0.88f) };
|
|
var shader = Shader.Find("Universal Render Pipeline/Unlit") ?? Shader.Find("Unlit/Texture");
|
|
if (shader == null)
|
|
{
|
|
enabled = false;
|
|
return;
|
|
}
|
|
|
|
for (var i = 0; i < _materials.Length; i++)
|
|
{
|
|
if (_materials[i] == null) _materials[i] = new Material(shader) { enableInstancing = true };
|
|
_materials[i].mainTexture = itemTexture;
|
|
_materials[i].color = colors[i];
|
|
}
|
|
}
|
|
|
|
private static Mesh CreateQuad()
|
|
{
|
|
var mesh = new Mesh { name = "Demo2 Item Quad" };
|
|
mesh.SetVertices(new[] { new Vector3(-.5f, -.5f), new Vector3(-.5f, .5f), new Vector3(.5f, .5f), new Vector3(.5f, -.5f) });
|
|
mesh.SetUVs(0, new[] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) });
|
|
mesh.SetTriangles(new[] { 0, 1, 2, 0, 2, 3 }, 0);
|
|
mesh.RecalculateBounds();
|
|
return mesh;
|
|
}
|
|
}
|
|
}
|