unity自动校准(翻译)

本文只是对那篇老外博客进行了翻译,翻译的不好,自己刚过六级.肯定有很多问题,欢迎同学指出.

原文链接:http://www.paradeofrain.com/2010/07/lessons-learned-in-tilt-controls/

回顾一下

我想简单粗糙的讲讲TtL(游戏名)实现的过程。这不是后期分析,但是读者可以因此了解Ttl的实现和代码是如何慢慢改进的。Ttl是我做的移动平台的第一个app程序。第一次使用mac,第一次用XCode, 第一次写Objective-C.有太多的第一次。通常,当我学东西的时候,我不会因为风格,最优化,或者平台的特殊规定等而烦恼。但当我开始学这个的时候,我就把这些都给学了。Ttl从第一次的改进到现在,已经花了很长时间。

这是以前的版本

在那时的Ttl中,我们把绿色的点叫做核弹,

现在

 

游戏很美观,要多谢谢Adam强大的美工(3A质量)。代码却有时感觉像大丑兽。通常,我会这样来写程序,先写一个原型,然后重新开始,对代码进行重构,重新编写,这样使得代码容易维护。然而Ttl不是这样的,这个游戏的改进是直接从原型改成了产品级代码。原始代码经历了大量的重写,重构,和一些补丁,使得代码开始变得健壮起来。好的是,我现在对可维护性代码不应该是什么样的有了更清楚的认识,同时在编码过程中,懂得更多设计架构,可以避免代码以后出现混乱。

         要明确指出的是,因为要把它做成一个产品,所以最后,只要游戏有趣,没有人会骂它(除了作者)

Tile 控制中的设计问题

在操控设计中,我们当前关注的主要重点是如何为用户实现校准功能。整体上,我们对增加游戏用户的体验有个非常简单的方法。我们需要让用户进入游戏花上最少的点击次数,一旦进入游戏,你所做的就是倾斜设备开始游戏。这样看来,让校准自动进行看起来会是最好的用户体验。用户甚至不知道自己做了什么,只知道这只是个游戏。那么如何初始化校准工作呢?当游戏计数”3,2,1”,“1”消失时,游戏就在这个时间点即时在平衡位置进行了校准。同样,当玩家取消暂停游戏,校准也会执行。听起来不错,玩起来更好…如果你知道它是如何工作的。从游戏测试中我们发现:

         用户可能会迷惑,当他们改变他们玩的姿势时没有暂停游戏,校准没有生效。这是一个使他们困惑的情况。

         有很多的聪明玩家会马上找到校准的选项,因为他们在以前的iphone游戏中用到过这种功能。如果没有找到校准选项,他们会因为不能按照他们喜欢的方式去打游戏而感到不爽。

         在更多地社会环景中,而不是单独的游戏测试,那里游戏可以玩的很随意。这可能会破坏我们的自动校准功能。玩家可能把iphone朝下,与同事交谈时又把iphone摆到自己旁边,当游戏计数开始时,又马上把iphone向后转动后再玩,这个时候校准就乱了。这会对用户产生不好的印象。

 

那么我们是否要在玩家玩之前告诉他通过暂停和开始游戏就可以对游戏重新校准?我们快速模拟了客户的反应.

         对那些知道校准功能的用户,他们可以立即的理解.

对其他人,他们很可能会说:"校准是什么意思?".是的,全都带着不好的口音.

好吧,因为我们要对那些最幼稚的iphone玩家有吸引力,做了以下测试:

1.   针对自动校准:没有合适的反馈,用户可能会错误的设置校准,使他们认为这个游戏出问题了.

2.   针对用户自定义的校准:有些用户可以很好的使用,但是对用户的无数种情况,很验难预料到不怎么玩游戏的玩家会知道校准功能.

3.   一般的情况:有经验的用户会比较喜欢校准,甚至要求更多的功能.用户要玩你的游戏,他要做的决定越少,就越喜欢玩.这是在移动领域中很重要的概念,特别是像加速度计这些不精确的物理输入.

4.   尤其在Ttl的设计方面:TtL的游戏设置需要精确的tilt控制,否则,游戏就会失败.其它的不怎么需要精确控制的游戏,则可以使用自动校准.

因此,通过集思广益,想到了很多种校准界面.相比其它基于tilt操控的游戏,Adam在那时想到了一个独一无二的好主意.

 

我们认为这是一个好主意,同时测试也很好,我们没有想到目前的这个选择跟用户会产生更多的共鸣.

 

“这是我发现的自定义tilt 控制最好的选项.”

“那些害怕手动校准的人,现在不用怕了”

“游戏的不同之处在于他的校准选项,提供了三个默认操控,这样可以满足大多数人的游戏姿势.”

玩家和评论者对我们的方法都给予了积极的反馈.regular的设置功能可以满足大多数的游戏情况,top_down也更能满足游戏爱好者.sleepy是有很多种可能的姿势.比如我吧,如果你让一组用户用sleepy的姿势来玩游戏,你可能会得到一个比regular, top_down姿势更大的方向方差.我不认为现在的tilt control比下一代游戏的要好,但是我感觉,让用户更少的去选择就能得到更好的精确值,那么他们就会更加积极.

 

Tilt控制的技术问题

除了设计上的问题,在实现tilt控制的技术上,我有很多问题要克服.第一个也是最大的问题是如何计算tile的偏移限制.当iphone的校准出现完全竖直的情况时,那么所能检测到的水平移动几乎没有.为了解决这个问题,我加了一个控制方案,当设备在这个位置时玩家通过steering来控制游戏中的飞船,而不是倾斜设备来控制.这不是好的情况,但是随着iphone4陀螺仪的出现,这也许可以缓解.已经有很好的方法来实现3G/3GS上的tilt控制,所以这不是一个问题,我没有太多时间来做这个实验.当我做这些实验的时候,我会发布更新的.

第二个问题是加速度计数据的噪音.我按照Apploc文档的说明,对原始输入值进行了过滤.但是最后,我还是让输入值没有进过过滤,取而代之的是,只改变了飞船的显示.如果飞船在高速运行,通过原始输入值来改变飞船的方向显示,会引起不可控的抖动.这就不可能使用那些要瞄准的武器.要解决这个基本问题,我加了一个插值函数,可以使飞船从当前方向到目标方向有一个几帧的缓冲,同时,加了一个盲区,可以让玩家坐着玩的很好,而不会产生游戏内飞船时时刻刻旋转的问题.我已经玩了很多基于titl操控的游戏,这些游戏都没有实现盲区的功能.对玩家更好的是,至少加个该死的盲区吧.

第三个但是比较小的问题就是采样率.Sss我设置的加速度计的采样率是 30hz,那么Ttl运行也是30FPS.但FPS与加速度计的数据有点不同步,你会看到加速度数据会从几帧中获得,因而有点细小的变化.Ttl没有做太多管理不同帧时间的工作(不好意思),但是这个问题也没有带来太多的不好,因此我没有觉得这个问题值得修.

 

是如何真正工作的?

对一直读下去的读者们,都会很想知道这是怎么实现的,我添加了一个XCode工程来实现.我写了一个GLSprite demo程序,把其中的功能进行了分解,使它满足了一个简单tile控制 的样例.我的这个方法就是写了一个函数,用来实现 反转操作杆 的功能.我不会试着去解释WTF的意思,通过下面简单的绘画来描述.

 

我通过对加速度计数据进行插值,使它转向的向量可以一直指向远离设备屏幕的方向.我通过这样,找到这个向量和’neutral’位置(blue)的差,最后投影在屏幕的2D平面上,返回一个速度值.绿色的箭头就是玩家速度的方向.那么,当neutral位置和反转的加速度数据很接近时,玩家的速度值会趋近于0(盲区).

