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

  简单摄像机跟随:

public class CameraFollow:MonoBehaviour()
{
//设置摄像机跟随速度
private float moveSpeed = 3f;
  //设置摄像机旋转速度
  private float turnSpeed = 10f;
//设置摄像机跟随的物体
private Transform target;
//定义方向向量
private Vector3 dir;
void Awake(){
//获取物体
target = GameObject.FindWithTag(Tags.Player).transform;
}
void Start(){
//获取方向向量
dir = transform.position - target.position;
}
void Update(){
//跟随目标
transform.position = Vector3.Lerp(transform.position, target.position+dir, moveSpeed * Time.deltaTime);
     //摄像机旋转
     transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(dir), turnSpeed * Time.deltaTime);
}
}
  在摄像机的简单跟随中,应用的场景中如果有一些障碍物,target在障碍物的后面会在游戏视图中看不到target,因此在大多数的场景中不适用。
高级摄像机跟随:在跟随的目标移动到障碍物后面的时候,调整摄像机的位置,达到看到目标的目的;原理:当target走到障碍物后面,用RaycastHit射线检测摄像机照到的物体是否是target,如果不是,设置档位,依次慢慢移动摄像机,直到照到target为止,所以可以在设定档位的时候,最后一个档位为target的正上方;当target移动到障碍物外面的时候,还原为以前的视角。
  高级摄像机跟随代码如下:
public class Camera : MonoBehaviour{
//设置摄像机的移动速度
private float moveSpeed = 3f;
//设置摄像机的旋转速度
private float turnSpeed = 10f;
//摄像机跟随目标
private Transform target;
//方向向量
private Vector3 dir;
//设置档位
private int gears = 5;
//射线碰撞检测器
privatr RaycastHit hit;
void Awake(){
//照到摄像机跟随目标
target = GameObject.FindWithTag(Tags.Player).transform;
}
void Start(){
dir = transform.position - target.position;
}
void Update(){
//起始坐标
Vector3 beginPos = target.position + dir;
//摄像机的投影向量
Vector3 projectDir = Vector3 Project(dir, Vector3.up);
//计算头顶摄像机与target之间的距离
float distance = projectDir.mignitude;
//target头顶坐标
Vector3 endPos = target.position + Vector3.up * distance;
//所有档位
Vector3[] allPos = new Vector3[gears];
//起点
allPos[0] = beginPos;
//终点
allPos[allPos.Length - 1] = endPos;
//填充中间点
for(int i = 1; i < allPos.Length - 1; i++){
allPos[i] = Vector3.Lerp(beginPos, endPos, i/(gears - 1f));
}
//默认结果点为起点
Vector3 resultPos = beginPos;
//遍历所有点
for(int i=0; i < allPos.Length - 1; i++){
if(CanSeeTarget(allPos[i])){
resultPos = allPos[i];
break;
}
}
//摄像机移动
transform.position = Vector3.Lerp(transform.position, resultPos + dir, moveSpeed * Time.deltaTime);
//获取方向向量
Vector3 lookDir = target.position - resultPos;
//摄像机旋转
    transform.rotation=Quaternion.Lerp(transform.rotation,Quaternion.LookRotation(lookDir), turnSpeed * Time.deltaTime);
//将欧拉角Y置零
transform.eulerAngles = new Vector3(transform.eulerAngles.x, 0, transform.eulerAngles.z);
}
//能否看到玩家
void CanSeeTarget(Vector3 pos){
//发射射线(起点,方向向量,射到的物体)
if(Physics.Raycast( pos, target.position - pos ,out hit)){
//能否看到玩家
if(hit.collider.CompareTag(Tags.Player)){
return true;
}
}
return false;
}
}

  

