跳到主要内容

材质material

新建材质 material 在属性中切换颜色

找到要换颜色的 控件 修改其材质为指定材质


// 方法1:创建使用 Standard Shader 的 Material
Material myMaterial = new Material(Shader.Find("Standard"));

// 方法2:从现有 Material 克隆
Material clonedMaterial = new Material(existingMaterial);

// 方法3:使用特定 Shader
Material uiMaterial = new Material(Shader.Find("UI/Default"));
Material spriteMaterial = new Material(Shader.Find("Sprites/Default"));

// 方法4:创建无光照 Material
Material unlitMaterial = new Material(Shader.Find("Unlit/Color"));
unlitMaterial.color = Color.red;



Material m1 = Resources.Load("blue") as Material;

Renderer r1 = cube.GetComponent<Renderer>();
r1.sharedMaterial = m1;

1. 应用到单个物体

csharp

public class MaterialApplicator : MonoBehaviour
{
public Material targetMaterial;

void Start()
{
// 方法1:通过 Renderer 组件
Renderer renderer = GetComponent<Renderer>();
if (renderer != null)
{
renderer.material = targetMaterial; // 创建实例
// 或使用 sharedMaterial 共享材质(所有使用该材质的物体都会受影响)
// renderer.sharedMaterial = targetMaterial;
}

// 方法2:应用到子物体
Renderer[] childRenderers = GetComponentsInChildren<Renderer>();
foreach (Renderer childRenderer in childRenderers)
{
childRenderer.material = targetMaterial;
}
}
}

2. 应用到多个材质槽

csharp

void ApplyMultipleMaterials()
{
Renderer renderer = GetComponent<Renderer>();

// 设置多个材质(用于多材质渲染)
Material[] materials = new Material[2];
materials[0] = primaryMaterial;
materials[1] = secondaryMaterial;

renderer.materials = materials; // 注意:会创建新实例
// 或使用 sharedMaterials 共享
// renderer.sharedMaterials = materials;
}

四、Material 属性设置

1. 常用属性设置方法

csharp

public class MaterialPropertySetter : MonoBehaviour
{
public Material material;

void Start()
{
// 1. 设置颜色
material.color = Color.red; // 设置主颜色
material.SetColor("_Color", Color.blue); // 通过属性名设置
material.SetColor("_EmissionColor", Color.green * 0.5f); // 自发光颜色

// 2. 设置纹理
public Texture2D diffuseTexture;
public Texture2D normalTexture;

material.mainTexture = diffuseTexture; // 主纹理
material.SetTexture("_MainTex", diffuseTexture); // 同上
material.SetTexture("_BumpMap", normalTexture); // 法线贴图

// 3. 设置浮点值
material.SetFloat("_Metallic", 0.5f); // 金属度
material.SetFloat("_Glossiness", 0.8f); // 光滑度
material.SetFloat("_Cutoff", 0.5f); // 透明裁切

// 4. 设置向量/颜色
material.SetVector("_SomeVector", new Vector4(1, 0, 0, 1));

// 5. 启用/禁用关键字(Shader变体)
material.EnableKeyword("_EMISSION");
material.DisableKeyword("_SPECULARHIGHLIGHTS_OFF");
}
}

2. Standard Shader 完整示例

csharp

public class StandardMaterialSetup : MonoBehaviour
{
public Material standardMaterial;

void SetupStandardMaterial()
{
// Albedo (漫反射)
standardMaterial.SetColor("_Color", new Color(0.8f, 0.8f, 0.8f, 1f));

// Metallic/Smoothness (金属/光滑)
standardMaterial.SetFloat("_Metallic", 0.5f);
standardMaterial.SetFloat("_Glossiness", 0.8f);

// Normal Map (法线贴图)
if (normalMap != null)
{
standardMaterial.SetTexture("_BumpMap", normalMap);
standardMaterial.SetFloat("_BumpScale", 1.0f);
}

// Height Map (高度图/视差)
if (heightMap != null)
{
standardMaterial.SetTexture("_ParallaxMap", heightMap);
standardMaterial.SetFloat("_Parallax", 0.02f);
}

// Occlusion (环境遮蔽)
if (occlusionMap != null)
{
standardMaterial.SetTexture("_OcclusionMap", occlusionMap);
standardMaterial.SetFloat("_OcclusionStrength", 1.0f);
}

// Emission (自发光)
standardMaterial.SetColor("_EmissionColor", Color.black);
standardMaterial.EnableKeyword("_EMISSION");

// Detail Mask/Albedo (细节遮罩/漫反射)
if (detailAlbedoMap != null)
{
standardMaterial.SetTexture("_DetailAlbedoMap", detailAlbedoMap);
standardMaterial.SetTexture("_DetailMask", detailMask);
}

// UV 设置
standardMaterial.SetTextureScale("_MainTex", new Vector2(2, 2)); // 平铺
standardMaterial.SetTextureOffset("_MainTex", new Vector2(0.5f, 0.5f)); // 偏移
}
}

五、动态修改 Material 属性

1. 运行时动态修改

csharp

public class DynamicMaterialController : MonoBehaviour
{
private Material materialInstance;
private Renderer objectRenderer;

void Start()
{
objectRenderer = GetComponent<Renderer>();
materialInstance = objectRenderer.material; // 获取实例副本

// 初始设置
materialInstance.color = Color.white;
}

void Update()
{
// 1. 随时间变化颜色
Color pulseColor = Color.Lerp(Color.red, Color.blue,
Mathf.PingPong(Time.time, 1f));
materialInstance.color = pulseColor;

// 2. 随时间变化透明度
float alpha = 0.5f + 0.5f * Mathf.Sin(Time.time);
Color currentColor = materialInstance.color;
materialInstance.color = new Color(currentColor.r, currentColor.g,
currentColor.b, alpha);

// 3. 纹理滚动效果
float scrollSpeed = 0.5f;
Vector2 offset = materialInstance.mainTextureOffset;
offset.x = Time.time * scrollSpeed;
offset.y = Time.time * scrollSpeed * 0.5f;
materialInstance.mainTextureOffset = offset;

// 4. 纹理缩放动画
float scale = 1f + 0.5f * Mathf.Sin(Time.time);
materialInstance.mainTextureScale = new Vector2(scale, scale);
}
}

2. 交互式 Material 控制

csharp

public class InteractiveMaterial : MonoBehaviour
{
private Material mat;

void Start()
{
mat = GetComponent<Renderer>().material;
}

void OnMouseEnter()
{
// 鼠标悬停时高亮
mat.EnableKeyword("_EMISSION");
mat.SetColor("_EmissionColor", Color.yellow * 0.5f);
}

void OnMouseExit()
{
// 鼠标离开时恢复
mat.DisableKeyword("_EMISSION");
}

void OnMouseDown()
{
// 点击时改变材质
mat.color = Random.ColorHSV();
}
}

六、Material 与 Shader 交互

1. 访问和修改 Shader 属性

csharp

public class ShaderPropertyAccess : MonoBehaviour
{
private Material material;

void Start()
{
material = GetComponent<Renderer>().material;

// 获取所有属性
int propertyCount = material.shader.GetPropertyCount();
for (int i = 0; i < propertyCount; i++)
{
string propertyName = material.shader.GetPropertyName(i);
Debug.Log($"属性 {i}: {propertyName}");
}

// 检查属性是否存在
bool hasProperty = material.HasProperty("_Color");

// 获取属性类型
if (material.HasProperty("_Color"))
{
ShaderPropertyType type = material.shader.GetPropertyType(
material.shader.FindPropertyIndex("_Color"));
Debug.Log($"Color 属性类型: {type}");
}
}
}

2. 自定义 Shader 属性设置

csharp

public class CustomShaderProperties : MonoBehaviour
{
public Material customMaterial;

void Update()
{
// 设置自定义属性(需要在Shader中定义)
float timeValue = Mathf.Sin(Time.time);

// 浮点数
customMaterial.SetFloat("_CustomFloat", timeValue);

// 颜色
customMaterial.SetColor("_CustomColor",
new Color(timeValue, 0.5f, 0.5f, 1f));

// 向量
customMaterial.SetVector("_CustomVector",
new Vector4(timeValue, timeValue * 0.5f, 0, 1));

// 矩阵(较少使用)
Matrix4x4 matrix = Matrix4x4.identity;
customMaterial.SetMatrix("_CustomMatrix", matrix);
}
}

七、性能优化技巧

1. Material Property Blocks

csharp

