unity3d 摄像机跟随角色时被物体遮挡解决方案

参考文章:http://www.xuanyusong.com/archives/1991

在看此文章时请先看上面的参考文章

看完以上文章后,你也许会想人家都已经给出所有代码了,你还写个毛啊

别急,现在进入主题

在我的项目中,我采用的是物体遮挡作半透明处理,如果按照上述文章中的思路来写代码的话,那么结果就是当多个物体遮挡角色时,只有第一个物体会半透明,如图:

角色被墙和屋顶遮挡住了,但是可以清楚的看见左下角的墙呈半透明状态,而屋顶依旧不透明

为了解决这个问题,我们不采用上述文章中的 physics.Linecast,在这里我们需要用到 Physics.RaycastAll;使用方法详见圣典

ok,现在我们开始敲代码

首先 ,我们引入命名空间 System.Collections.Generic,然后在声明三个需要用到的变量

using System.Collections.Generic;//引入命名空间

public class MyCamera1 : MonoBehaviour
{
    //观察目标
    public Transform Target;

    //上次碰撞到的物体
    private List<GameObject> lastColliderObject;

    //本次碰撞到的物体
    private List<GameObject> colliderObject;
}

我们需要发射一条射线,这条射线从角色当前位置发射置摄像机的方向

 1         /*射线可以从头部起始*/
 2
 3         //这里是计算射线的方向,从主角发射方向是射线机方向
 4         Vector3 aim = Target.position;
 5         //得到方向
 6         Vector3 ve = (Target.position - transform.position).normalized;
 7         float an = transform.eulerAngles.y;
 8         aim -= an * ve;
 9
10         //在场景视图中可以看到这条射线
11         //Debug.DrawLine(target.position, aim, Color.red);
12
13         RaycastHit[] hit;
14         hit = Physics.RaycastAll(Target.position, aim, 100f);//起始位置、方向、距离

射线发送完毕后,我们获取发送射线时碰撞到的所有物体,并且添加进本次碰撞到的物体(colliderObject)变量中

因为我的地图、护栏碰撞(不可见)、地面碰撞(不可见)是三个模型,也就是说地图本身是没有任何碰撞的

所以当碰撞到的物体名为护栏或地面时,就不修改其透明度,因为他本身就不可见

这里我偷懒了,直接判断物体名称,可自行改为判断物体 tag

当视角旋转的时候,射线有时候会碰撞到角色,所以,我们获取 tag 判断是否碰撞的物体为角色

 1         //将 colliderObject 中所有的值添加进 lastColliderObject
 2         for (int i = 0; i < colliderObject.Count; i++)
 3             lastColliderObject.Add(colliderObject[i]);
 4
 5         colliderObject.Clear();//清空本次碰撞到的所有物体
 6         for (int i = 0; i < hit.Length; i++)//获取碰撞到的所有物体
 7         {
 8             if (hit[i].collider.gameObject.name != "Editable Poly 1"//护栏
 9                 && hit[i].collider.gameObject.name != "Editable Poly"//地面
10                 && hit[i].collider.gameObject.tag != "Player")//角色
11             {
12                 //Debug.Log(hit[i].collider.gameObject.name);
13                 colliderObject.Add(hit[i].collider.gameObject);
14                 SetMaterialsColor(hit[i].collider.gameObject.renderer, 0.4f);//置当前物体材质透明度
15             }
16         }

当获取到所碰撞到的所有物体后,我们要修改他的材质透明度,有些物体有很多材质,不知道怎么解决的请看我下面这个方法:

 1     /// 置物体所有材质球颜色 <summary>
 2     /// 置物体所有材质球颜色
 3     /// </summary>
 4     /// <param name="_renderer">材质</param>
 5     /// <param name="Transpa">透明度</param>
 6     private void SetMaterialsColor(Renderer _renderer, float Transpa)
 7     {
 8         //获取当前物体材质球数量
 9         int materialsNumber = _renderer.sharedMaterials.Length;
10         for (int i = 0; i < materialsNumber; i++)
11         {
12             //获取当前材质球颜色
13             Color color = _renderer.materials[i].color;
14
15             //设置透明度  取值范围:0~1;  0 = 完全透明
16             color.a = Transpa;
17
18             //置当前材质球颜色
19             _renderer.materials[i].SetColor("_Color", color);
20         }
21     }

如果本次碰撞到的物体存在于上个物体,那么则说明当前物体还处于遮挡角色状态,所以我们赋值为null

 1         //上次与本次对比,本次还存在的物体则赋值为null
 2         for (int i = 0; i < lastColliderObject.Count; i++)
 3         {
 4             for (int ii = 0; ii < colliderObject.Count; ii++)
 5             {
 6                 if (colliderObject[ii] != null)
 7                 {
 8                     if (lastColliderObject[i] == colliderObject[ii])
 9                     {
10                         lastColliderObject[i] = null;
11                         break;
12                     }
13                 }
14             }
15         }

还处于遮挡状态的物体已被赋值为null,那么剩下的物体就是没有处于遮挡状态的,所以我们要重置该物体材质为不透明

1 //当值为null时则可判断当前物体还处于遮挡状态
2         //值不为null时则可恢复默认状态(不透明)
3         for (int i = 0; i < lastColliderObject.Count; i++)
4         {
5             if (lastColliderObject[i] != null)
6                 SetMaterialsColor(lastColliderObject[i].renderer, 1f);//恢复上次物体材质透明度
7         }

好了,所有代码已完成,我们看一下运行结果

未遮挡时:

遮挡时:

怎么样,有木有感觉很酷炫呢,哈哈哈

最后,附上完整代码链接:http://pan.baidu.com/s/1gdGLwiv 密码:pbrd

原文链接:http://www.cnblogs.com/shenggege/p/4113316.html

时间: 2024-10-05 04:58:38

unity3d 摄像机跟随角色时被物体遮挡解决方案的相关文章

Unity3D摄像机跟随人物

这里的镜头主要是从人物的背后跟随的. 首先新建一个C#脚本,命名为MyFollow,然后把以下代码粘贴进去,保存: using UnityEngine; using System.Collections; public class MyFollow : MonoBehaviour { public float distanceAway = 5; // distance from the back of the craft public float distanceUp = 2; // dista

unity3d 角色头顶信息3D&amp;2D遮挡解决方案

先上效果图,只凭文字描述,脑补应该有些困难- - 如图:有三个角色(我们暂且从左到右叫它们A.B.C),一个2D UI(中间动作选择的框框),一个cube(右边的方块) cube挡住了角色C的头顶信息 2D UI挡住了角色和cube 共同点是只显示未被遮挡的部分,遮挡的部分不显示 相信大多数人在看我这篇文章之前已经看过雨松momo的<人物头顶名称与血条更新与绘制> 没看过的可以去看看:http://www.xuanyusong.com/archives/1032 如果直接使用雨松momo文章中

unity3d 角色头顶信息3D&amp;2D遮挡解决方案(二)

在阅读本文之前请先阅读上一篇文章:http://www.cnblogs.com/shenggege/p/4179012.html 本来一篇文章就可以说完了,但是上次只是实现了已知的一些功能 后来在实际运用中遇到了一个问题,请看图 3D场景嘛!近大远小! 当我把视角移动得很远时,头顶信息就变得很小了,小得我看不见它显示的是什么 而且如果有多个玩家的话,每个玩家都有头顶信息 当我离另外一个玩家很远时,那个玩家的头顶信息就看不见了 那么要头顶信息有何意义? 本文就解决这个问题,其实很简单的 下面是解决

Unity3d中第三人称摄像机跟随的实现

最简单的一种就是先设置好摄像机跟物体的相对距离, 在脚本里就可以由物体的位置,跟相对距离,就可以求出摄像机的位置, 用插值的方法可以让摄像机平滑跟随. 1 public class CamFollow1 : MonoBehaviour 2 { 3 4 private Vector3 offset; 5 public Transform player; 6 7 void Start() 8 { 9 offset = player.position - transform.position; 10

unity3d摄像机

主要来自unity3d reference,再加上一些自己的理解 一 概述 摄像头是用于将世界场景投影到屏幕的设备.可以在场景中放置不限数目的摄像机,它们可以设定成任意的渲染次序,渲染到屏幕上的任意地方. 摄 像机实质上是用于将游戏显示给玩家看,它们可以被定制,在上面写脚本或者挂载到其他物体上面以获得想象中的各种效果.对于一个猜谜的游戏,可能只需对游戏 的全部视图保持摄像机静止即可.对于第一人称的射击游戏,常会将摄像机挂载到玩家角色上面,将其放置在角色眼睛的高度.对于一个赛车游戏,可能会让摄像机

关于Unity3D中鼠标移动指定物体的解决方案

一.鼠标拾取物体的原理 在Unity3D当中,想要在观察面(Aspect)中拾取物体(有碰撞属性)的方法一般如下: 1.声明一个观察的摄像机.一个从摄像机原点出发的射线Ray以及一个用于检测碰撞的RaycastHit: 2.将射线Ray定义为从摄像机原点出发并且指向当前鼠标所在的坐标(屏幕坐标): 3.定义碰撞RaycastHit为射线Ray与有碰撞属性的物体的碰撞点. 具体代码实现如下(C#代码): using System.Collections; using System.Collecti

Unity移动开发(1):2d摄像机跟随

Unity从4.3开始,unity3d开始叫unity了,去掉后缀,因为4.3版本以后加入了强大的原生2d开发环境.对于原来熟悉3d开发的unity工程师而言,不需要太多时间去适应就能很好的过度到2d的开发中去.今天说下2d的摄像机跟随.因为是2d环境,所以我们考虑的轴向就少了一个z轴,我们只需要考虑x和y轴.因为是横版的,所以我们就锁定摄像机的x轴,这样就不会让相机跟着主角上串下跳导致相机的晃动(这样的效果就跟相机设置为自物体一样样了,体验不太好.)代码如下: 1.定义一个公有的transfo

Unity游戏开发第三人称摄像机跟随

在第三人称游戏开发中,因为我们的人物是会不断移动的,所以我们的相机需要保持合适的角度跟随我们的人物进行移动,最简单的一种实现方法是先在unity场景中将摄像机调整到合适的位置,然后将它放到我们的人物下面,让他成为人物的子物体,这样做也可以达到摄像机跟随的目的.如果对摄像机跟随的要求不高的话可以临时采用这种方法 为了实现第三人称摄像机跟随的功能,大部分情况先我们都是采用编写代码的方法来实现的.下面是本人实现的一种摄像机跟随的方法,仅供参考,实现的功能是按住键盘AD键可以让摄像机视野围绕人物左右移动

Unity 中简单的第三人称摄像机跟随

先说较为简单的一种: 一.将摄像机作为人物角色的子对象,设置好相对距离和偏移量即可,但这种方法弊端较多,一般不采用. 二. 设置好摄像机跟物体的相对距离,之后利用插值让摄像机平滑跟随. 原理:摄像机与player以向量(有大小,有方向)相连,这样就可以确定摄像机与player的相对距离了,这样人物走动,摄像机也会跟随移动. 将下列代码与camera绑定就可以实现第三人称摄像机跟随.代码: public class CameraFollow : MonoBehaviour { // 摄像机跟随的对