你可以从这个案例程序中发现,所有的加速度计算的逻辑代码都在TiltPlayer类的'accelerometer:didAccelerate"方法里实现.在TiltPlayer的update方法,做了对图标方向的平滑处理,减少了抖动.其它的都是渲染程序或其它引用程序.因此这里贴出了与本文相关的代码,不用打开XCode工程去查看了.

样例程序下载链接:http://www.paradeofrain.com/downloads/Tilt_Controls

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
/* while not ideal, most of the relevant code is stuffed in this method for clarity. A lot can be computed once
and saved in instance variables, preferences, etc instead of re-calculating each frame
*/// hard coding our 'neutral' orientation. By default this is the orientation of
// having the device tilted slightly towards your face.
// if you wanted strictly a 'top down' orientation then a (0,0,-1) vector would be put here.
// to create a new 'neutral' position you can sample the UIAcceleration parameter for a single
// frame and set that to be the new nx,ny,nz for the remainder of the app (aka calibrating).
const float nx = -0.63f;
const float ny = 0;
const float nz = -0.92f;// this quaternion represents an orientation (I like to think of it as a 3D vector with 0 rotation in this case)
// that points straight out from the device's back away from the user's face.
Quaternion neutral(0,nx, ny, nz);
// take a straight up vector and rotate it by our 'neutral' orientation
// to give us a vector that points straight out from the device's screen (at the user's face)
Quaternion neutralPosition = neutral * Quaternion(0,0,0,1);/* now with our 'neutral' quaternion setup we:
1. take the incoming accelerometer data
2. convert it to a 2D velocity projected onto the plane of the device's screen
3. and rotate it by 90 degrees (since we are landscape oriented) and feed it to our player's
velocity directly.
*/// convert our accel data to a Quaternion
Quaternion accelQuat(0, acceleration.x, acceleration.y, acceleration.z);// now rotate our accel data BY the neutral orientation. effectively transforming it
// into our local space.
Vec3 accelVector = (accelQuat * neutralPosition).v; // we only want the 3D vector at this point// now with our accel vector we wish to transform it into our standard (1,1,1) coordinate space
Vec3 planeXAxis(1,0,0);
Vec3 planeYAxis(0,1,0);
Vec3 normal(0,0,1); // the normal of the plane we wish to transform our data into.//project this movement onto our X/Y plane by removing
// the accel part that is along our normal
// note: Vec3 * Vec3 = dot product of the 2 vectors.
Vec3 projection = accelVector - normal *(accelVector * normal);// now decompose that projection along our X and Y axis that represents our 2D plane
Vec2 accel2D(0,0);
accel2D.x = planeXAxis * projection;
accel2D.y = planeYAxis * projection;const float xSensitivity = 2.8f;
const float ySensitivity = 2.8f; // yay magic numbers!
const float tiltAmplifier = 8; // w0ot more magic numbers// now apply it to our player's velocity data.
// we also rotate the 2D vector by 90 degrees by switching the components and negating one
// since we are in a landscape orientation.
vx += (-accel2D.y) * tiltAmplifier * xSensitivity;
vy -= accel2D.x * tiltAmplifier * ySensitivity; // we do a (-) here because the accel y axis is inverted.
}

多谢Mikko Mononen,使代码更加简洁,下面是Mikko mononen改进后的代码.

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
// A much more concise version courtesy of Mikko Mononen http://digestingduck.blogspot.com/
Vec2 accel2D(0,0);
Vec3 ax(1, 0, 0);
Vec3 ay(-.63f, 0,-.92f);
Vec3 az(Vec3::Cross(ay,ax).normalize());
ax = Vec3::Cross(az,ay).normalize();accel2D.x = -Vec3::Dot(Vec3(acceleration.x, acceleration.y, acceleration.z), ax);
accel2D.y = -Vec3::Dot(Vec3(acceleration.x, acceleration.y, acceleration.z), az);const float xSensitivity = 2.8f;
const float ySensitivity = 2.8f; // yay magic numbers!
const float tiltAmplifier = 8; // w0ot more magic numbers// since we are in a landscape orientation.
// now apply it to our player's velocity data.
// we also rotate the 2D vector by 90 degrees by switching the components and negating one
vx += -(accel2D.y) * tiltAmplifier * xSensitivity;
vy += accel2D.x * tiltAmplifier * ySensitivity;}

