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; } }
如果喜歡點個贊吧,感謝 ! ! !