
๐Art_006_Sine_Grid.cs
using UnityEngine;
using System.Collections.Generic;
public class Art_SineGrid : MonoBehaviour
{
[Header("๊ทธ๋ฆฌ๋ ๊ตฌ์กฐ (๋ณ๊ฒฝ ์ ์ค๋ธ์ ํธ ์ฌ์์ฑ)")]
public int gridSize = 50;
public float spacing = 0.8f;
public float cubeSize = 0.35f;
public int colorSeed = 0;
[Header("ํ๋ ์ค์ (์ค์๊ฐ ๋ฐ์)")]
public float waveHeight = 2.0f;
public float waveSpeed = 1.5f;
public float waveFrequency = 0.8f;
[Header("์์ ์ค์ (์ค์๊ฐ ๋ฐ์)")]
[ColorUsage(false)] public Color colorStart = new Color(0.1f, 0.1f, 0.1f);
[ColorUsage(false)] public Color colorEnd = new Color(1.0f, 1.0f, 1.0f);
public float emissionIntensity = 0.4f;
[Header("์ฌ์ง ์ค์ ")]
public Material baseMaterial;
struct CubeData
{
public Transform tr;
public Material mat;
public Vector3 basePos;
public float colorFactor;
}
List<CubeData> _cubes = new List<CubeData>();
void OnEnable()
{
if (baseMaterial == null)
baseMaterial = CreateURPMaterial();
Generate();
}
void Update()
{
ApplyAnimation(Time.time * waveSpeed);
}
void OnDisable()
{
Clear();
}
void Generate()
{
Clear();
Random.InitState(colorSeed);
float offset = (gridSize - 1) * spacing * 0.5f;
for (int x = 0; x < gridSize; x++)
{
for (int z = 0; z < gridSize; z++)
{
Vector3 pos = new Vector3(
x * spacing - offset,
0f,
z * spacing - offset
);
float colorFactor = Random.value;
SpawnCube(pos, colorFactor);
}
}
ApplyAnimation(0f);
}
void SpawnCube(Vector3 pos, float colorFactor)
{
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);
go.transform.SetParent(transform);
go.transform.localPosition = pos;
go.transform.localScale = Vector3.one * cubeSize;
Material mat = Instantiate(baseMaterial);
mat.EnableKeyword("_EMISSION");
mat.globalIlluminationFlags = MaterialGlobalIlluminationFlags.RealtimeEmissive;
go.GetComponent<Renderer>().material = mat;
_cubes.Add(new CubeData
{
tr = go.transform,
mat = mat,
basePos = pos,
colorFactor = colorFactor
});
}
void Clear()
{
foreach (var cube in _cubes)
{
if (cube.mat != null)
Destroy(cube.mat);
if (cube.tr != null)
Destroy(cube.tr.gameObject);
}
_cubes.Clear();
}
void ApplyAnimation(float t)
{
for (int i = 0; i < _cubes.Count; i++)
{
CubeData c = _cubes[i];
if (c.tr == null || c.mat == null) continue;
float wave = Mathf.Sin(
(c.basePos.x + c.basePos.z) * waveFrequency + t
) * waveHeight;
float normalized = (wave / waveHeight + 1f) * 0.5f;
Vector3 p = c.basePos;
p.y = wave;
c.tr.localPosition = p;
Color baseColor = Color.Lerp(colorStart, colorEnd, c.colorFactor);
float brightnessMod = Mathf.Lerp(0.4f, 1f, normalized);
Color albedo = baseColor * brightnessMod;
Color emission = baseColor * (brightnessMod * emissionIntensity);
c.mat.SetColor("_BaseColor", albedo);
c.mat.SetColor("_EmissionColor", emission);
}
}
Material CreateURPMaterial()
{
Shader urpShader = Shader.Find("Universal Render Pipeline/Lit");
if (urpShader == null)
{
Debug.LogWarning("[Art_SineGrid] URP ์
ฐ์ด๋๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค. Inspector ์์ baseMaterial ์ ์ง์ ํ ๋นํด์ฃผ์ธ์.");
return new Material(Shader.Find("Diffuse"));
}
Material mat = new Material(urpShader);
mat.EnableKeyword("_EMISSION");
mat.globalIlluminationFlags = MaterialGlobalIlluminationFlags.RealtimeEmissive;
return mat;
}
}