在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. Linux中使用python测试主机存活 Linux系统CentOS Linux release 7.3.1611 (Core) py版本Python 2.7.5

    下面是最初的情况 #/usr/bin/env python # -*- coding: utf-8 -*- import os import time import subprocess import ...

  2. python库pandas

    由于在机器学习中经常以矩阵的方式来表现数据,那么我们就需要一种数据结构来存储和处理矩阵.pandas库就是这样一个工具. 本文档是一个学习笔记,记录一些常用的命令,原文:http://www.cnbl ...

  3. python中import和from-import的区别

    . import导入模块的路径两种方式 # 将模块所在路径再程序中添加到sys.path列表中 import sys sys.path import导入模块按照sys.path顺序依次查找,“”代表当 ...

  4. web session 原理1

     原理 我们都知道,浏览器无状态的.浏览器是操作不了session的,浏览器能够做的只是传递cookie,每次都传递. 把当前主机下的,和当前请求相同域下的cookie 传递到服务器去,只要cooki ...

  5. Linux sed 流编辑器

    sed是stream editor的简称,也就是流编辑器.盗用一张图片解释原理 命令格式: SYNPPSIS: sed [OPTION]… {script-only-if-no-other-scrip ...

  6. Mysqli 数据库连接类

    <?php namespace Lib; // 数据库连接类 class DB { //私有的属性 private static $dbcon = false; private $host; p ...

  7. Django models模型(1)

    1)使用模型需要在INSTALLED_APPS中注册 2)模型字段(字段类型和字段选项) 1.字段类型 常用: CharField,TextField: 对应字符串对象 DateTimeField和D ...

  8. 用代码检查Windows程序的位数

    方法就是通过读取程序文件的头部来判断,具体代码如下: #include <stdio.h> #include <windows.h> int CrnGetImageFileMa ...

  9. 排序NB三人组

    排序NB三人组 快速排序,堆排序,归并排序 1.快速排序 方法其实很简单:分别从初始序列“6  1  2 7  9  3  4  5 10  8”两端开始“探测”.先从右往左找一个小于6的数,再从左往 ...

  10. 130. Surrounded Regions 卧槽!我半梦半醒之间做出来的。

    打开这个题,做了一半躺下了. 结果,怎么都睡不着.一会一个想法,忍不住爬起来提交,要么错误,要么超时. 按照常规思路,依次对每个点检测是否是闭包,再替换,超时.计算量太大了. 还能怎么做呢?没思路,关 ...