好久没有敲Blog该。感谢您的留言、注意、私人信件和其他支持,但我似乎没有办法继续自己曾经写了一篇博客系列,因为我在网上找到有关unity3D太少的内容,U3D相关的文章!。。

第三人称视角

第三人称视角是什么?非常easy,CS就是一种第一人称视角游戏,玩家没有办法看到自己的角色形象,仅仅能观察除开自己之外的游戏内容。第三人称视角那么就明显是可以看到玩家所控制的角色的一种视角。

并且大部分游戏的镜头不能固定不动,肯定是要尾随猪脚。能看到猪脚,可是保持一定的高度和距离,这种视角才是最好的。

U3D中使用镜头来呈现游戏画面,一般来说是Main Camera。

官方有一个使用JS书写的 第三人称镜头尾随脚本和猪脚控制脚本,可是鉴于U3D的js语法太过于诡异。于是我想自己去搞明确如何来写一个自己用起来爽的第三人称镜头尾随脚本。

==去机场接个人,回来再继续写==

OK。以下分步骤完毕这个脚本。关于加入猪脚的gameObject 以及加入CharacterController Component这里就不做解释了,前提是猪脚可以在场景中前后左右上下移动而且不会穿越障碍物然后我们继续往下写。

也就是我们的摄像机如今是固定视角,猪脚能够任意移动和跳跃,如图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemF5MTA5MzI3NDAy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

1.创建一个脚本文件CameraFollow.cs

2.接下来。分析我们最想要的效果:

a,摄像机保持和猪脚一定的高度差(y轴固定差值)和

b.距离差(x,z轴向量的合量相对固定);

c,面向猪脚的正前方

先完毕目的a:

//摄像机固定在猪脚上方10米高度
public float camera_height=10.0f;
//摄像机离猪脚大概10米的水平距离
public float camera_distance=10.0f; //摄像机和猪脚的transform属性
private Transform player;
private Transform camera;
// Use this for initialization
void Start () {
//初始化
player=GameObject.FindGameObjectWithTag("Player").transform;
camera = Camera.main.transform;
} // Update is called once per frame
void Update () {
//每一帧都改变摄像机的高度
camera.position = new Vector3 (player.position.x, player.position.y+ camera_height, player.position.z ); }

效果:

我们在脚本中将高度距离两个变量暴露为public,能够在Inspector中改动,先改一个大概惬意的高度

眼下我们看不到猪脚,原因是摄像机的位置是取的猪脚的X,Z 。仅仅是Y轴加上固定高度。

所以我们须要计算摄像机的X,Z坐标与猪脚的X,Z坐标是一个什么样的关系?

假设单纯的 取猪脚的X,Z坐标然后分别减去distance,是不行的,这样我们仅仅有在某一个方向才干正好在猪脚后方

改动update中的赋值语句为:

那么我们执行游戏,选择到mainCamera,改动他的Y轴旋转度,直到镜头正好时刻在猪脚后方。发现这个角度一直是45°:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemF5MTA5MzI3NDAy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

所以不难明确,当且仅当摄像机的Y轴偏离45°的时候,x,z各取地平面某一点的值,摄像机的位置在这个x,z坐标基础上减去一个同样的值。摄像机能够正好看到这个点在正中间。

这是为什么?我来画个图示意一下:

忽略掉摄像机的高度差。我们的猪脚在点O(α。0,α)

摄像机在O一撇(0,0,0)

要让摄像机正好看到猪脚在正中间且保持一定距离,那么本来摄像机的正前方是这个坐标系的Z轴正方向,如今改为朝射线O' O方向。那么偏离量非常明显因为是个正方形的对角线。(这是透视下的正方形),角度为45°。

问题来了,我们难道要一直保持45°去望着猪脚吗,别忘了我们的摄像机随时要旋转保持正对猪脚的。那么这个位置究竟该是多少呢?

我们 先把C完毕:随时保证面向猪脚的正前方:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemF5MTA5MzI3NDAy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

加入这两行代码之后。我们再看看问题出在哪儿:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemF5MTA5MzI3NDAy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

非常明显,摄像机的朝向是与猪脚的正前方朝向一致的,可是位置呢,当切仅当猪脚Y轴旋转度偏离Z轴正方向45°的时候。位置在猪脚正后方,小于45°偏左,大于45°偏右,180°+45°直接跑到猪脚正前面去了。

