BITKit/Packages/Runtime~/Unity/Scripts/Utils/MeshRendering.cs

110 lines
3.7 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cysharp.Threading.Tasks;
using System.Threading.Tasks;
using UnityEngine.Rendering.Universal;
namespace BITKit
{
public class MeshRendering : MonoBehaviour
{
[System.Serializable]
public class RenderQueue
{
public Transform model;
public float size;
public bool captured;
public int time;
}
[RuntimeInitializeOnLoadMethod]
static void Reload()
{
GameObject gameObject = new(nameof(MeshRenderer));
GameObject.DontDestroyOnLoad(gameObject);
singleton = gameObject.AddComponent<MeshRendering>();
var camera = singleton.renderCamera = gameObject.AddComponent<Camera>();
gameObject.transform.position = Vector3.forward;
gameObject.transform.eulerAngles = new(0, -180, 0);
camera.orthographic = true;
camera.orthographicSize = 1;
camera.cullingMask = LayerMask.GetMask(LayerMask.LayerToName(31));
camera.clearFlags = CameraClearFlags.Depth;
camera.GetUniversalAdditionalCameraData().renderShadows = false;
singleton.renderTexture = new RenderTexture(256, 256, 16);
camera.targetTexture = singleton.renderTexture;
}
public static async Task<Texture2D> Create(Transform model)
{
RenderQueue queue = new()
{
model = model,
};
float size = 0;
foreach (var renderer in model.GetComponentsInChildren<Renderer>())
{
if (renderer is SkinnedMeshRenderer skinnedMeshRenderer)
{
size = Mathf.Max(size, skinnedMeshRenderer.sharedMesh.bounds.size.GetLength());
}
else if (renderer.TryGetComponent<MeshFilter>(out var meshFilter))
{
size = Mathf.Max(size, meshFilter.sharedMesh.bounds.size.GetLength());
}
}
queue.size = size / 2;
queues.Enqueue(queue);
await UniTask.WaitUntil(() => queue.captured);
return singleton.renderTexture.ConvertToTexture2D();
}
static Queue<RenderQueue> queues = new();
static MeshRendering singleton;
public Camera renderCamera;
public bool captured;
RenderTexture renderTexture;
RenderQueue current;
void Update()
{
if (current is not null)
{
foreach (var x in current.model.GetComponentsInChildren<Renderer>())
{
var material = Instantiate<Material>(x.sharedMaterial);
var mesh =
x is SkinnedMeshRenderer skinnedMeshRenderer ?
skinnedMeshRenderer.sharedMesh :
x.GetComponent<MeshFilter>().sharedMesh;
material.shader = Shader.Find("Universal Render Pipeline/Unlit");
Graphics.DrawMesh(
mesh,
x.transform.localPosition,
x.transform.localRotation,
material,
31
);
}
renderCamera.Render();
current.captured = true;
current = null;
renderCamera.enabled = false;
}
else if (queues.TryDequeue(out current))
{
renderCamera.orthographicSize = current.size;
renderCamera.enabled = true;
}
}
}
}