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;
    }

}

 

如果喜歡點個贊吧,感謝 ! ! !

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM