Unity 3D模型展示之模型透明效果

1.透明效果实现思路

	简单点就是将模型的材质替换成透明材质。
	需要注意:
	1.指定范围内的模型进行透明化。
	2.一个模型会有多个材质,都需要进行透明化。
	3.还能将模型的材质恢复最初的效果。
	4.选中的模型及它的子对象不需要进行透明化。

带着以上问题,我们来看编写的脚本。

2.模型透明脚本

  • 记录原模型材质信息,能够恢复最初的材质。
 Dictionary<string, Material[]> dic = new Dictionary<string, Material[]>();
	定义字典变量存储模型名,以及材质信息。
  void Start()
    {
        foreach (var item in parentObj)
        {
            foreach (Transform child in item.GetComponentsInChildren<Transform>())
            {
                var temp = GetGameObjectPath(child);
                dic.Add(temp, child.GetComponent<Renderer>().materials);
            }
        }
    }
在start中进行信息收集。这里GetGameObjectPath是获取路径及名称,全名称的获取防止名称重复
配合字典的key值唯一特性。在完整脚本中会有代码。
  • 修改模型透明化方法。
    private void ModTransparent(Transform tran)
    {
        Material[] Mat = new Material[tran.GetComponent<Renderer>().materials.Length];
        for (int i = 0; i < Mat.Length; i++)
        {
            Mat[i] = transparentMaterial;
        }
        tran.GetComponent<Renderer>().materials = Mat;
    }
创建一个长度为模型材质数量的数组。
将透明材质赋值给此数组。
  • 恢复模型最初材质。
   private void RecoveryTransparent(Transform tran)
    {
           var name = GetGameObjectPath(tran);
            MatOld = dic[name];
            tran.GetComponent<Renderer>().materials = MatOld;
    }
根据名称查找字典存储的材质信息进行赋值。
  • 核心方法
public void TransparentOthers(string partName)
    {
        for (int i = 0; i < parentObj.Length; i++)
        {
            foreach (Transform child in parentObj[i].GetComponentsInChildren<Transform>())
            {
                if (partName == child.name)
                {
                    othersTransform = child.GetComponentsInChildren<Transform>();
                    continue;
                }
                int count = 0;
                if (othersTransform != null)
                {
                    foreach (var item in othersTransform)
                    {
                        var temp1 = GetGameObjectPath(item);
                        var temp2 = GetGameObjectPath(child);
                        if (temp1 == temp2)
                        {
                            count = 1;
                            break;
                        }
                    }
                }
                //改透明
                if (count == 0)
                {
                    ModTransparent(child);
                }
            }
        }
    }
选中的模型及它的子对象不需要进行透明化。
  • 完整脚本。
using System.Collections.Generic;
using UnityEngine;

public class TransparentSet : MonoBehaviour
{
    public static TransparentSet Instance;
    private void Awake()
    {
        Instance = this;
    }
    public Transform[] parentObj;
    public Material transparentMaterial;
    Material[] MatOld;
    Transform[] othersTransform;
    Dictionary<string, Material[]> dic = new Dictionary<string, Material[]>();
    // Start is called before the first frame update
    void Start()
    {
        foreach (var item in parentObj)
        {
            foreach (Transform child in item.GetComponentsInChildren<Transform>())
            {
                var temp = GetGameObjectPath(child);
                dic.Add(temp, child.GetComponent<Renderer>().materials);
            }
        }
    }

    public string GetGameObjectPath(Transform obj)
    {
        string path = "/" + obj.name;
        while (obj.transform.parent != null)
        {
            obj = obj.parent.gameObject.transform;
            path = "/" + obj.name + path;
        }
        return path;
    }
    private void ModTransparent(Transform tran)
    {
        Material[] Mat = new Material[tran.GetComponent<Renderer>().materials.Length];
        for (int i = 0; i < Mat.Length; i++)
        {
            Mat[i] = transparentMaterial;
        }
        tran.GetComponent<Renderer>().materials = Mat;
    }
    private void RecoveryTransparent(Transform tran)
    {
           var name = GetGameObjectPath(tran);
            MatOld = dic[name];
            tran.GetComponent<Renderer>().materials = MatOld;
    }
    public void TransparentOthers(string partName)
    {
        for (int i = 0; i < parentObj.Length; i++)
        {
            foreach (Transform child in parentObj[i].GetComponentsInChildren<Transform>())
            {
                if (partName == child.name)
                {
                    othersTransform = child.GetComponentsInChildren<Transform>();
                    continue;
                }
                int count = 0;
                if (othersTransform != null)
                {
                    foreach (var item in othersTransform)
                    {
                        var temp1 = GetGameObjectPath(item);
                        var temp2 = GetGameObjectPath(child);
                        if (temp1 == temp2)
                        {
                            count = 1;
                            break;
                        }
                    }
                }
                //改透明
                if (count == 0)
                {
                    ModTransparent(child);
                }
            }
        }
    }
    public void RecoveryTransparent()
    {
        for (int i = 0; i < parentObj.Length; i++)
        {

            foreach (Transform child in parentObj[i].GetComponentsInChildren<Transform>())
            {
                RecoveryTransparent(child);
            }
        }
    }
}

  • 透明化脚本的调用
sparentSet.Instance.TransparentOthers(mSwitchParts.ObjName);
在SwitchPart脚本中的OnMouseDown 增加以上代码。
  TransparentSet.Instance.RecoveryTransparent();
在SwitchPart脚本中的OnMouseOver增加以上代码。

Unity 3D模型展示之模型透明效果

  • 脚本使用
    Unity 3D模型展示之模型透明效果
    将脚本挂载到Switch模型上,设置变量parentObj也就是透明化的范围的父对象
    在选择透明材质。

3.最终效果

Unity 3D模型展示之模型透明效果

上一篇:Springboot mini - Solon详解(四)- Solon的事务传播机制


下一篇:C#中的扩展方法及用途