public class MaterialPropertyBlockExample : MonoBehaviour
{
private Renderer renderer;
private MaterialPropertyBlock propertyBlock;

void Start()
{
renderer = GetComponent<Renderer>();
propertyBlock = new MaterialPropertyBlock();

// 获取当前属性
renderer.GetPropertyBlock(propertyBlock);

// 设置属性(不会创建Material实例)
propertyBlock.SetColor("_Color", Color.red);
propertyBlock.SetFloat("_Glossiness", 0.8f);

// 应用属性
renderer.SetPropertyBlock(propertyBlock);

// 批量设置多个物体
Renderer[] allRenderers = FindObjectsOfType<Renderer>();
foreach (Renderer r in allRenderers)
{
r.SetPropertyBlock(propertyBlock);
}
}

void Update()
{
// 动态更新属性(高效)
renderer.GetPropertyBlock(propertyBlock);
float pulse = Mathf.PingPong(Time.time, 1f);
propertyBlock.SetColor("_Color", Color.Lerp(Color.red, Color.blue, pulse));
renderer.SetPropertyBlock(propertyBlock);
}
}

2. Material 实例化 vs 共享

csharp

public class MaterialInstanceManagement : MonoBehaviour
{
void ManageMaterials()
{
Renderer renderer = GetComponent<Renderer>();

// ❌ 不要这样做(每帧创建新实例)
// renderer.material.color = Color.red;

// ✅ 正确做法:缓存material实例
Material mat = renderer.material; // 获取实例
mat.color = Color.red; // 修改实例

// ✅ 如果需要修改多个物体且效果相同,使用sharedMaterial
// renderer.sharedMaterial.color = Color.red;

// ✅ 使用MaterialPropertyBlock(最佳性能)
MaterialPropertyBlock block = new MaterialPropertyBlock();
renderer.GetPropertyBlock(block);
block.SetColor("_Color", Color.red);
renderer.SetPropertyBlock(block);
}
}

八、特殊 Material 类型

1. UI Material

csharp

public class UIMaterialController : MonoBehaviour
{
public Image uiImage;

void SetupUIMaterial()
{
// UI Material 特殊属性
Material uiMaterial = uiImage.material;

// 设置遮罩
uiMaterial.EnableKeyword("UNITY_UI_CLIP_RECT");

// 设置软边
uiMaterial.SetFloat("_Softness", 0.5f);

// 设置颜色叠加
uiMaterial.SetColor("_Color", new Color(1, 1, 1, 0.8f));
}
}

2. 粒子系统 Material

csharp

public class ParticleMaterialController : MonoBehaviour
{
public ParticleSystem particleSystem;

void SetupParticleMaterial()
{
var renderer = particleSystem.GetComponent<ParticleSystemRenderer>();
Material particleMat = renderer.material;

// 粒子系统特殊设置
particleMat.SetTexture("_MainTex", particleTexture);
particleMat.SetInt("_BlendOp", (int)UnityEngine.Rendering.BlendOp.Add);

// 设置渲染模式
renderer.renderMode = ParticleSystemRenderMode.Stretch;

// 设置材质球
renderer.material = particleMat;
}
}

3. 地形 Material

csharp

public class TerrainMaterialController : MonoBehaviour
{
public Terrain terrain;

void SetupTerrainMaterial()
{
// 获取地形材质
Material terrainMaterial = terrain.materialTemplate;

// 设置地形纹理
if (terrainMaterial != null)
{
// Standard Terrain Shader 属性
terrainMaterial.SetTexture("_MainTex", terrainTexture);
terrainMaterial.SetTexture("_MetallicGlossMap", metallicMap);

// 控制贴图混合
terrainMaterial.SetFloat("_Metallic", 0.2f);
terrainMaterial.SetFloat("_Glossiness", 0.3f);
}
}
}

九、Material 资源管理

1. 加载和卸载 Material

csharp

public class MaterialResourceManager : MonoBehaviour
{
// 从 Resources 加载
Material LoadMaterialFromResources(string path)
{
return Resources.Load<Material>(path);
}

// 从 AssetBundle 加载
IEnumerator LoadMaterialFromAssetBundle(string bundlePath, string materialName)
{
AssetBundle bundle = AssetBundle.LoadFromFile(bundlePath);
AssetBundleRequest request = bundle.LoadAssetAsync<Material>(materialName);
yield return request;

Material loadedMaterial = request.asset as Material;

// 使用后卸载
bundle.Unload(false);
}

// 动态创建并管理
void CreateAndManageMaterials()
{
List<Material> createdMaterials = new List<Material>();

// 创建多个材质
for (int i = 0; i < 10; i++)
{
Material mat = new Material(Shader.Find("Standard"));
mat.color = Color.HSVToRGB(i / 10f, 1, 1);
createdMaterials.Add(mat);
}

// 使用...

// 清理
foreach (Material mat in createdMaterials)
{
Destroy(mat);
}
createdMaterials.Clear();

// 强制垃圾回收(谨慎使用)
Resources.UnloadUnusedAssets();
}
}