CameraController

1、根据角色的位置来计算camera的位置

targetLookAt = new GameObject("targetLookAt").transform;

首先我们先介绍下targetLookAt对象,主要记录camera应该看相的方向,但他的位置是target的位置,rotation是camera的rotation,

这是我们创建的一个虚拟的物体,它和target保持同一位置(有一个身高差值),但却具有camera的视角,所以targetLookAt.forward其实就是camera的forward


/*targetLookAt的位置相对于target 不变,在Y轴向有一个身高差量*/
targetLookAt.position = new Vector3(currentTarget.position.x, currentTarget.position.y, currentTarget.position.z)
+ new Vector3(0, currentHeight, 0);var camDir = targetLookAt.forward;
camDir = camDir.normalized;/*current_cPos可以认为就是目标的位置,distance就是相机和目标之间的距离,这个值应该是恒定的2.5fcamDir相机和目标之间的方向,初始值是(-1,0,0)正常模式下相机转动时,位置不断改变,但始终指向目标
*/
transform.position = targetLookAt.position - (camDir * distance);

targetLookAt的positon根据目标的实时位置就能计算出来,targetLookAt的rotation是根据鼠标输入改变,我们接下来介绍

2、根据输入来控制camera的rotation

MouseSensitivity是鼠标敏感度,Input.GetAxis获取的是鼠标的位移量,不是绝对位置

相机的初始位置和目标的eularAngles保持一直

注意这里的x和y颠倒了,这个原因是啥?因为当我们水平移动鼠标时(MouseX),我们希望相机也是水平转向,但相机水平转向其实是绕Y轴旋转,这一点需要注意

mouseY = currentTarget.eulerAngles.x;//注意这里的x和y颠倒了,这个原因是啥?
mouseX = currentTarget.eulerAngles.y;
var Y = Input.GetAxis(rotateCameraYInput);
var X = Input.GetAxis(rotateCameraXInput);
public void RotateCamera(float x, float y){// free rotation mouseX += x * xMouseSensitivity;mouseY -= y * yMouseSensitivity;movementSpeed.x = x;movementSpeed.y = -y;if (!lockCamera){mouseY = vExtensions.ClampAngle(mouseY, yMinLimit, yMaxLimit);mouseX = vExtensions.ClampAngle(mouseX, xMinLimit, xMaxLimit);}else{mouseY = currentTarget.root.localEulerAngles.x;mouseX = currentTarget.root.localEulerAngles.y;}}

如果锁定了相机(注意这里是指相机的角度固定,而不是锁定敌人),则角度固定和目标保持一致,否则就计算mouseX和mouseY不要超过最大值和最小值

/*targetLookAt的位置相对于target 不变,在Y轴向有一个身高差量*/
targetLookAt.position = new Vector3(currentTarget.position.x, currentTarget.position.y, currentTarget.position.z)
+ new Vector3(0, currentHeight, 0);
/*lookPoint,target的位置往前2个单位*/
var lookPoint = targetLookAt.position + targetLookAt.forward * 2f;/*根据需要旋转的欧拉角增量,转换成四元素*/
Quaternion newRot = Quaternion.Euler(mouseY, mouseX, 0);
/* Quaternion.Slerp(Quaternion from ,Quaternion to, float t)叫球面线形插值
这样使相机转动更柔和*/
targetLookAt.rotation = Quaternion.Slerp(targetLookAt.rotation, newRot, smoothCameraRotation * Time.deltaTime);
var rotation = Quaternion.LookRotation((lookPoint) - transform.position);transform.rotation = rotation;

简单画一个示意图帮助理解A->B

1、targetLookAt的位置相对于目标是始终是不变的,在Y轴向有一个身高差量,它的rotation从tragetLookAt.rotation差值变成newRot

2、lookPoint在距离targetLookAt,半径为2的球面上,所以targetLookAt.position + targetLookAt.forward * 2f;

3、上面我们已经计算过了camera的实时位置transform.position

4、Quaternion.LookRotation(lookPoint - transform.position)就是我们最后需要的camera的旋转量,LookRotation函数就是根据lookPoint - transform.position向量创建四元数

transform.rotation = targetLookAt.rotation这样camera会抖动,是因为深拷贝和浅拷贝的原因吗?

3、锁定模式(Lock On)下的camera的角度

lock on 模式下,camera就不会随着鼠标移动了,

角色始终是面向lockTarget的

相机的视角也是面向lockTarget的

但相机的位置应该还是跟随人物移动的

var lockDir = lockTarget.transform.position - transform.position;
lockDir = lockDir.normalized;
var rotation = Quaternion.LookRotation(lockDir);
transform.rotation = rotation;
transform.position = targetLookAt.position - (lockDir * distance);

其他方式实现相机旋转

上述的方式用来计算Camera的旋转还是有点复杂的,傅老师的黑魂复刻教程里介绍了一种简单的方式,就是实现如下的方式

PlayerHandle->CameraHandle->Camera

水平旋转的时候,只需要转动PlayerHandle,垂直旋转的时候只需要旋转CameraHandle

注意:要有两层容器,如果都在一层是,是不对的,同时进行X和Y轴旋转,会有问题,这是欧拉角的旋转引起的,具体可以参考

void Update(){Vector3 tempEulers = actor.transform.eulerAngles;var Y = Input.GetAxis(pi.rotateCameraYInput);var X = Input.GetAxis(pi.rotateCameraXInput);playerHandle.transform.Rotate(Vector3.up*X*cameraSensity);cameraHandle.transform.Rotate(Vector3.right*-Y*cameraSensity);/*角色相对于世界坐标系的欧拉角要保持不变*/actor.transform.eulerAngles = tempEulers;}

至于相机的位置,可以将camera和角色都放在PlayerHandle下面,camra相对角色有个向后的位移,可是旋转PlayerHandle时,Actor也会随之旋转,所以要让Actor的eulerAngles保持不变

相机延迟追赶

主要还是利用Lerp()函数就可以实现弹性跟随的效果

具体可以参考黑魂复刻1-30相机延迟移动

https://www.bilibili.com/video/BV1gW411T7yb?p=30

遗留:

同位角问题??

同位角问题??限制相机上下旋转角度的时候会遇到

啥是欧拉角?四元数??

gameObject.transform是个啥?不是数组?是对象?

lerp:

在unity3d中经常用线性插值函数Lerp()来在两者之间插值,两者之间可以是两个材质之间、两个向量之间、两个浮点数之间、两个颜色之间,其函数原型如下:

从最简单的数学插值来看,插值函数接收三个参数a,b,t,在ab之间,以t作为比例来插值。

例如,Lerp(0, 10, 0.4f),此时返回4,即 a + (b - a) * t

作用:而Lerp()函数就可以实现弹性跟随的效果

参考:

Unity插值函数Lerp()与增量时间Time.deltatime

https://www.cnblogs.com/softcorns/p/10925836.html

Unity黑魂复刻经典教程心得(三)-CameraController相关推荐

  1. Unity黑魂复刻经典教程心得(一)

    b站上傅老师的黑魂复刻教程,是比较好的,傅老师风情幽默,值得种草 https://www.bilibili.com/video/BV1gW411T7yb?p=55

  2. 傅老师的unity黑魂复刻学习日记(六)

    内容:角色奔跑,角色转身 在blend tree里面新加一个Motion field 把包里的run动画拖进去 把蓝处消钩取消锁定,设置1为走2为跑. 在palyerinput里面定义一个布尔run, ...

  3. 【Mib自看】黑魂复刻Unity脚本

    [课程地址]B站傅老师Unity课程学习记录,仅代表个人理解. [自看]黑魂复刻Unity脚本 1.移动脚本 设计思路 2.动画 动画脚本:ActorController + 输入脚本:PlayerI ...

  4. 黑魂复刻游戏的碰撞摩擦问题——Unity随手记(2021.4.27)

    文章目录 前言 今天实现的内容: 角色跳起来时的卡墙问题描述 修改物理材质方案 修改m_planarVec方案 BUG以及缺陷: 值得注意的: 前言 本篇博客旨在解决黑魂like游戏开发时遇到的一个问 ...

  5. 黑魂复刻游戏的玩家控制器(基础移动,动画实现及优化)——Unity随手记(2021.3.15)

    文章目录 今天实现的内容: 动画机设计理念 动画机的运用及模型旋转 玩家角色的位移 爬坡测试 跑步 旋转的优化 跑步动画的优化 BUG以及缺陷: 值得注意的: 今天实现的内容: 动画机设计理念 要我说 ...

  6. Unity项目-黑魂复刻(四)玩家控制器(翻滚以及跳跃操作改动)

    翻滚以及跳跃操作改动 黑魂游戏中,翻滚的触发条件:1.走路按跳跃键 2.助跑按跳跃键 3.高处掉落 所以之前的跳跃键需要改成翻滚键 翻滚动画以及触发逻辑: 注意:由于翻滚的动画会出现y方向的根tran ...

  7. 黑魂复刻游戏的玩家控制器(翻滚及跳跃的重新设计)——Unity随手记(2021.3.31)

    文章目录 今天实现的内容: 翻滚和跳跃的重新设计 翻滚动画及触发逻辑 翻滚的向前冲量 跳跃并向前翻滚 BUG以及缺陷: 值得注意的: 今天实现的内容: 翻滚和跳跃的重新设计 按照黑魂游戏的设计,跳跃其 ...

  8. 黑魂复刻游戏的玩家输入模块——Unity随手记(2021.3.14)

    文章目录 前言 今天实现的内容: 按键封装 获取输入及输入信号优化 输入的渐变 模块的软开关 处理输入 BUG以及缺陷: 值得注意的: 前言 好久不见,在接下来的Unity随手记里,我会学着B站上的视 ...

  9. Unity项目-黑魂复刻(二)玩家控制器(跳跃)

    跳跃信号 要实现跳跃,首先要实现跳跃的输入.跳跃信号是按下的当场触发的一次性触发控制(Trigger Once Signal),这个信号转化为编程语言就是bool值,通过控制真还是假判定是否按下跳跃键 ...

最新文章

  1. IronPython系列:Composite Pattern及其实现
  2. MacBook Air 使用技巧
  3. 取消Ajax请求 || Ajax重复请求问题
  4. 数字图像处理(一):灰度变换和直方图处理
  5. designer一直未响应 qt_未雨绸缪及时清淤 曾是内涝重灾区 这次涵洞未积水
  6. WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展
  7. mysql如何管理空间_管理空间的mysql数据库
  8. 系统动力学建模工具_多体动力学:ANSYS Motion 2020R2
  9. Android编译系统介绍
  10. 女粉想要找男朋友,竟是为了...
  11. Node.js开发指南中的例子(mysql版)
  12. Anaconda下载、安装及配置教程
  13. 设计模式实践-装饰器
  14. Excel函数IF的多条件通配使用方法
  15. c#webservice接口調用_Windows 桌面应用开发之 C# 调用 WebService 接口
  16. 数据科学AB测试(说人话系列)
  17. 像素、分辨率及PPI各自含义与区别及目前主流手机的分辨率介绍
  18. 输入售价后点击计算税费,自动显示在税费输入框!
  19. 几种抠象技术理论试验-1 (Luma-Key,Chroma-Key)
  20. 个人空间岁末大回报活动12月28日获奖名单

热门文章

  1. C++中list的front()和begin()
  2. webConfig中customErrors节点配置
  3. mfc~实现mfc程序支持设置多语言
  4. Java发送内嵌图片的邮件
  5. C语言I博客作业 04
  6. 【数字图像处理】色彩模型
  7. Linux程序源码编译安装的configure配置详解
  8. 【rmzt:火影忍者鸣人帅气主题】
  9. spring-cloud-netflix学习笔记(一):Eureka Server
  10. Android hibernation 导致的冻屏问题分析