所以说,我们想要的情况是:

45°时,x 与z各减去 distance

180°+45°=225°时。x与z各加上distance

0°的时候,x不变,z-distance/sin45°  (为什么,由于实际上45°时候线段O'O的长度事实上不是distance而是distance/sin45°。看我画的那个图。勾股定理)

90°的时候,z不变,x-distance/sin45°

所以事实上我们这里的定义的distance參数名字和他代表的不一样,实际距离应该是distance/sin45°

所以不难归纳,我们以角度β为变量。得出x与β的函数关系为:

x-=distance*sinβ

z-=distance*cosβ

正好满足我们上面列的4个条件

因为我们代码中须要的三角函数參数是弧度而不是角度,所以这里把角度替换为弧度:

x-=distance*sin(β*π/180)

z-=distance*cos(β*π/180)

所以我们的代码应该改动为:

//看向猪脚
//camera.LookAt (player); //与猪脚的正前方为正前方(仅仅取Y轴的旋转度)
camera.eulerAngles =new Vector3(camera.eulerAngles.x,
player.eulerAngles.y,
camera.eulerAngles.z);
//获取当前的镜头的Y轴旋转度
float angle = camera.eulerAngles.y; //计算x轴的距离差:
float deltaX = camera_distance * Mathf.Sin(angle * Mathf.PI /180 );
float deltaZ = camera_distance * Mathf.Cos (angle * Mathf.PI / 180); //每一帧都改变摄像机的高度
camera.position = new Vector3 (player.position.x-deltaX,
player.position.y+ camera_height,
player.position.z-deltaZ);

这个lookAt已经不须要了,由于我们的镜头旋转到猪脚的正前方而且位置在他的正后方。那么我们镜头必定已经在看他了

最后的效果是不管猪脚如何走。我们的镜头都在完美地尾随:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemF5MTA5MzI3NDAy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

完整脚本代码(比官方的样例精简吧):

using UnityEngine;
using System.Collections; //加入脚本到component菜单
[AddComponentMenu ("CameraControl/Follow")]
public class CameraFollow : MonoBehaviour { //摄像机固定在猪脚上方10米高度
public float camera_height=10.0f;
//摄像机离猪脚大概10米的水平距离
public float camera_distance=10.0f; //摄像机和猪脚的transform属性
private Transform player;
private Transform camera;
// Use this for initialization
void Start () {
//初始化
player=GameObject.FindGameObjectWithTag("Player").transform;
camera = Camera.main.transform;
} // Update is called once per frame
void Update () { //看向猪脚
//camera.LookAt (player); //与猪脚的正前方为正前方(仅仅取Y轴的旋转度)
camera.eulerAngles =new Vector3(camera.eulerAngles.x,
player.eulerAngles.y,
camera.eulerAngles.z);
//获取当前的镜头的Y轴旋转度
float angle = camera.eulerAngles.y; //计算x轴的距离差:
float deltaX = camera_distance * Mathf.Sin(angle * Mathf.PI /180 );
float deltaZ = camera_distance * Mathf.Cos (angle * Mathf.PI / 180); //每一帧都改变摄像机的高度
camera.position = new Vector3 (player.position.x-deltaX,
player.position.y+ camera_height,
player.position.z-deltaZ); Debug.Log("angle:"+angle+",deltax:"+deltaX+",deltaZ:"+deltaZ); }
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

Unity3D第三人称摄像机控制脚本的更多相关文章

  1. Unity3D中的第三人称镜头的脚本控制

    原地址:http://blog.csdn.net/mobanchengshuang/article/details/27591271 好久没有敲Blog了,谢谢大家的留言.关注.私信等支持,但是我好像 ...

  2. Unity3D Player角色移动控制脚本

    1. 简介 在Unity3D中,有多种方式可以改变物体的坐标,实现移动的目的,其本质是每帧修改物体的position.之前写过类似的文章,这次增加了平时常用API的脚本,每个脚本均手打测试可用. 2. ...

  3. unity3d 第三人称视角的人物移动以及相机控制

    何谓第三人称?就像这样: 用wasd控制人物移动,同时保持在相机的中心.用鼠标右键与滚轮控制相机的角度和距离. 先说一下人物的移动: 首先给作为主角的单位加上 Charactor Controller ...

  4. Unity小知识---第三人称中设置摄像机的简单跟随

    第三人称中设置摄像机的简单跟随 private Transform player; private Vector3 offect; private float smooothing = 3f; //插 ...

  5. Unity 3D还原Scene场景、市面多数游戏视角高度自定义、第三人称视角分离功能:平移、拖动、看向中心等

    Unity视角的高度自定义 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享. ...

  6. Unity 3D第三人称视角、用途广泛限定角度(视角不能360度翻转)

    Unity第三人称相机视角控制 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分 ...

  7. 【Unity】第11章 第三人称角色控制器和碰撞体

    分类:Unity.C#.VS2015 创建日期:2016-05-02 一.简介 第三人称视角控制器涉及的相关概念有: 1.刚体(Rigidbody). 2.碰撞体(Collider).包括球体碰撞体( ...

  8. (转) [教程] Unity3D中角色的动画脚本的编写(一)

    ps: 这两天研究unity3d,对动画处理特别迷糊,不知FBX导入以后,接下来应该怎么操作,看到这篇文章,感觉非常好,讲解的很详细. 已有好些天没写什么了,今天想起来该写点东西了.这次我所介绍的内容 ...

  9. UE4中创建第一、第三人称角色,并进行角色间的切换

    在游戏中经常会出现第一人称和第三人称的视角切换场景,笔者在这里简单介绍如何进行这步操作. 1.创建角色 在内容浏览器中添加2个Character蓝图,分别命名为FirstPersonalCharact ...

随机推荐

  1. 【C++ Primer每天刷牙】一间 迭代器

    迭代器的介绍 概述 迭代器是一种检查容器内元素并遍历元素的数据类型. 迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或所有元素,每一个迭代器对象代表容器中的确定的地址.迭代 ...

  2. 离robots.txt启动网络爬虫之旅

    要成为一个网络爬虫或搜索引擎(在这里,共同蜘蛛)它不会陌生,在搜索引擎爬虫的第一个文件或者访问该网站上浏览robots.txt该.robots.txt文件讲述了蜘蛛server哪些文件要观看正在. 当 ...

  3. C语言的这些事情有关内存

    C语言的程序内存布局,从高到低依次为:栈区.堆区.未初始化数据区.初始化数据区.代码区. 一.栈区 由编译器自己主动管理,无需程序猿手工控制.存放函数的參数值.局部变量的值等.栈区内容从高地址到低地址 ...

  4. Android-采用Matrix对Bitmap加工

    1.Android正在使用Matrix放.旋转.平移.斜切等变换的. Matrix是一个3*3的矩阵,其值相应例如以下: 以下给出详细坐标相应变形的属性|scaleX, skewX, translat ...

  5. Maven+struts2+spring4+hibernate4的环境搭建

    搭建Maven+struts2+spring4+hibernate4其实并不难!但开始弄的时候还是费了我好大的力气,老是出现这样那样的错误!好了,废话不多说,开始搭建开发环境. 一.Myeclipse ...

  6. Maven学习笔记(四):协调和依赖

    Maven协调具体的解释:      Maven定义了这样一组规则:世界上不论什么一个构件都能够使用Maven坐标唯一标识.Maven坐标的元素包含groupId.artifactId.version ...

  7. hibernate中使用sql语句进行表链接查询,对结果集的遍历方法

    今天做了一个在hibernate中使用sql语句进行表链接查询的功能,得到的属性是来自两个表中的字段.下面对结果集遍历的方法进行记录. sql语句不写了.部分代码如下: List<Course_ ...

  8. Windows移动开发(一)——登堂入室

    開始本博客之前先分享一个自己的好消息吧,2014年3月31日起,正式就职于北京****集团Win8project师.主要负责将IOS和Android应用移植到Win8.1平板上,目标客户是银行,闲话不 ...

  9. C在宏定义中使用的语言可变参数

    于C标准库的语言,printf.scanf.sscanf.sprintf.sscanf入输出函数,參数都是可变的.在调试程序时.我们可能希望定义一个參数可变的输出函数来记录日志,那么用可变參数的宏是一 ...

  10. android 实现真正意义上的服务及源代码下载

    android APP后台服务和长期server长期互动,保证实时数据,这个小项目主要实施app退出后仍然能够执行服务. 使用该系统的Intent.ACTION_TIME_TICK现,这个系统的广播每 ...