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增加以上代码。
- 脚本使用
将脚本挂载到Switch模型上,设置变量parentObj也就是透明化的范围的父对象
在选择透明材质。