unity3d_角色与障碍物遮挡

来源:互联网 发布:mysql分组后组内排序 编辑:程序博客网 时间:2024/05/01 03:44

最近的项目有涉及到关于角色与障碍物的遮挡与显示问题:

个人能想到的解决方法有两种:

①从摄像机发射与角色连接射线,判断射线碰撞的go,将其材质改为半透明。

②shader


第一种方法:我有找到两篇相关的文章

1.雨松momo:http://www.xuanyusong.com/archives/1991

2.时间比较久,忘记出处了,不过是根据momo的文章改编的。

第二篇的代码:

using UnityEngine;using System.Collections;using System.Collections.Generic;public class ObjectOcclusion : MonoBehaviour {//观察目标public Transform Target;        //上次碰撞的物体private List<GameObject> lastColliderObject = new List<GameObject>();//本次碰撞到的物体private List<GameObject> colliderObject = new List<GameObject>();void LateUpdate(){//这里是计算射线的方向,从主角发射方向是射线机方向Vector3 aim = Target.position;//得到方向Vector3 ve = (Target.position - transform.position).normalized;float an = transform.eulerAngles.y;aim -= an * ve;//在场景视图中可以看到这条射线Debug.DrawLine(Target.position, aim, Color.red);RaycastHit[] hit;hit = Physics.RaycastAll(Target.position, aim, 100f);//起始位置、方向、距离//将colliderObject 中所有的值添加进 lastColliderObjectfor (int i = 0; i < colliderObject.Count; i++) lastColliderObject.Add(colliderObject[i]);colliderObject.Clear();//清空本次碰撞到的所有物体//获取碰撞到的所有物体for (int i = 0; i < hit.Length; i++){if(hit[i].collider.gameObject.tag != "Player"){//Debug.Log(hit[i].collider.gameObject.name);colliderObject.Add(hit[i].collider.gameObject);//设置当前物体材质透明度SetMaterialsColor(hit[i].collider.gameObject.renderer, 0.4f);}}//上次与本次对比,本次还存在的物体则赋值为nullfor (int i = 0; i < lastColliderObject.Count; i++)         {for (int j = 0; j < colliderObject.Count; j++) {if (colliderObject [j] != null) {if (lastColliderObject [i] == colliderObject [j]) {lastColliderObject [i] = null;break;}}}}//当值为null时则可判断当前物体还处于遮挡状态//值不为null时则可恢复默认状态(不透明)for (int i = 0; i < lastColliderObject.Count; i++)        {if (lastColliderObject [i] != null)SetMaterialsColor (lastColliderObject [i].renderer, 1f);}}//设置透明度private void SetMaterialsColor(Renderer _renderer, float Transpa){//获取当前物体材质球数量int materialsNumber = _renderer.sharedMaterials.Length;for (int i = 0; i < materialsNumber; i++) {//获取当前材质球颜色Color color = _renderer.materials[i].color;//设置透明度  取值范围:0~1;  0 = 完全透明color.a = Transpa;//置当前材质球颜色_renderer.materials[i].SetColor("_Color", color);//_renderer.materials[i].color = color;}}}
此脚本,要先设置go的材质为“Transport/Diffuse”,嫌麻烦的话,可以在代码中动态更换。


缺陷:当go比较多,角色移动过去会有很明显的闪烁现象。


第二种方法:写shader,这是我一直想干的事,苦于能力不够,一直未能解决。

直到momo新更新了片文章:http://www.xuanyusong.com/archives/3466

momo的这篇文章也是转载的,同时也有改动


shader代码:

Shader "Custom/PlayerDiffuse" {    Properties {        _NotVisibleColor ("NotVisibleColor (RGB)", Color) = (0.3,0.3,0.3,1)        _MainTex ("Base (RGB)", 2D) = "white" {}    }    SubShader {        Tags { "Queue" = "Geometry+500" "RenderType"="Opaque" }        LOD 200         Pass {            ZTest Greater            Lighting Off            ZWrite Off         //   Color [_NotVisibleColor]            Blend SrcAlpha OneMinusSrcAlpha            SetTexture [_MainTex] { ConstantColor [_NotVisibleColor] combine constant * texture }                    }         Pass {            ZTest LEqual            Material {                Diffuse (1,1,1,1)                Ambient (1,1,1,1)            }            Lighting Off            SetTexture [_MainTex] { combine texture }         }     }     FallBack "Diffuse"}
可以直接挂在角色上,可能会有违和感,只要稍稍改一下角色材质的透明度以及灰度值就好。


其实最初解决的办法是小伙伴想出来的:他有找一个雾化shader(笼罩整个场景),挂载2个main camera,一个用来渲染整个场景(包括角色),一个用来单独渲染角色。起初可以用,到后来不知为什么会出现bug,就是只显示渲染角色的camera的图像,没办法后面采用shader的方法来做。


差不多关于角色与障碍物的遮挡的显示就到这了!




0 0