秀才坤坤出品

转载于:https://www.cnblogs.com/xckk/archive/2012/09/02/2667838.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/353639.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

vivo 互联网业务就近路由技术实战

一、问题背景 在vivo互联网业务高速发展的同时,支撑的服务实例规模也越来越大,然而单个机房能承载的机器容量是有限的,于是同城多机房甚至多地域部署就成为了业务在实际部署过程中不得不面临的场景。 一般情况下,同一个机房内部的…

进出口跨境电商软件平台系统开发,源码技术架构

一、进出口跨境电商软件平台系统开发需做好相应的前期准备,如确定市场、了解政策、推广宣传等。 欢迎名片沟通探讨 确定目标市场:选择合适的目标市场。需要了解目标市场的消费习惯、政策法规以及竞争情况。 了解海关相关政策:针对不同国家或…

机器学习——集成学习(装袋法Bagging、提升法Boosting、梯度提升决策树GBDT、随机森林RF)

集成学习 集成学习通过构建并结合多个学习器来完成学习任务 集成方法是用多种学习方法的组合来获取比原方法更优的结果 使用于组合的算法是弱学习算法 即分类正确率仅比随机猜测略高的学习算法 但是组合之后的效果仍可能高于强学习算法 即集成之后的算法准确率和效率都很高…

C++,Qt部分面试和笔试题

面试这么多次,C这块基础太差了,乘着还有印象总结下相关的面试问答和笔试题,后续会不断更新内容 目录 问答题1.计算机网络七层体系结构2.C中关键字static和const的使用3.QList和QVector for循环输出速度比较4.构造函数能否为虚函数5.谈谈你对面…

Mysql进阶【1】论述索引,索引数据结构,MVCC

1. ReadView 案例,解释为什么 RR 和 RC 隔离级别下看到查询结果不一致 案例 01- 读已提交 RC 隔离级别下的可见性分析 开启两个回话,会话事务级别都是READ-COMMITED; 操作步骤 开启两个数据库会话,设置事务为提交读事务2查询id1数据&#…

纯净内存清理加速软件(Mem Reduct)

纯净内存清理加速软件(Mem Reduct) 文章目录 纯净内存清理加速软件(Mem Reduct)一、Mem Product是什么?二、使用步骤1.下载2.安装 总结 你还为了加速球还困扰全家桶吗,看看这个!! 一、Mem Product是什么&a…

如何清理占用计算机内存,告诉你如何深度清理电脑内存

在如今这个社会时代中,电脑可以说是人们在日常生活中必不可少的一个工具,电脑对我们的学习和工作都起着非常大的作用。但电脑也有出现问题的时候,比如说电脑内存变得越来越小,遇到该问题是该如何处理呢?当然是进行清理内存啦,今天小编就给大家分享一下清理电脑内存的方法…

计算机C盘内存清理

计算机C盘总是莫名其妙的就满了,于是总结了一些清理C盘垃圾以及维护C盘内存的方法。大家有别的有效的方法欢迎告诉我,随时补充。 目录 一、 清理C盘垃圾方法1 利用系统自带的磁盘清理工具进行清理2 定期清理系统临时文件3 清理电脑缓存垃圾4 定期清理浏…

服务器系统如何清理,服务器清理内存怎么清理

