遮挡透明若没有渐变实现方法:
1、透明中物体存在list中
2、每过一段时间(可以每帧,但是流畅性会降低)摄像机发送一条射线向玩家,out hitInfo
3、list与hitInfo比对,将在list中但是没有在hitInfo中的物体转变成不透明,list.remove;将在hitInfo中但是没有在list中转变成透明,list.add
若有渐变,实现比较麻烦一点,物体有两个状态:转变成透明过程中、转变成不透明过程中,添加两个list(InTransparent,outTransparent)对应两种状态,那么维护两个list即可:
1、未遮挡->遮挡,查看outTransparent,如果有该物体,从outTransparent移入InTransparent,outTransparent remove;如果没有添加新的加入InTransparent
2、遮挡->未遮挡,查看InTransparent,如果有该物体,从InTransparent移入outTransparent,InTransparent remove;如果没有添加新的加入outTransparent
摄像机CameraFollow.cs:
public class CameraFollow : MonoBehaviour
{ public static CameraFollow instance;
public Transform Player; public List<CameraMaskInfo> Mask;
public List<CameraMaskInfo> InTransparentList;
public List<CameraMaskInfo> OutTransparentList; RaycastHit[] hitInfo; void Awake()
{
instance = this;
}
void Start()
{
StartCoroutine(IEMask());
}
public void ClearMask()
{
Mask.Clear();
InTransparentList.Clear();
OutTransparentList.Clear();
} IEnumerator IEMask()
{
while (true)
{
hitInfo = Physics.CapsuleCastAll(FollowTarget.position + Vector3.up * 0.2f, FollowTarget.position - Vector3.up * 0.1f, 0.2f, (transform.position - FollowTarget.position).normalized, 100f, layerMask);
bool flag;
for (int i = Mask.Count - ; i >= ; i--)
{
flag = false;
for (int j = ; j < hitInfo.Length; j++)
{
if (Mask[i].GetObj() == hitInfo[j].collider.gameObject)
{
flag = true;
break;
}
}
if (!flag)
{
Mask[i].PutOutTransparent();
Mask.RemoveAt(i);
}
} for (int i = ; i < hitInfo.Length; i++)
{
flag = false;
for (int j = ; j < Mask.Count; j++)
{
if (hitInfo[i].collider.gameObject == Mask[j].GetObj())
{
flag = true;
break;
}
}
if (!flag)
{
CameraMaskInfo maskInfo = new CameraMaskInfo(hitInfo[i].collider.gameObject);
maskInfo.PutInTransparent();
Mask.Add(maskInfo);
}
}
}
yield return new WaitForSeconds(0.2f);
} void Update()
{
for (int i = InTransparentList.Count - ; i >= ; i--)
{
InTransparentList[i].Sub();
} for (int i = OutTransparentList.Count - ; i >= ; i--)
{
OutTransparentList[i].Add();
}
}
}
遮挡物体CameraMaskInfo.cs:
using UnityEngine;
using System.Collections; public class CameraMaskInfo
{ private GameObject obj;
private Shader[] preMaterialShader;
public bool isDestroy;
#region get
public GameObject GetObj()
{
return obj;
} public Shader[] GetpreMaterialShader()
{
return preMaterialShader;
}
#endregion public CameraMaskInfo(GameObject obj)
{
this.obj = obj;
} public void PutInTransparent()
{
int id = -;
for (int i = ; i < CameraFollow.instance.OutTransparentList.Count; i++)
{
if (CameraFollow.instance.OutTransparentList[i].GetObj() == obj)
{
id = i;
//如果在out里面有,那么说明该物体的shader已经被改变,只能从之前的获得
preMaterialShader = CameraFollow.instance.OutTransparentList[i].GetpreMaterialShader();
CameraFollow.instance.InTransparentList.Add(CameraFollow.instance.OutTransparentList[i]);
CameraFollow.instance.OutTransparentList.RemoveAt(i);
break;
}
}
if (id==-)
{
preMaterialShader = new Shader[obj.renderer.materials.Length];
for (int i = ; i < obj.renderer.materials.Length; i++)
{
preMaterialShader[i] = obj.renderer.materials[i].shader;
obj.renderer.materials[i].shader = Shader.Find("Transparent/Diffuse");
}
CameraFollow.instance.InTransparentList.Add(this);
}
} public void PutOutTransparent()
{
int id = -;
for (int i = ; i < CameraFollow.instance.InTransparentList.Count; i++)
{
if (CameraFollow.instance.InTransparentList[i].GetObj() == obj)
{
id = i;
CameraFollow.instance.OutTransparentList.Add(CameraFollow.instance.InTransparentList[i]);
CameraFollow.instance.InTransparentList.RemoveAt(i);
break;
}
}
if (id == -)
{
CameraFollow.instance.OutTransparentList.Add(this);
}
} public void Add()
{
for (int i = ; i < obj.renderer.materials.Length; i++)
{
obj.renderer.materials[i].color = new Color(obj.renderer.materials[i].color.r, obj.renderer.materials[i].color.g, obj.renderer.materials[i].color.b, obj.renderer.materials[i].color.a + Time.deltaTime * 2f);
}
if (obj.renderer.materials[].color.a >= 0.95f)
{
for (int i = ; i < obj.renderer.materials.Length; i++)
{
obj.renderer.materials[i].color = new Color(obj.renderer.materials[i].color.r, obj.renderer.materials[i].color.g, obj.renderer.materials[i].color.b, 1f);
}
SetPreShader();
CameraFollow.instance.OutTransparentList.Remove(this);
}
} public void Sub()
{
for (int i = ; i < obj.renderer.materials.Length; i++)
{
obj.renderer.materials[i].color = new Color(obj.renderer.materials[i].color.r, obj.renderer.materials[i].color.g, obj.renderer.materials[i].color.b, obj.renderer.materials[i].color.a - Time.deltaTime * 2f);
}
if (obj.renderer.materials[].color.a <= 0.3f)
{
CameraFollow.instance.InTransparentList.Remove(this);
}
} private void SetPreShader()
{
for (int i = ; i < obj.renderer.materials.Length; i++)
{
obj.renderer.materials[i].shader = preMaterialShader[i];
}
}
}
效果: