您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
163 行
4.6 KiB
163 行
4.6 KiB
using UnityEngine;
|
|
using UnityEngine.Serialization;
|
|
|
|
[ExecuteInEditMode]
|
|
public class MaterialPlacer : MonoBehaviour
|
|
{
|
|
public enum TargetType
|
|
{
|
|
Float,
|
|
Color
|
|
}
|
|
|
|
[SerializeField]
|
|
Renderer m_Prefab;
|
|
|
|
[SerializeField]
|
|
int m_Rows = 2;
|
|
|
|
[SerializeField]
|
|
int m_Cols = 2;
|
|
|
|
[SerializeField]
|
|
Vector3 m_Size = Vector3.one;
|
|
|
|
[SerializeField]
|
|
TargetType m_TargetType;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("m_FloatName")]
|
|
string m_PropertyName;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("m_FromValue")]
|
|
float m_FromValueFloat = 0;
|
|
|
|
[SerializeField]
|
|
[FormerlySerializedAs("m_ToValue")]
|
|
float m_ToValueFloat = 1;
|
|
|
|
[SerializeField]
|
|
Color m_FromValueColor = Color.white;
|
|
|
|
[SerializeField]
|
|
Color m_ToValueColor = Color.white;
|
|
|
|
int m_LastHash = 0;
|
|
|
|
void Update()
|
|
{
|
|
int hash = CalculateParameterHash();
|
|
if (hash != m_LastHash)
|
|
{
|
|
m_LastHash = hash;
|
|
Regenerate();
|
|
}
|
|
}
|
|
|
|
[ContextMenu("Regenerate")]
|
|
void Regenerate()
|
|
{
|
|
DestroyAll();
|
|
if (m_LastHash != 0)
|
|
Generate();
|
|
}
|
|
|
|
void Generate()
|
|
{
|
|
var tr = transform;
|
|
var count = (float)(m_Cols * m_Rows - 1);
|
|
var _1_count = 1f / count;
|
|
|
|
var positionOffset = -m_Size;
|
|
var positionStep = new Vector3(2f * m_Size.x / (m_Rows - 1f), 2f * m_Size.y / (m_Cols - 1f), 0);
|
|
|
|
switch (m_TargetType)
|
|
{
|
|
case TargetType.Float:
|
|
{
|
|
var valueOffset = m_FromValueFloat;
|
|
var valueStep = (m_ToValueFloat - m_FromValueFloat) * _1_count;
|
|
|
|
for (var j = 0; j < m_Cols; j++)
|
|
{
|
|
for (var i = 0; i < m_Rows; i++)
|
|
{
|
|
var instance = Instantiate(m_Prefab);
|
|
var itr = instance.transform;
|
|
itr.SetParent(tr, false);
|
|
itr.localPosition = Vector3.Scale(positionStep, new Vector3(i, j, 0)) + positionOffset;
|
|
var mat = Instantiate(instance.sharedMaterial);
|
|
instance.material = mat;
|
|
var value = valueOffset + valueStep * (i + j * m_Rows);
|
|
instance.name = string.Format("{0} {1}", m_Prefab.name, value.ToString("F2"));
|
|
mat.SetFloat(m_PropertyName, value);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case TargetType.Color:
|
|
{
|
|
var valueOffset = m_FromValueColor;
|
|
var valueStep = (m_ToValueColor - m_FromValueColor) * _1_count;
|
|
|
|
for (var j = 0; j < m_Cols; j++)
|
|
{
|
|
for (var i = 0; i < m_Rows; i++)
|
|
{
|
|
var instance = Instantiate(m_Prefab);
|
|
var itr = instance.transform;
|
|
itr.SetParent(tr, false);
|
|
itr.localPosition = Vector3.Scale(positionStep, new Vector3(i, j, 0)) + positionOffset;
|
|
var mat = Instantiate(instance.sharedMaterial);
|
|
instance.material = mat;
|
|
var value = valueOffset + valueStep * (i + j * m_Rows);
|
|
instance.name = string.Format("{0} {1}", m_Prefab.name, value.ToString("F2"));
|
|
mat.SetColor(m_PropertyName, value);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void DestroyAll()
|
|
{
|
|
var tr = transform;
|
|
var childCount = tr.childCount;
|
|
for (var i = childCount - 1; i >= 0; --i)
|
|
{
|
|
var child = tr.GetChild(i);
|
|
var renderer = child.GetComponent<Renderer>();
|
|
|
|
if (renderer != null)
|
|
{
|
|
var mat = renderer.sharedMaterial;
|
|
DestroyImmediate(mat, false);
|
|
}
|
|
|
|
DestroyImmediate(child.gameObject, false);
|
|
}
|
|
}
|
|
|
|
int CalculateParameterHash()
|
|
{
|
|
if (m_Prefab == null || string.IsNullOrEmpty(m_PropertyName))
|
|
return 0;
|
|
|
|
return m_Prefab.GetInstanceID()
|
|
^ m_Rows.GetHashCode()
|
|
^ m_Cols.GetHashCode()
|
|
^ m_Size.GetHashCode()
|
|
^ m_PropertyName.GetHashCode()
|
|
^ m_FromValueFloat.GetHashCode()
|
|
^ m_ToValueFloat.GetHashCode();
|
|
}
|
|
|
|
void OnValidate()
|
|
{
|
|
m_Rows = Mathf.Max(2, m_Rows);
|
|
m_Cols = Mathf.Max(2, m_Cols);
|
|
m_Size = Vector3.Max(Vector3.zero, m_Size);
|
|
}
|
|
}
|