unity3d摄像机跟随 怎么让相机跟随人物动

Unity 相机围绕物体指定观察角度和位置
问题:相机始终围绕着O观察,现在从A坐标和视角 运动旋转 到B坐标和视角。。
条件:abcd这个矩形盒差不多是物体O的顶视图尺寸,A点箭头是相机所在的起点和角度,B点为目标点需要观察的角度。
直接直线移动相机并按照AB夹角的差去移动和扭转相机的话 镜头很容易翻转!相机不可能总是在关注O对象!难受死了!
我能想到的最优解决办法:
水平围绕+position插值、angle插值!插值时使用Lerp函数,而非直接递增角度、递增位置!
我之所以最后这么&愉快&的决定实在是由于数学捉急,除非会构造一条这样优美的曲线!
But,实际A到O的具体和B到O的具体相等的情况太特殊了,更多时候,OAB只是一条普通的任意曲线!我甚至查了贝塞尔曲线相关的东西,但是发现起讫点AB虽然确定了,但如何调整这条弧的弧度却成了问题。最终我的处理方案近乎于这样的曲线:(图中荧光黄的部分!)
但是作为补充,为什么我要扭曲的找到这条路径去移动相机,而不直接用Slerp球形插值的函数从头到尾的移动旋转呢?Slerp函数官方手册给的那个例子有点醉,我们普通的执行一下Vector3.SLerp(startposition, endstartposition, Time.deltaTime),就会发现直接起点到终点弧形插值的话,轨迹点始终在起点终点共面的一个球面上,轨迹的扭曲可能不比Lerp好到哪里去,除非你会计算调整传入的参数,找到自己想要的优美曲线,因此这个方法由于不够直观也被我pass了。
其实最终这条曲线,即图中荧光黄的部分(有事可能是左上的那条路径),也是比较接近一条圆弧的。只要&MOB或&NOB足够小的话(只要大于一次RotateAround时的角度即可作为阈值)
最后附上处理过程(假定实际中&NAO &&MAO):
1.第一点也是这个问题存在的前提条件!只有镜头A到B过程会穿过O对象时才需要这么复杂的路径,如果没有穿过B,普通的直线运动插值就OK了。因此首先需要检测相机出发到目标点B是否会穿插O对象。
由于Physics.Raycast()所检测的对象要包含Collider及子类型的,我给O加个BoxCollder组件包围O对象。方向direction=b.position-a.
然后涉嫌检测到碰撞了O的话继续2步骤,否则直接走步骤4线性插值完毕。
2. 计算A沿圆周运动的终点M或N,&NAO &&MAO的情况下,目标点应该是N,表示A沿移动到离B的差距 即 NOB夹角小于一定阈值如20&时,即可停止圆周运动。
目标点N的角度即为a.angle+&BOA-y轴20&,这个视角是俯视的话,即为A移动到和B角差距的Y小于20&时即可。
3. 使得相机从A点平滑移动旋转到N点:
具体是转到M点还是N点?这个取决于A沿圆弧触发的时候,去那个点转的角度更小一点!不然相机可能要几乎转一周去想要的终点啊啊。
我在处理走弧OAM还是弧OAN的时候,这时只要直接计算向量BO和向量OA的夹角,结果小于180&的,从左上旋转 方向Vector3.up,否则从右上旋转-Vector3.up.
用沿圆周围看着O绕旋转运动的函数camera.RotateAround(o.transform.position,Vector3.up,Time.deltaTime);
4.从N点插值计算移动并旋转到B点。期间使用围绕着中心点o!
我用了Lerp线性插值计算:
camera.transform.position=Vector3.Lerp(camera.transform.position, b.transfrom.position,delta);
camera.transform.rotation=Quaternion.Lerp(camera.transform.rotation,Quaternion.Euler(b.transfrom.angle),delta);
最终,虽然线性插值表示N到B是直线移动过去的,但由于相机一直观察着o且距离较小 ,这个近似误差也不会感觉太明显,还能接受的范围。扫一扫,访问微社区
后使用快捷导航没有帐号?
签到成功!您今天第{todayrank}个签到,签到排名竞争激烈,记得每天都来签到哦!已连续签到:{constant}天,累计签到:{days}天
当前位置: &
_____________________________________________________________________________________________________________
问答求助版块规则:
  1、问题尽量描述清楚
