Unity一键替换选中物体的材质Editor
1. 编辑器脚本,方便快捷,省时省力(适合替换同一种材质球)
放在Editor文件夹下
直接上代码
using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; /// <summary> /// ************************一键替换模型的材质球**********************编辑器脚本************************************ /// /// ************************选中你要改变的模型,点击Tools/ChangeNewMaterial按钮即可************************** /// </summary> public class ChangeNewMaterial { [MenuItem("Tools/ChangeNewMaterial")] static void ChangeNewMat() { GameObject obj = Selection.activeGameObject; foreach (Renderer it in obj.transform.GetComponentsInChildren<Renderer>()) { Material mat = AssetDatabase.LoadAssetAtPath<Material>("Assets/消融/occ.mat"); //材质球的路径 Material[] bufMat = new Material[it.sharedMaterials.Length]; for (int i = 0; i < it.sharedMaterials.Length; i++) { bufMat[i] = mat; } it.sharedMaterials = bufMat; } } }
上面是编辑器脚本
下面是动态代码脚本
效果:
按钮点击物体切换材质,再次点击恢复原本材质
代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// <summary> /// 本脚本挂在摄像机上面 /// 动态变化物体材质球(同一个材质球) /// </summary> public class TransparentControl : MonoBehaviour { public class TransparentParam { public Material[] materials = null; public Material[] sharedMats = null; public float currentFadeTime = 0; public bool isTransparent = true; } public Transform targetObject = null; //目标对象 public float height = 3.0f; //目标对象Y方向偏移 private float destTransparent = 0.3f; //遮挡半透的最终半透强度, public float fadeInTime = 1.0f; //开始遮挡半透时渐变时间 private int transparentLayer; //需要遮挡半透的层级 private Dictionary<Renderer, TransparentParam> transparentDic = new Dictionary<Renderer, TransparentParam>(); private List<Renderer> clearList = new List<Renderer>(); public Button button; //测试按钮 public bool btnbool = false; void Start() { transparentLayer = 1 << 8;//第8层layer //按钮点击切换 button.onClick.AddListener(delegate { btnbool = !btnbool; if (btnbool) { Renderer[] renderers = targetObject.GetComponentsInChildren<Renderer>(); foreach (Renderer r in renderers) { AddTransparent(r); } } else { RemoveUnuseTransparent(); } }); } void Update() { if (targetObject == null) return; UpdateTransparentObject(); //UpdateRayCastHit(); //RemoveUnuseTransparent(); } public void UpdateTransparentObject() { var var = transparentDic.GetEnumerator(); while (var.MoveNext()) { TransparentParam param = var.Current.Value; param.isTransparent = false; foreach (var mat in param.materials) { //颜色自己设置 r g b a Color col = mat.GetColor("_Color"); param.currentFadeTime += Time.deltaTime; float t = param.currentFadeTime / fadeInTime; col.r = 0; col.g = 0.526f; col.b = 0.831f; col.a = Mathf.Lerp(1, destTransparent, t); mat.SetColor("_Color", col); } } } //射线检测有没有物体遮挡检测 (比如物体遮挡住人物,被遮挡物体变半透明) public void UpdateRayCastHit() { RaycastHit[] rayHits = null; //视线方向为从自身(相机)指向目标位置 Vector3 targetPos = targetObject.position + new Vector3(0, height, 0); Vector3 viewDir = (targetPos - transform.position).normalized; Vector3 oriPos = transform.position; float distance = Vector3.Distance(oriPos, targetPos); Ray ray = new Ray(oriPos, viewDir); rayHits = Physics.RaycastAll(ray, distance, transparentLayer); //直接在Scene画一条线,方便观察射线 Debug.DrawLine(oriPos, targetPos, Color.red); foreach (var hit in rayHits) { Renderer[] renderers = hit.collider.GetComponentsInChildren<Renderer>(); foreach (Renderer r in renderers) { AddTransparent(r); } } } //恢复物体原有材质 public void RemoveUnuseTransparent() { clearList.Clear(); var var = transparentDic.GetEnumerator(); while (var.MoveNext()) { if (var.Current.Value.isTransparent == false) { //用完后材质实例不会销毁,可以被unloadunuseasset销毁或切场景销毁。 var.Current.Key.materials = var.Current.Value.sharedMats; clearList.Add(var.Current.Key); } } foreach (var v in clearList) transparentDic.Remove(v); } //添加透明材质 void AddTransparent(Renderer renderer) { TransparentParam param = null; transparentDic.TryGetValue(renderer, out param); if (param == null) { param = new TransparentParam(); transparentDic.Add(renderer, param); //此处顺序不能反,调用material会产生材质实例。 param.sharedMats = renderer.sharedMaterials; param.materials = renderer.materials; foreach (var v in param.materials) { v.shader = Shader.Find("ApcShader/OcclusionTransparent"); } } param.isTransparent = true; } }
如果喜欢点个赞吧,感谢 ! ! !
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器