最近遇到一些类似3D FPS的game play。针对这里面Player摄像机的运动的问题,随便总结一些东西以备参考。首先,对问题做一些的假设:

  • Player摄像机在多数情况下在场景中的位置是固定的,只在某些时候因为动画而发生平动(当然也会发生转动),多数时候只需要转动。
  • Player摄像机不需要照射到Player的任何部分,也就是Player的角色根本不显示在场景中。
  • 如果Player摄像机拍摄的方向是其自身坐标系的z方向,那么其转动只限于绕自身的x和y轴,且只在一定范围内(比如正负45度)。转动的原因有两种,一种是瞄准(在移动设备上,可以通过触摸、加速度传感器或者陀螺仪返回的数据进行控制,在此不详述),一种是收到攻击时的震动。
  • 程序在Unity3D中开发。
Unity3D实现了基于组件的编程模型,一个GameObject上可以挂载很多组件,比如Transform、Animation、RigidBody、Camera、AudioSource等等,所以可以考虑把各个控制逻辑分成组件。由于动画而造成的运动直接由内置的Animation组件完成,而瞄准和被攻击可以用相应的脚本(也是组件)来完成。但是,这样做其实有很多问题,因为这三种组件都会影响摄像机的旋转。
 
Animation组件是不管其他组件,每一帧都直接给摄像机的旋转赋新值(当然对其位置和大小也如此)。Animation组件没有处于播放状态时,摄像机位置不变,瞄准脚本将作为控制摄像机旋转的主要组件,在Animation控制其旋转的时候,瞄准脚本的控制也就失效了。如果Animation组件起作用的时间不长,那还好说,如果Animation造成旋转的时间较长,那就麻烦了。另外,由于震动这个组件是后加上的,理想情况下它应该只是在被瞄准脚本控制的摄像机转动上面加上适当的扰动。
由于我现在只有瞄准、震动两个脚本直接控制摄像机角度,我可以在瞄准脚本的Update()方法里,根据传感器给出的值调整摄像机角度,而在震动脚本里,通过LateUpdate()加上扰动。(后者不能直接使用Update()方法,是因为不同脚本中Update()的调用顺序是不定的。)这样的实现不好看,而且难以扩展。如果再有一个脚本加进来怎么办?Unity3D肯定没有一个LateLateUpdate()方法了。
除此之外,在上面描述的实现方式中,不论我使用欧拉角还是四元数,都会有一些问题。原因我还没有查清,但有一点是肯定的:我不怎么会用四元数,并且忌惮它的复杂性。因此,我想了一种简单的方法来实现上面的功能,尚未实验,但我认为应该行得通。准备3个GameObject,分别设为A, B, C,使得A为B的父物体,B为C的父物体。将主控脚本和Animation组件挂在A上,瞄准脚本挂在B上,震动脚本挂在C上(不用LateUpdate()而也改用Update())。这样,瞄准只听从传感器的指示,叠加在Animation造成的运动上;而震动则根据相应算法生成扰动,直接设置C的local
rotation。这个实现应可既让三种运动相对独立,不受Update()调用顺序的困扰,又可以让这些运动叠加起来。
现在能想见,这种实现有一个缺点,就是GameObject的树结构会随着控制脚本的增加越来越大。如果硬要将这个功能放在同一物体上,也许只能设置一个主控脚本,按顺序调用瞄准脚本和震动脚本的Update()方法,而后两者也就不能实现为MonoBehaviour了。但是,要克服Animation组件对旋转的霸道影响,还是要把Animation组件和Camera组件分别挂在两个GameObject上的。
不知道如果熟悉四元数的概念,这个问题会不会更加容易解决?找时间补补课。