服务器清理内存怎么清理 内容精选 换一换 本节操作指导您完成Windows操作系统云服务器磁盘空间清理。弹性云服务器匀出一部分磁盘空间来充当内存使用,当内存耗尽时,云服务器可以使用虚拟内存来缓解内存的紧张。但当内存使用率已经非常高时,频繁的内存与虚拟内存的切换会导致…

Lftp+Sftp传输总结

背景介绍:因为备份数据的不断扩大,需要把现网备份的数据(2T左右)传回到本地进行异地保存。但是2T太大了,需要进行压缩,这里采用了3G一个压缩包的方式。以下是压缩脚本 #!/bin/bash # 此脚本是全量压缩mongo…

xftp,xftp怎么连接

服务器管理进行文件传输用的最多的就是FTP传输,那xftp怎么连接服务器呢?打开xftp软件,新建一个连接,填上要连接的IP,端口号,用户名,密码等,保存即可。在选项中选择编码为UTF-8&#…

JAVA日志框架

JAVA日志框架 常见日志框架日志级别阿里日志规约什么时候打印日志配置文件log4j.propertieslogback-spring.xmllogback的默认配置 导入依赖日志使用方式,引入slf4j的API输出用户日志 常见日志框架 日志框架:Log4j 、Logback 。 日志门面:Slf…

VSFTP服务

概述: FTP服务器(File Transfer Protocol Server)是在互联网上提供文件存储和访问服务的计算机,它们依照FTP协议提供服务。 FTP(File Transfer Protocol: 文件传输协议)作用: Internet 上用来…

vsftp

一、概述 FTP是file Transfer Protocoll文件传输下ieyi,用于Internet上的文件的双向传输。因ftp是明文传输,没有受到保护,所以具有一定危险性。 VSFTP是一个基于GPL发布的类unix系统上使用的FTP服务器软件。为了解决ftp传输安全性问题的&…

SFTP在Linux和window下的文件传输

使用SecureCRT的SFTP在WINDOWS与LINUX之间传输文件 参考文献: http://ice-k.iteye.com/blog/1068275 http://www.cnblogs.com/chen1987lei/archive/2010/11/26/1888391.html 背景: 有一台主机,安装了windows7,在其安装了virtualbo…

vsftp的简单使用

一、vsftp以及安装 服务端软件:vsftpd 客户端软件:ftp 端口号:20、21或指定范围内其他随机端口 配置文件:vim /etc/vsftpd/vsftpd.conf # 安装 yum install vsftpd ftp# 开机自启 systemctl enable vsftpd# 启动 systemc…

Explaining predictive models: the Evidence Counterfactual

Imagine being targeted with an advertisement for this blog. You’d like to know: why did the AI model predict you’d be interested in the Faculty of Business and Economics’ blog, based on the hundreds of web pages you visited? The answer could be: becaus…

记录搭建hadoop集群的过程

Linux(CentOS-7.6-x64位)基础配置, 虚拟机平台VmWare15 CentOS-7.6-x64镜像下载: https://www.aliyundrive.com/s/72Xg449t6i8 提取码: 32rm VmVare15安装包下载带序列号:VmVare15安装包下载带激活序列号资源-CSDN文库 点击关闭,点击完成&…

ChatGPT热度不减!华为宣布入局,盘古GPT能否大杀四方!

ChatGPT热度不减 六月份了,朋友们,来到六月份了已经,ChatGPT的热度依旧不减,各大论坛网站的榜单上还飘着ChatGPT相关话题的文章,且排名靠前。由此可见,这ChatGPT这股子热潮还得持续一段时间呢。 而且ChatG…

三国志战略版:Daniel_新晋减伤战法-奇计良谋

一、战法介绍 战法定位:稳定且有针对性的群体减伤战法。 同类效果: 稳定的群体减伤战法:八门金锁阵、抚辑军民、暂避其锋、锋矢阵、藤甲兵、御敌屏障。 稳定群体减伤战法往往可以极大提升一个队伍的强度,如今一线群体减伤战法中…