Files
CartoonRPG/Assets/StixGames/GrassShader/Example/GameScene/Scripts/TextureObjectInstanciator.cs

93 lines
2.9 KiB
C#
Raw Normal View History

2025-06-05 22:59:18 +01:00
using System.Collections.Generic;
using StixGames.NatureCore.Utility;
using UnityEngine;
namespace StixGames.GrassShader.Example
{
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter))]
public class TextureObjectInstanciator : MonoBehaviour
{
public int MinDensity = 1;
public int MaxDensity = 5;
public float MinScale = 1.0f;
public float MaxScale = 1.2f;
public Transform[] Objects;
public Texture2D DensityTexture;
public int Seed = 1234;
public bool DoUpdate = false;
public void Update()
{
if (!DoUpdate)
{
return;
}
DoUpdate = false;
var objects = new List<Transform>();
foreach (Transform child in transform)
{
objects.Add(child);
}
foreach (var o in objects)
{
#if UNITY_EDITOR
DestroyImmediate(o.gameObject);
#else
Destroy(o.gameObject);
#endif
}
var rng = new System.Random(Seed);
var posSampler = new Sampler2D(new HaltonSampler(2, rng.Range(1, 1000)),
new HaltonSampler(3, rng.Range(1, 1000)));
var mesh = GetComponent<MeshFilter>().sharedMesh;
var triangles = mesh.triangles;
var vertices = mesh.vertices;
var uvs = mesh.uv;
for (int i = 0; i < triangles.Length; i += 3)
{
var t0 = triangles[i];
var t1 = triangles[i + 1];
var t2 = triangles[i + 2];
var v0 = vertices[t0];
var v1 = vertices[t1];
var v2 = vertices[t2];
var uv0 = uvs[t0];
var uv1 = uvs[t1];
var uv2 = uvs[t2];
var triangle = new Triangle(v0, v1, v2, uv0, uv1, uv2);
var objectCount = rng.Range(MinDensity, MaxDensity);
for (int j = 0; j < objectCount; j++)
{
var coords = triangle.GetRandomCoordinates(posSampler);
var pos = triangle.GetPosition(coords);
var uv = triangle.GetUVCoordinates(coords);
var density = DensityTexture.GetPixelBilinear(uv.x, uv.y);
if (density.r > rng.Range(0.0f, 1.0f))
{
CreateInstance(pos, rng);
}
}
}
}
private void CreateInstance(Vector3 pos, System.Random rng)
{
var scale = rng.Range(MinScale, MaxScale);
var index = rng.Range(0, Objects.Length);
var instance = Instantiate(Objects[index], transform.TransformPoint(pos), Quaternion.identity, transform);
instance.localScale = new Vector3(scale / transform.localScale.x, scale / transform.localScale.y, scale / transform.localScale.z);
}
}
}