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

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

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

别急,现在进入主题

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

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

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

ok,现在我们开始敲代码

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

  1. using System.Collections.Generic;//引入命名空间
  2.  
  3. public class MyCamera1 : MonoBehaviour
  4. {
  5. //观察目标
  6. public Transform Target;
  7.  
  8. //上次碰撞到的物体
  9. private List<GameObject> lastColliderObject;
  10.  
  11. //本次碰撞到的物体
  12. private List<GameObject> colliderObject;
  13. }

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

  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 = ; i < colliderObject.Count; i++)
  3. lastColliderObject.Add(colliderObject[i]);
  4.  
  5. colliderObject.Clear();//清空本次碰撞到的所有物体
  6. for (int i = ; 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 = ; 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 = ; i < lastColliderObject.Count; i++)
  3. {
  4. for (int ii = ; 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 = ; 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

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

  1. unity3d 角色头顶信息3D&2D遮挡解决方案(一)

    先上效果图,只凭文字描述,脑补应该有些困难- - 如图:有三个角色(我们暂且从左到右叫它们A.B.C),一个2D UI(中间动作选择的框框),一个cube(右边的方块) cube挡住了角色C的头顶信息 ...

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

    在阅读本文之前请先阅读上一篇文章:http://www.cnblogs.com/shenggege/p/4179012.html 本来一篇文章就可以说完了,但是上次只是实现了已知的一些功能 后来在实际 ...

  3. Unity3D中的高级摄像机跟随

    在Unity3D中,先调整MainCamera在场景中的位置,然后把脚本挂到MainCamera上,摄像机跟随分为简单的摄像机跟随和高级摄像机跟随. 简单摄像机跟随: public class Cam ...

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

    一.鼠标拾取物体的原理 在Unity3D当中,想要在观察面(Aspect)中拾取物体(有碰撞属性)的方法一般如下: 1.声明一个观察的摄像机.一个从摄像机原点出发的射线Ray以及一个用于检测碰撞的Ra ...

  5. unity3d 摄像机抖动效果 CameraShake

    unity3d 摄像机抖动效果 ,利用脚本直接控制:当然也可以选择使用dotween插件,但到不至于为了使用仅一个功能,就导入了一个插件: 脚本示例: using UnityEngine; using ...

  6. 关于Unity中的小案例之运动的小船以及摄像机跟随技术(专题五)

    实例步骤 1.创建Unity项目和文件目录,保存场景 场景搭建 2.导入美术做好的资源包(第68) a: 导入地形资源包terrain.unitypackage,把里面的Map/Prefabs/Ter ...

  7. 2D游戏摄像机跟随不出界

    做2D游戏的时候碰上摄像机要跟随人物时要防止摄像机看到界面外的黑幕,直接上代码. using System.Collections; using System.Collections.Generic; ...

  8. Unity3D 相机跟随主角移动

    这里给主相机绑定一个脚本. 脚本写为: using UnityEngine; using System.Collections; public class camerafollow : MonoBeh ...

  9. unity3d 通过添加rigidBody来指明物体是动态的,以避免cache开销

    unity3d 通过添加rigidBody来指明物体是动态的,以避免cache开销. 如果不添加rigidBody,则unity会认为它是静态的,会对物理计算进行cache,但如果此物体实际上tran ...

随机推荐

  1. HDU 1045 Fire Net 【连通块的压缩 二分图匹配】

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)    ...

  2. 宠物商城后台管理系统(springMVC+Mybatis+数据库)

    mysql数据库 create database swager; use swager; #类别 create table Category( id int primary key auto_incr ...

  3. c语言描述的顺序栈实现

    #include<stdio.h> #include<stdlib.h> #define initsize 100 #define ok 1 #define error 0 t ...

  4. center os 创建用户、设置密码、修改用户、删除用户命令

    参考:https://www.linuxidc.com/Linux/2017-06/144916.htm useradd testuser  创建用户testuserpasswd testuser  ...

  5. 并发编程之多线程基础-join方法及优先级(五)

    join()方法作用 当在主线程当中执行到t1.join()方法时,就认为主线程应该把执行权让给t1 优先级 现代操作系统基本采用时分的形式调度运行的线程,线程分配得到的时间片的多少决定了线程使用处理 ...

  6. 配置隐私协议 - iOS

    根据苹果隐私协议新规的推出,要求所有应用包含隐私保护协议,故为此在 App 中添加了如下隐私协议模块. 首次安装 App 的情况下默认调用隐私协议模块展示相关信息一次,当用户点击同意按钮后,从此不再执 ...

  7. 访问本地方站出现EOF的分析和解决

    每天早晨打开电脑运行本地项目的时候,有时候浏览器上会出现EOF 之前都都能正常访问,所以我猜想本地的项目本身肯定是没有问题的. Google了下,发现有人说是代理的问题,于是关闭代理试过后,发现可以访 ...

  8. Linux实战教学笔记

    Linux实战教学笔记01:计算机硬件组成与基本原理 Linux实战教学笔记02:计算机系统硬件核心知识 Linux实战教学笔记03:操作系统发展历程及系统版本选择 Linux实战教学笔记04:Lin ...

  9. Docker(三):部署软件

    Docker的镜像文件可以在镜像仓库中进行搜索. 部署软件目录导航: 常用命令 部署 Tomcat 部署 MySQL 部署 Oracle 常用命令 docker的常用命令如下: docker -v , ...

  10. 在Liunx上搭建FTP并配置用户权限

    伴随着.Net Core的开源,公司前几天上了新的Liunx服务器,我在前几篇文章中介绍了如何搭建环境以及部署.Net Core应用. 然后,今天客户和我说想自己给网站做推广,需要用FTP链接我们的服 ...