最近遇到一些类似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. (九)Struts2 防重复提交

    所有的学习我们必须先搭建好Struts2的环境(1.导入对应的jar包,2.web.xml,3.struts.xml) 第一节:重复提交示例演示 struts.xml <?xml version ...

  2. Java stackoverflow error

    本文想记录一下尝试产生stackoverflow的程序 1 -Xss=1k, 设置stack大小1024个字节,产生515个long,想把stack撑爆. 2 嵌套调用 3 创建大量线程 1 -Xss ...

  3. 插入标记 方法 insertAdjacentHTML

    html5新增的插入标记方法,insertAdjacentHTML() 可以接受2个参数 插入位置和要插入的 HTML 文本.第一个参数必须是下列值之一: "beforebegin" ...

  4. jquery 之选择符

    css:选择符$('#selected-plays > li') 使用了子元素组合符,查找 ID 为 selected-plays 的元素的子元素( > )中所有的列表 li$('#sel ...

  5. js 之 json

    /*JSON语法数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组 JSON 数据的书写格式是:名称/值对名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值;如"myw ...

  6. javascrip 分享到

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. 从gcc的__attribute__((packed))聊到结构体大小的问题

    公司的前辈的代码里面 结构体的花括号最后 有__attribute__((packed))字样.以前没见过,所以查了查.学习学习http://blog.sina.com.cn/s/blog_559f6 ...

  8. jquery实现表格可变列宽插件开发

    工作中用到了表格的可变列宽,网上看了下,自己也实现了一个,整理贴记录. 测试环境chrome,ie8,firefox jquery版本1.8.2 原理:监听table第一行的mousemove事件,当 ...

  9. Contest20140705 testC DP

    testC 输入文件: testC.in 输出文件testC.out 时限1000ms 问题描述: ,⋯,an. ,a2,a3,⋯,an) ,⋯,alm. ,al2,al3,⋯,alm) 现要求G=g ...

  10. App Store内购

    一.In App Purchase概览 Store Kit代表App和App Store之间进行通信.程序将从App Store接收那些你想要提供的产品的信息,并将它们显示出来供用户购买.当用户需要购 ...