& && &2、代码要放在代码块里
& && &3、附件最好放到云盘,然后把链接放到TXT文档里,上传TXT文档。【最好没有附件,你懂得】
& && &4、本版块回复不得无意义,如:顶、呵呵、不错......以及擦边!【真的会扣分的哦】严重者,封IP!
& && &5、问题得到解决,请选择最佳答案。
& && &6、若问题是你自己解决了,可以联系管理员,返还蛮牛币,写下你的答案,另有蛮牛币奖赏。
_____________________________________________________________________________________________________________
查看: 772|回复: 9
怎样让角色的前进方向与相机的面向保持一致?
本帖为抢楼帖,欢迎抢楼!&
2120/150排名<font color="#FF昨日变化6主题帖子积分
初来乍到, 积分 120, 距离下一级还需 30 积分
初来乍到, 积分 120, 距离下一级还需 30 积分
在线时间20 小时
WASD控制前后左右移动,虚拟摇杆式的,带旋转方向。
鼠标可控制相机、或者角色的旋转。
那么来了,当角色旋转之后怎样让WASD控制的移动和旋转后的朝向保持一致呢?
求大神给思路……最好能直接给脚本,蟹蟹
每日推荐:
118/50排名<font color="#FF昨日变化59主题帖子积分
注册看看, 积分 18, 距离下一级还需 32 积分
注册看看, 积分 18, 距离下一级还需 32 积分
在线时间9 小时
我個人的寫法是抓Camera的y值
宣告一個camera類別是GameObject
var Angley = camera.eulerAngles.y;
再讓需要時角色的rotation.y = Angley
個人是設定在移動時
if ((Mathf.Abs(Input.GetAxis(&Vertical&)) & 0) || (Mathf.Abs(Input.GetAxis(&Horizontal&)) & 0)){
& & & && &&&transform.rotation=Quaternion.Euler(0,Angley,0);
& & & && &&&}
給你參考一下
每日推荐:
61116/1500排名<font color="#FF昨日变化主题帖子积分
蛮牛粉丝, 积分 1116, 距离下一级还需 384 积分
蛮牛粉丝, 积分 1116, 距离下一级还需 384 积分
蛮牛币2126
在线时间320 小时
transform.translate(new vector3(x,y,z),Space.Self); 即可,意思就是朝自身坐标轴向移动,而不是世界坐标轴向,
每日推荐:
61472/1500排名<font color="#FF昨日变化1主题帖子积分
蛮牛粉丝, 积分 1472, 距离下一级还需 28 积分
蛮牛粉丝, 积分 1472, 距离下一级还需 28 积分
蛮牛币4659
在线时间1136 小时
自带的角色控制器里有脚本把,可以看看。
每日推荐:
3216/300排名<font color="#FF昨日变化5主题帖子积分
偶尔光临, 积分 216, 距离下一级还需 84 积分
偶尔光临, 积分 216, 距离下一级还需 84 积分
在线时间95 小时
用Transform.TransformDirection() 把角色在物体坐标系中的朝向(Vector.forward)转换成世界坐标系中的方向,按这个方向来移动。
参考API /ScriptReference/Transform.TransformDirection.html
每日推荐:
5942/1000排名<font color="#FF昨日变化1主题帖子积分
熟悉之中, 积分 942, 距离下一级还需 58 积分
熟悉之中, 积分 942, 距离下一级还需 58 积分
蛮牛币1168
在线时间258 小时
clipboard.png (22.2 KB, 下载次数: 3)
11:40 上传
这样就可以了摄像机会跟着人物一起转向的!
每日推荐:
12排名<font color="#FF昨日变化主题帖子积分
蛮牛币6994
在线时间1232 小时
楼上正解,注释也详细。
每日推荐:
3265/300排名<font color="#FF昨日变化5主题帖子积分
偶尔光临, 积分 265, 距离下一级还需 35 积分
偶尔光临, 积分 265, 距离下一级还需 35 积分
在线时间161 小时
支持一下。。。。。不清楚
每日推荐:
2120/150排名<font color="#FF昨日变化6主题帖子积分
初来乍到, 积分 120, 距离下一级还需 30 积分
初来乍到, 积分 120, 距离下一级还需 30 积分
在线时间20 小时
我個人的寫法是抓Camera的y值
宣告一個camera類別是GameObject
var Angley = camera.eulerAngles.y;
你的方法有用呢。不过试了下,如果角色移动不带四面转向基本是没问题的,但是如果加上转向(比如D键角色向右转,然后向右移动)就又不好了- -& &一心想要写这种奇怪的角色控制器TAT
每日推荐:
2120/150排名<font color="#FF昨日变化6主题帖子积分
初来乍到, 积分 120, 距离下一级还需 30 积分
初来乍到, 积分 120, 距离下一级还需 30 积分
在线时间20 小时
我個人的寫法是抓Camera的y值
宣告一個camera類別是GameObject
var Angley = camera.eulerAngles.y;
啊突然就解决了~谢谢小伙伴
每日推荐:
连续签到30天
认证开发者
经过游戏蛮牛认证的独立开发者& & & 游戏中,我们经常会有这样的操作,点击场景中某个位置,角色自动移动到那个位置,同时角色一直是朝向那个位置移动的,而且相机也会一直跟着角色移动。有些游戏,鼠标滑动屏幕,相机就会围绕角色旋转。
看似很简单的操作,那么到底是怎么实现的呢?
我们把上述操作分解为以下几个步骤
角色的移动
1. 移动到下一个路点,线性插值、
2. 角色朝向,一直面朝下一个路点
相机跟随角色
1. 相机俯视角度,决定相机的高度
2. 相机跟随距离,前向距离或者直线距离(就是三角形的水平边长或者斜边长)
3. 相机一直看角色的后背(Y轴旋转角度和角色一致)
4. 相机围绕角色旋转
先来看效果,请原谅我未注册屏幕录像orz
  包括位移和方向,就是移动角色的同时角色一直要朝向移动的方向。