3D FPS游戏中Player摄像机的运动的更多相关文章

  1. 在FPS游戏中,玩家对音画同步感知的量化与评估

    前言 在游戏测试中,音画同步测试是个难点(所谓游戏音画同步:游戏中,音效与画面的同步程度),现在一般采用人工主观判断的方式测试,但这会带来2个问题: 无法准确量化,针对同一场景的多次测试结果可能会相反 ...

  2. FPS 游戏实现GDI透视

    FPS游戏可以说一直都比较热门,典型的代表有反恐精英,穿越火线,绝地求生等,基本上只要是FPS游戏都会有透视挂的存在,而透视挂还分为很多种类型,常见的有D3D透视,方框透视,还有一些比较高端的显卡透视 ...

  3. Unity游戏中使用贝塞尔曲线

    孙广东   2015.8.15 比方在3D rpg游戏中.我们想设置弹道,不同的轨迹类型! 目的:这篇文章的主要目的是要给你关于在游戏怎样使用贝塞尔曲线的基本想法. 贝塞尔曲线是最主要的曲线,一般用在 ...

  4. 游戏中的网络同步机制——Lockstep(帧同步)

    本文来自: https://bindog.github.io/blog/2015/03/10/synchronization-in-multiplayer-networked-game-lockste ...

  5. 关于FPS游戏的设计问题

    第一个想到的问题: 首先以unity的FPSCharactorController为例,这里规定,相机的方向中心一定是瞄准的方向中心.设置身体的扭曲朝向相机方向,这样身体可以弯腰.你们看图中,我让玩家 ...

  6. Unity 3d 实现物体跟随摄像机视野运动

    https://blog.csdn.net/qq_31411825/article/details/61623857 Unity 3d 实现物体跟随摄像机视野运动Created by miccall ...

  7. FPS中受伤UI在VR游戏中的实现思路

    FPS中受伤UI在VR游戏中的实现思路 希望实现的效果 这几天一直在尝试各种解决方案,现在算是不完美的解决啦,记录一下心路历程,思路有了算法都比较简单. V_1 玩家胶囊体指向的方向作为正方向,计算出 ...

  8. [Unity3D]Unity3D游戏开发3D选择场景中的对象,并显示轮廓效果强化版

    大家好,我是秦培,欢迎关注我的博客,我的博客地址blog.csdn.net/qinyuanpei. 在上一篇文章中,我们通过自己定义着色器实现了一个简单的在3D游戏中选取.显示物体轮廓的实例. 在文章 ...

  9. 图形与游戏中3D数学基础的说明

    1.左手坐标系与右手坐标系没有好坏之分,不同的研究领域和不同的背景下,选择不同的坐标系:传统计算机图形学采用“左手坐标系”,线性代数则倾向于使用右手坐标系 坐标系由坐标轴与坐标原点组成.原点定义坐标系 ...

随机推荐

  1. matlab中max的用法

    C = max(A) 返回一个数组各不同维中的最大元素.如果A是一个向量,max(A)返回A中的最大元素.如果A是一个矩阵,max(A)将A的每一列作为一个向量,返回一行向量包含了每一列的最大元素. ...

  2. WIN7 64位配置Oracle SQL Developer工具

    在使用Oracle SQL 的过程中,很多参考资料,辅导机构,各种书籍绝大多数都是使用PL/SQL进行讲解,但是问题是PL/SQL对WIN7 64位系统支持不好,网上有各种各样的配置教程,我尝试了很多 ...

  3. java基础(死循环退出选项)

    java程序中为了程序正常运行,需要给无限循环加入一个退出选项,保证程序的可执行性. import java.util.Scanner; public class { public static vo ...

  4. /etc/fstab一些信息

    [root@shine shine]# vim /etc/fstab ## /etc/fstab# Created by anaconda on Thu May 9 13:29:35 2013## A ...

  5. apache 网址重定向

    参考了以下网站,终于基本搞定b2c网站伪静态.剩下的就是体力活了. 回家后整理下. http://yp.oss.org.cn/software/show_resource.php?resource_i ...

  6. 十进制和n进制的转换(10进制转换为36进制)

    答案如下: void Convert() { map<int ,string> maps; maps[0]="0"; maps[1]="1"; ma ...

  7. ASP.NET MVC轻教程 Step By Step 9——分页

    现在我们要把Index视图的留言信息进行分页显示. Step 1. 创建路由 我们希望以类似地址http://localhost:41583/Page1来表示第一页,Page2表示第二页,以此类推.在 ...

  8. oracle 自动增长

    在SQLSERVER和MYSQL里面自动增长字段直接设置就可以.在ORACLE里面就复杂多了.特别是我这样的初学者,不过网络是最好的老师,看了很多相关介绍,本人使用的是使用触发器.具体如下: 首先要创 ...

  9. Python处理XML

    在Python(以及其他编程语言)内有两种常见的方法处理XML:SAX(Simple API for XML)和DOM(Document Object Model,文档对象模型).SAX语法分析器读取 ...

  10. SSL交互和握手过程

    SSL消息按如下顺序发送:  1.Client Hello  客户发送服务器信息,包括它所支持的密码组.密码组中有密码算法和钥匙大小: 2.Server Hello  服务器选择客户和服务器都支持的密 ...