Unity3D中的高级摄像机跟随的更多相关文章

  1. Unity3d中使用摄像机制作实时显示小地图

    Unity3d中使用摄像机制作实时显示小地图,以之前的tank为例.开始制作之前场景中物体如图. 开始制作,步骤1:新建一个camera及一个plane.对齐位置,将camera改名为camera_U ...

  2. Unity3D中的shader基础知识

    1.Unity中配备了强大的阴影和材料的语言工具称为ShaderLab,以程式语言来看,它类似于CgFX和Direct3D的效果框架语法,它描述了材质所必须要的一切咨询,而不仅仅局限于平面顶点/像素着 ...

  3. Unity3D中Mathf数学运算函数总结

    引入: 看到一个案例注意到函数Mathf.SmoothDamp的使用,游戏中用于做相机的缓冲跟踪和boss直升机跟踪士兵.该函数是Unity3D中Mathf数学运算函数中的一个.一些游戏使用了smoo ...

  4. Unity3D中可重载虚函数的总结

    重载虚函数:Unity3D中所有控制脚本的基类MonoBehaviour有一些虚函数用于绘制中事件的回调,也可以直接理解为事件函数,例如大家都很清楚的Start,Update等函数,以下做个总结. A ...

  5. Unity3D中C#和js方法相互调用

    通过查找资料,Unity3D中C#和js要相互调用彼此的方法,js文件必须放在"Standard Assets". "Pro Standard Assets" ...

  6. 【转】Unity3D中Layers和LayerMask解析

    http://blog.csdn.net/yupu56/article/details/50441151 Unity中是用int32来表示32个Layer层.int32表示二进制一共有32位(0-31 ...

  7. unity3d中的Viewport

    Camera属性中有个Viewport Rect,如下图: X.Y为(0, 0)代表左下角,(1, 1)代表右上角:W和H分别是Viewport的宽(Width)和高(Height),摄像机的Aspe ...

  8. Unity3D中事件函数的运行顺序

    Unity3D中脚本的生命周期是依照预先定义好的事件函数的运行流程来演化的,详细流程例如以下: Editor模式下Reset: 当脚本第一次被挂到GameObject上或用户点击Resetbutton ...

  9. Unity3D中的Coroutine详解

    Unity中的coroutine是通过yield expression;来实现的.官方脚本中到处会看到这样的代码. 疑问: yield是什么? Coroutine是什么? unity的coroutin ...

随机推荐

  1. Robot Operating System (ROS)学习笔记4---语音控制

    搭建环境:XMWare  Ubuntu14.04  ROS(indigo) 转载自古月居  转载连接:http://www.guyuehome.com/260 一.语音识别包 1.安装         ...

  2. 【3-20】html 基本知识/表格/超链接

    一.HTML (一).HTML定义 HTML:是指超文本标记语言,用浏览器打开的文件 超文本标记语言:是指页面内包含文本.图片.视频.音频等元素的计算机编程语言 (二).基本格式: <html& ...

  3. Mybatis学习2传统dao开发

    传统dao开发 在mybati基础上 dao和daoimpl 1.工厂工具类 获得SqlSessionFactory SqlSessionFactoryUtil.java package util; ...

  4. 1. 报错:1130-host ... is not allowed to connect to this MySql server 开放mysql远程连接 不使用localhost

    在服务器上打开mysql命令行,依次执行下面这两句: GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRA ...

  5. asp.net在配置文件里设置多种编码方式的研究

    我们在做asp.net的程序时,在根目录下肯定会有一个web.config的文件, 有点开发经验的可能都知道,它是配置程序的全局信息的地方, 当然了,也可以在这里做更多的事情,下面我们来研究一下 ,如 ...

  6. vue父子组件嵌套的时候遇到 - Component template should contain exactly one root element. If you are using v-i

    转自:https://blog.csdn.net/yangyiboshigou/article/details/72084619

  7. 深度学习原理与框架-Tensorflow卷积神经网络-神经网络mnist分类

    使用tensorflow构造神经网络用来进行mnist数据集的分类 相比与上一节讲到的逻辑回归,神经网络比逻辑回归多了隐藏层,同时在每一个线性变化后添加了relu作为激活函数, 神经网络使用的损失值为 ...

  8. day38-常见第三方模块

    1.requests模块 2.psutil模块 3.xlrd模块 4.xlwt模块 5.Paramiko模块

  9. JDK1.8 LocalDateTime 时间类与字符互转

    public static void main(String[] args) { DateTimeFormatter dateTimeFormatter=DateTimeFormatter.ofPat ...

  10. 分布式存储Seaweedfs源码分析

    基于源码版本号 0.67 , [Seaweedfs以前旧版叫Weedfs]. Seaweedfs 是一个非常优秀的由 golang 开发的分布式存储开源项目, 虽然在我刚开始关注的时候它在 githu ...