左边的图,角色从A移动到B,朝向却一直是向前方的,明显不符合跑动的显示逻辑。正确的表现是右图所展示那样,角色面朝移动方向。
那么我们要怎么做才能实现这个效果呢?位移很简单,A到B的坐标插值。
其次是旋转角色,Unity提供了一个方法Quaternion.LookRotation。关于这个方法,官方的解释如下:
.LookRotation 注视旋转
static function LookRotation (forward : Vector3, upwards : Vector3 = Vector3.up) : Quaternion
Description描述
Creates a rotation that looks along forward with the the head upwards along upwards
创建一个旋转,沿着forward(z轴)并且头部沿着upwards(y轴)的约束注视。也就是建立一个旋转,使z轴朝向view
y轴朝向up。
Logs an error if the forward direction is zero.
如果forward方向是0,记录一个错误。
光看描述,是不是比较难理解。网上对这个方法的解释也挺多的,但是各说纷纭,没个简单明了的说法,更容易误导人。
我们知道向量,包含大小和方向。大小很容易得到,那么方向怎么获得呢?常规来说,可以通过把向量分解为x、y、z三个分量,然后通过三角函数依次求得个分量的夹角。
Unity提供了更简单的方法,就是Quaternion.LookRotation,这个方法就是获得传入向量的方向,即旋转值,是个四元数。
代码实际上很简单,就几行。主要是要理解为什么
<span style="color: #
//计算当前位置到下一个坐标点的向量
<span style="color: #
var vector = (posB - posA).
<span style="color: #
//取得向量的方向
<span style="color: #
var rotation = Quaternion.LookRotation(vector).eulerA
<span style="color: #
//将物体旋转到指向下一个坐标点的方向
<span style="color: #
transform.rotation = Quaternion.Euler(<span style="color: #, rotation.y, <span style="color: #);
<span style="color: #
//设置物体的坐标
<span style="color: #
transform.position = posB;
想想为什么Quaternion.Euler(0, rotation.y, 0)这里x和z方向都是填的0?
因为角色的朝向是根据偏转角Yaw,也就是Y轴决定的,x和z轴是没有发生偏转的,倘若改变x轴z轴旋转值,就会发现角色会有俯仰、翻滚的效果。
相机跟随角色
好了,角色的朝向解决了。那么,如果我要让相机一直跟着角色走,同时相机一直看到角色的后背,也就是角色旋转时,相机要跟着转动,同时保持固定距离,该如何实现?
我们先计算相机的位置,然后在旋转相机朝向角色的后背。
1. 计算相机的旋转值,这里需要指定相机的俯仰角Pitch的值,假定是30度,可以根据具体情况调节
//相机的俯仰角和偏航角,Y方向偏航和目标对象一致
Quaternion ro = Quaternion.Euler(Pitch, transform.rotation.eulerAngles.y, <span style="color: #);
2. 计算指定长度Distance的向量,这个向量是与世界坐标z方向平行
var vector = Vector3.forward * Distance;
3. 用上面的相机旋转值左乘第二步得到的向量,改变这个向量的方向( 四元数左乘向量,改变向量的方向)
= ro * vector;
4. 用目标位置减去vector,得到指向目标位置的坐标点,也就是相机的最终位置。(为什么这样就得到位置了,回去看看向量的知识吧)
var pos = transform.position -&
5. 最后,将旋转值和坐标赋值给相机,相机就完成了跟随效果, 是不是很简单
CameraGo.transform.position =
CameraGo.transform.rotation =
<span style="color: # //相机的俯仰角和偏航角,Y方向偏航和目标对象一致
<span style="color: # Quaternion ro = Quaternion.Euler(Pitch, transform.rotation.eulerAngles.y, <span style="color: #);
<span style="color: # //给向量赋予旋转
<span style="color: # var distanceVector = ro * Vector3.forward * D
<span style="color: # var pos = transform.position - distanceV
<span style="color: # CameraGo.transform.position =
<span style="color: # CameraGo.transform.rotation =
至于相机围绕角色旋转,我们只需要改变一下Quaternion.Euler(Pitch,&transform.rotation.eulerAngles.y,&0) 中transform.rotation.eulerAngles.y这个值
本来这个值是指定相机朝向角色的方向,我们改变这个值,就可以实现相机围绕角色的效果。我们可以这样做
//delta就是围绕角色旋转的旋转角度0~360.
Quaternion ro = Quaternion.Euler(Pitch, transform.rotation.eulerAngles.y + delta, <span style="color: #)
最终,上诉代码如下,代码不完整,请各位自行补全:
1      //角色移动
void SmoothMove()
Vector3[] vector3s = _transDataL// CurvePath.PathControlPointGenerator(_transDataList);
int sample = _transDataList.Length * SampleR
_movePtg += Time.deltaTime * MoveS
//曲线插值
<span style="color: #
transform.position = CurvePath.Interp(vector3s, _movePtg / sample);
<span style="color: #
<span style="color: #
//计算当前位置到下一个坐标点的向量
<span style="color: #
var vector = (transform.position - _prevPos).
<span style="color: #
//取得向量的方向
<span style="color: #
var rotation = Quaternion.LookRotation(vector, Vector3.right).eulerA
<span style="color: #
//去处x和z方向的影响,仅作用y方向偏转
<span style="color: #
rotation.x = <span style="color: #;
<span style="color: #
rotation.z = <span style="color: #;
<span style="color: #
<span style="color: #
//将物体旋转到指向下一个坐标点的方向
<span style="color: #
transform.rotation = Quaternion.Euler(rotation);
<span style="color: #
<span style="color: #
<span style="color: #
_prevPos = transform.
<span style="color: #
if (_movePtg &= sample)
<span style="color: #
<span style="color: #
ResetLocalData();
<span style="color: #
<span style="color: #
<span style="color: #
<span style="color: #
//相机跟随
<span style="color: #
void FollowCamera()
<span style="color: #
<span style="color: #
if (CameraGo == null) return;
<span style="color: #
<span style="color: #
if(UseFollow != <span style="color: #)
<span style="color: #
<span style="color: #
//相机的俯仰角和偏航角,Y方向偏航和目标对象一致
<span style="color: #
Quaternion ro = Quaternion.Euler(Pitch, transform.rotation.eulerAngles.y + Slider, <span style="color: #);
<span style="color: #
<span style="color: #
//给向量赋予旋转
<span style="color: #
var distanceVector = ro * Vector3.forward * D
<span style="color: #
var pos = transform.position - distanceV
<span style="color: #
CameraGo.transform.position =
<span style="color: #
CameraGo.transform.rotation =
<span style="color: #
<span style="color: #
<span style="color: #
阅读(...) 评论()11033人阅读
unity-开发(43)
固定相机跟随
这种相机有一个参考对象,它会保持与该参考对象固定的位置,跟随改参考对象发生移动
using UnityE
using System.C
public class CameraFlow : MonoBehaviour
private Vector3
void Start()
offset = target.position - this.transform.
void Update()
this.transform.position = target.position -
固定相机跟随,带有角度旋转
这一种相机跟随是对第一种相机跟随的改进,在原有基础上面,添加了跟随角度的控制
using UnityE
using System.C
public class CameriaTrack : MonoBehaviour {
private Vector3 offset = new Vector3(0,5,4);
private Vector3
public float speed = 2;
void Start () {
target = GameObject.FindGameObjectWithTag("Player").
void Update () {
pos = target.position +
this.transform.position = Vector3.Lerp(this.transform.position, pos, speed*Time.deltaTime);
Quaternion angel = Quaternion.LookRotation(target.position - this.transform.position);
this.transform.rotation = Quaternion.Slerp(this.transform.rotation, angel, speed * Time.deltaTime);
第三人称相机
这种相机跟随,是第三人称角度看向对象的,也就是一直看向对象的后面,如一直显示玩家的后背
using UnityE
using System.C
public class CameraFlow : MonoBehaviour {
public float distanceUp=15f;
public float distanceAway = 10f;
public float smooth = 2f;
public float camDepthSmooth = 5f;
void Start () {
void Update () {
if ((Input.mouseScrollDelta.y & 0 && Camera.main.fieldOfView &= 3) || Input.mouseScrollDelta.y & 0 && Camera.main.fieldOfView &= 80)
Camera.main.fieldOfView += Input.mouseScrollDelta.y * camDepthSmooth * Time.deltaT
void LateUpdate()
Vector3 disPos = target.position + Vector3.up * distanceUp - target.forward * distanceA
transform.position=Vector3.Lerp(transform.position,disPos,Time.deltaTime*smooth);
transform.LookAt(target.position);
相机跟随,鼠标控制移动和缩放
相机与观察对象保持一定距离,可以通过鼠标进行上下左右旋转,通过鼠标滚轮进行放大和缩小操作
using UnityE
using System.C
public class CameraFlow : MonoBehaviour
void Start()
offset = transform.position - target.
void Update()
transform.position = target.position +
private void Scale()
float dis = offset.
dis += Input.GetAxis("Mouse ScrollWheel") * 5;
Debug.Log("dis=" + dis);
if (dis & 10 || dis & 40)
offset = offset.normalized *
private void Rotate()
if (Input.GetMouseButton(1))
Vector3 pos = transform.
Vector3 rot = transform.eulerA
transform.RotateAround(Vector3.zero, Vector3.up, Input.GetAxis("Mouse X") * 10);
transform.RotateAround(Vector3.zero, Vector3.left, Input.GetAxis("Mouse Y") * 10);
float x = transform.eulerAngles.x;
float y = transform.eulerAngles.y;
Debug.Log("x=" + x);
Debug.Log("y=" + y);
if (x & 20 || x & 45 || y & 0 || y & 40)
transform.position =
transform.eulerAngles =
offset = transform.position - target.
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:109290次
积分:1587
积分:1587
排名:千里之外
原创:51篇
转载:22篇
评论:12条
(2)(1)(3)(3)(1)(1)(1)(4)(7)(5)(8)(7)(4)(9)(19)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'Unity5.x制作合金弹头(四)-相机的跟随-GAD腾讯游戏开发者平台

我要回帖

更多关于 unity ngui 相机跟随 的文章

 

随机推荐