1006大设计翻译版以黄杨_第1页
1006大设计翻译版以黄杨_第2页
1006大设计翻译版以黄杨_第3页
1006大设计翻译版以黄杨_第4页
1006大设计翻译版以黄杨_第5页
已阅读5页,还剩56页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

绪 选题背景与意 发展现 研究内容及方 结 Unity引 Unity引擎简 Unity基本功能介 基本概 刚体物 动画系 可扩展编辑 传统方法的缺陷与应 需求分析与设 人物控制器的逻辑需求分 人物控制器的美术需求分 传统状态机架 总体架构设 解决方 状态机层级结 机 关键帧算 动画速率控 小 具体功能的设计与实 输入响 输入响应需 实现方 运动物 由曲线输入位 物理击打效 的碰撞检 打击效 停 闪 相机.......................................................................................................... 参数监 小 实现效果与................................................................................................................效果比 开发效 可视化编辑内 工作流程的优 使用者反 小 结论与展 致 参考文 器射击敌人、与场景中特殊互动。例如:精英,等;ARPG。通常采用第三人称跟随俯视角,玩家在一个平面的地形上移动,入按键多,不仅不同动作、不同时间、不同按键组合的情况下能够不同的跳转,而ACT人物控制器主要1.21.1的青睐。至2014年4月,根据其的数据已经有超过60%的移动游戏开发采用了Unity引擎[2]。Unity上内置了一套人物控制器组件,但是仅限于通用游戏开发,并未针第二部分:Unity引擎架构,并且实现人物控制器基础的部分和可视化编辑方案。UnityUnityUnity是由Unity开发的一个让玩家轻松创建诸如三维游戏、建筑(c)为迪斯尼和ImangiStudios的卡通魔幻风格纵深跑酷游戏《TempleRun:魔境仙 yStation3、Xbox360、开发友好:Unity支持C#、JavaScript、Boo等进行游戏开发,并且对这些运行而不用修改代码。由于游戏开发者多惯用C++,C#相对于另外两者更容易上手,的第插件库,不论是简单的功能扩展还是复杂的功能组件都可以找到快速的解Hierarchy窗口,以树形结构,按名称显示场景中所有的物体。开发者在这里对场景中的物体进行选择、层级关系编辑、创建、或删除; 或者打开特定的全局属性时,Inspector2.3MonoDevelopUnitySceneScene中有以下重要的概念构成了场景运行GameObjectGameObject,GameObject按树形层级结构组织,通过父子关系来确定空间变换关系。GameObject既可以是有型场景中存在的所有GameObject及其层级关系;ComponentGameObjectGameObject的类别只运行在一个GameObject上存在一个实例,比如刚体。开发者可以通过Inspector窗口检视所选GameObject上挂在的Component及其属性;Component。开发者可以编写自定义,继承MonoBehavior类,然后定义一些响应方法,当GameObject上有发生时,指定的方被运行。比如:GameObjectUpdateUpdate方法调StartOnCollisionEnter方法等。MonoBehavior是Component的一个子类,默认情况下中定义的public成员变量会Collider:Collider组件管理碰撞范围和表面属性,当GameObject上挂载了Collider走之后,物理引擎才将其作为物理实体进行碰撞检测。Collider本身并不是一ComponentBoxCollider、CapsuleCollider、SphereCollider等基本形状,还包括使用指定的网格模型进行碰撞的MeshCollider。当碰撞发生时,物理引擎向发生碰撞的两个GameObject上的所有MonoBehaviorOnCollisionEnter、OnCollisionStay、OnCollisionExit消息并且进ColliderTrigger选Exit消息,但是不执行物理计算[4];除此之外,UnityRayCast、SphereCast等方法提供主动的碰撞检测,碰撞范围可视化等功能,已经较为完备,版的Unity中,还包括了一套2D的物理组Unity提供了传统动画组件,在版中还引入了Mecanim动画控制状态机。传统Animation和AnimationState:Animation是动画的组件,是Component的子类。开发者必须将Animation挂载到GameObject上以AnimationClip。而每个AnimationClipAnimationAnimationState来控制当前动画实例的状态。AnimationState封装了动画的主要功能,包括正常的控制、速度控AnimationCurve:AnimationCurveAnimationClip中的一种资源,开者通过在关键帧添加AnimationEvent来实现侦听动画状态并且将逻辑绑定到动画上。AnimationEvent功能支持在到指定的帧时回调该GameObject上挂载的某个MonoBehavior类中的一个基本类型参数或者无参数方法[6]。Mecanim动画状态系统在传统动画组件的基础上,增加了动画状态机的功能,图2.4所示:每个动画都被作为一个状态块,动画之间的跳转被用白色箭头线标准。主其他的Unity原生动画组件方,难以根据特殊需求进行自定义,因此在本文中不作详细2.4MecanimUnityEditor文件夹,Unity将会自动将其中的文件归入编辑器工程内。开发者主要可以通过以下几ScriptableObject:开发者可以将ScriptableObject类,并且使用 ACTARPG类人物动作设计作为游戏设计的需求,其具体动作跳转图如图3.1所示:3.1kAttack3。3连击的动画不同,效果也不同。随着动作的不同,时角色也会当人物是受到时,人物根据受伤后HP数值,如果大于0则跳转到受伤状态,如果小于等于0,则跳转到Dead状态;360度回旋斩,周围所有的敌人,并且在玩家的摇杆引导下朝某个方向移动;或者Try的情况,游戏设计师经常会有一些天才的想法和设计需要验证,开发人员很难预测,当人物进行并且作出位移的时候,由于动作产生的位移应当尽可能真效果是正好敌人时发生的、敌人瞬间会感受到动作的停顿、被击打动画的快入慢回等。为了增强打击的效果,可以配合以一些火花的特效、镜头的、被GameObject在场景中产生,不再接受人物动ACT人物,游戏中各个元素与动画的精密配合是3.23.2Character人物控制器类:控制器类管理一个人物可能有的所有状态,并且根据StateControllerState的子类,并执行具Idle状态类,Move状态类,Attack状态类,Injured状SpecialCharacterStateCharacter只需要负责在不同类之间切换并且向CharacterState发送。公用逻辑产生问题,以图3.3的情况为例:3.3MoveStateSpecial2State共享,但是“判定盒接触敌人时发生”逻辑又被AttackStateSpecial1StateSpecial2State共享,MoveState、AttackState、Special1State却又不共享“键触发跳转到状态”等逻辑。且将子类逻辑写死在代码中的设计使得设计师依赖开发者去修改一些子类的逻辑,现,确实可以解决共些逻辑代码,也能简单地向设计师提供更大的自由度来管理每过多的类成员变量,另一方面State类中的方法也会过多,这都造成工程代码的,降低了可性,甚至会造能问题。可见这种架构并没有真正解决代码通用性和可性的思路:将逻辑与动画绑定。上文提到,UnityAnimationEvent的功能,GameObjectMonoBehavior成员方法,不带参数或者只有一个基本类型参数,而且该方法不能被重载,使用起来也非常不方便。相比之下,自己实现对动画管理的代价相对较小。因此,可作架构和有限状态机运行部分的功能。4.1的分离,它的主要职责变为管理当前状态的动画。因此称其为AnimatedState,并且是KeyFrame的聚合。主要职责即是该状态所指定的动画,并且向动画的帧发送开始Next指定的状态,Next可以为空表示无跳转操作,也可以为自身表示循环;Action是所有独立逻辑单元的抽象类,提供两个基本接口:ActionEnter在人物进入所KeyFrameActionExitKeyFrame被调用。新增一类逻四个类的协作关系:CharacterAnimatedState,并且维持其中一个处于运AnimatedStateAnimatedState管理多个KeyFrame,并且顺序;每个KeyFrame上都可以挂载Action,在被时激活这些Action;Action在激活时运行指定逻辑可以人物并且对其进行处理。与传统方法一:UnityAnimationClipAnimation窗口(如图4.2)将其通过对Unity文档的阅读和分析,Unity并没有提供编辑器内置的窗口实现UI元素绘制,要支持各种状头、DirectionalLight(定向光、SingletonofVirtualScreen(用以后期效果处理的抽象CharacterStateKeyFrameAction四层的层级结GameObject编辑方法已经完备,并且可以使用菜单快速扩展4.4最后,利用层级窗口实现状态可视化的开发代价是少量的,仅需要将状态逻辑挂载到具体的GameObject上即可。每个人物最顶层的GameObject上挂载Character,以该节点作为人物的根根节点之下有模型节点,节点名为模型名字berserker_model,由于模型名称并不确定,需要在Character中建立;另一个是状态表节点,以States命名,这个节点不需要挂载,其作用相当于一个文件夹,所有状态将会成为子节点被其收纳;态、Idle状态、Move状态,挂载State;动的瞬间空气摩擦、并且在挥动过程中拥有碰撞的逻辑,因此其状态下还建立了Frame8、Frame8to11的关键帧,以挂载这两个逻辑;点然后在Inspector中进行查看。Unity可视化开发设计的一条而是将层级窗口中挂载有State的状态节点拖至需要赋值的属性上,从根本上避免图4.5Character检视和拖拉效Character类属性检视效果如图CurStateCharacterNameDefendState、DefenseBrokenState、InjuredState、FallState、DeadState为一系指定。这些状态都需要通过拖拽StateListAttackRange为范围,预留以来控制AI行为转状态,CurFrame显示了当前帧便于调试。其他状态与动画有关,在下章中进行4.6AnimatedStateKeyFrame以及挂在的Action如图4.7所示,其中KeyFrame中的Always表4.7KeyFrame以及挂载的Action 类型,而对其感的类可以自由或者停止,使得处理者对产生者保持透明[8]。这种处理下,复杂的事务处理被分解,产生和处理逻辑独立开来,4.8逐级传递方法图4.8所示:Character将发送至当前活跃的State,State将发送给当前活跃的KeyFrame,而KeyFrame需要将转发给感的Action。不同的都使用不同接口,为了传递,在State和KeyFrame中也存在所有Action所需的接口的副本。4.9的询问机制:State通过询问当前活跃的所有KeyFrame来告知Character活跃Action,这使得State和KeyFrame不必要建立传递接其实状态机内部也可以使用同样的消息机制,由Action主动去Character子类而言,只需要在重载ActionEnter时感的event,在ActionExit停止同时向者和全局者发送。由于此处较多地依赖语言特性进行了代码实现,为了表现语言相关性,贴出如下代码:publicclassGameEvent<T>//定义一个模板类,T为类{publiceventSystem.Action<T>publicstaticeventSystem.Action<T>publicboollistened//检查是否有{get{returnOnEvent!=null||OnEventGlobal!=null;}//按源发送publicvoidSendEventMessage(T{if(OnEvent!=null)//向源的对象发if(OnEventGlobal!=null)//向全局此类型的对象发送}publicstaticvoidSendGlobalEventMessage(T{if(OnEventGlobal!=null)}}害Damaged为例,的定义代码实现如下:publicclass{publicCharactercharacter;//受伤人物publicCharactersender; //打击者publicInjuryInformationinjury;//信息}publicGameEvent<Damaged>onDamaged=new表.1状态功能的基本的名StateFrame般情况下StateUpdate与FrameUpdate都是每秒发送60各个,但是一旦动画将会进行State与Frame更新关系的详细解释。ActionKeyFrameKeyFrameState,同时Action自身的ActionEnter与ActionExit是强制的默认,具有一定特殊性,因此不使用GameEvent进行实现,而由KeyFrame进行直接调用接口的。关键帧算State管理多个KeyFrame,每当Character的更新来临时,State都得知动画播放了一帧,并且根据进入时动画始终从第0帧开始,因此可以迭代记录当前帧号,记录变量CurrentFrame。而每个KeyFrame都有记录开始帧号和结束帧号,记录变量StartFrame与EndFrameKeyFrameEndFrameStartFrame1。State管理和所有的KeyFrame表,当检查到对于某个KeyFrame,有CurrentFrame>=StartFrame&&CurrentFrameEndFrame时候,该关键帧为活动;否则即为非活动。而一个状态因跳转而中断的情况ListKeyFrame,即可得到KeyFrame的进入和退出。表.2关键帧交A34B5C8D9EIndex;IndexIndexKeyFrame遍历ActiveFrame表的简单方法。动画速率控对动画速率控制的需求来源于两方面。从美术上说,从数据上调整速率来避免资源的替换能够提高调试效率;而从游戏设计上说,改变动画以及整个状态的速度是一种常有的需求,比如一种增强魔法能够加速玩家的跑动速度和速度方。由于本多功能绑定,因此也要支持实现改变动画速度时,逻辑与关键帧的绑定不被破坏,KeyFrameActionState接受到人物更新消息时,加SpeedCurrentFrameDeltaFrameDeltaFrame1*AnimationSpeed。最后CurrentFrame到CurrentFrame+DeltaFrame之间的整数帧号,进行离散的Frame更新。率发生变化。State总是保持与物理引擎速度相同的频率进行更新;在Animation>1FrameUpdateAnimationSpeed1时,FrameUpdate的时间频率也降低,可能多个StateUpdate过程中仅包含一次FrameUpdate。区分这两种主要是为FrameUpdate,而一些不随动画速率改变的动作,例如“获得5秒无敌状态”等状态就需要StateUpdate。KeyFrame概念的引入,使得逻辑绑定动画的功能更加易用。利用层级窗口进行状可性。另外GameEvent机制的设置,使得处理对于发生保持透明,并且可且保证了工程的可性。要实现的功能包括处理玩家或者AI的输入、控制人物的物理运动、检测碰撞和打UI的交互等等。这里由于篇幅限制,仅选取开中最的部分即质量与效率的平衡,也较为针对所选的Unity平台,因此着重介绍。一个游戏最为的部分即是提供交互性,对输入的响应是重要的一步。而由于键,在空闲状态按下,触发的将是原地动作;而移动状态按下时,触发的是向的情况作为最早跳转帧为0的一个特例。由于本项目处于移动平台,输入都来源于触屏方式的UI按键,然后根据玩家转到空闲状态;另外在状态的末尾几帧,玩家可以使用拉下移动键提前进入移动状态。由具体应用中可见,需要提供属性以区分方向输入开始和方向输入结束。 5.1名floatButtonCommandCharacterButtonCommandCharacterButtonTypefloatButtonCommandCharacterButtonTypefloat以向输入方向慢慢移动但是不改变其角色面朝向,比如连续的360度回旋斩。然后根据以上类型的需求,分别建立对应的Action的子类,在子类逻辑中向实现效果如图5.1TransitionOnButtonEventEventType指定按键弹起或是按下、ButtonType指定按键类型、ToState指定跳转目标状态,ActionFrame指TransitionOnDirectionEventEventType指定摇杆输入弹起或是按下、ToState指定跳转目标状态。Unity中为了实现动态的碰撞检用Rigidbody的功能来实现。在XZ轴上的旋转角度。如图5.2。另外,RigidbodyDrag参数可以用来控制阻力,LinearVelocity能够直接控制运LerpLerprotationSpeedcharacter.transform.rotation=Quaternion.Lerp(character.transform.rotation,Quaternion.Euler(newVector3(0,character.targetRotation,0)),rotationSpeed*Time.fixedDeltaTime);RigidbodyLinearVelocity来实现Unity提供了AnimationCurve的曲线编辑器,但该编辑器是完全图形化的,没5.3当人物收到但未被击倒时,人物需要受伤动画,并且根据的推力适当当发生时,会调用Rigidbody的Add RigidbodyRigidbody被然而人物腾空到落地时,应当有地面后小小反弹,然后保持躺在地上的效果。为了使人物能够在落地时候进行跳转,此处定义了一个HitGround,当人物的碰撞盒重新接触地面时,就会发送一个HitTound,为了响应这个,建立一个TransitionOnHitGround的跳转,指定落地时跳转到的状态。这个和Action的的状态跳转来说,无需关心它需要多久才能洛回到地上,只需要使用TransitionOnHitGround跳转到指定的落地Pose状态,可以进行自由的设计。 5.4将的碰撞检测绑定到根据的形状将碰撞盒绑定到上,当挥动时,判定盒也跟随进行运动。在高速挥动的几帧内若的碰撞盒敌人时候便认为。这种方法不需的范围相当于一个扇形,而较小的碰撞盒在每一帧的停留不足以覆盖整个应[9](如图5.4:鱼处于剑扫过的范围上理应发生碰撞,但是剑两帧的碰撞范围均未与鱼。为了保证没有落网之鱼,需要使用连续的碰撞检测方法,性能开销较大。RayCastSphereCast方法,即仅有射线和球形检测,并且没有原生的可视化ColliderDisabled;而当关键帧活动时,果玩家时没有运动,就检查不到这此。经过,发现这是由于Unity的物理DisabledColliderEnabled时,Rigidbody并没有发生运动,所以刚EnableCollider时手动调用Rigidbody的WakeUp方法,强制将其激活,退出睡眠状态而进行碰撞检测。一些特殊形状之间的碰撞检测,会需要网状的相互碰撞算法。使用Unity已经给出的Collider形状已较为实用,并且可以通过多个Collider进行拼接来模拟稍显复杂的碰撞上,这些特效的实现逻辑互相独立,互不,在逻辑上也没有执行顺序的要求,可以利用机制来编写效果逻辑,并且提供对设计师来说更为直观的管理。5.5在真实世界中,拳头挥空和的时候是有区别的,在的一瞬间者会当时,者的动画将暂停,同时速度暂时为0;被者跳转到受的动画,然后暂停在受动画的第一帧,速度同样暂时为0,在暂停期间,人物的还要作小范围的相对于机视角的水平方向。暂停时间大约一般保持0.1秒以度恢复停帧的状态,被者因为接受了,速度会变为推力所带来的速度。击状态,人物状态由被规则而进行跳转。停帧状态(时录暂停前的动画速度,而在暂停时将动画速度暂时归0,结束后再恢复。对于停帧状态(被停帧状态在停帧状态基础上,再执行的效果。这种只是纯视觉效果,void{Vector3camForcamera.transform.forward;Vector3shakeNorm=newVector3(camFor.z,0,-//根据时间计算函数相floatphase=floatshakedTime=delayFrames*phase=Mathf.Cos(shakedTime*shakeFrequency*Mathf.PI*modelTransformRef.localPosition=shakeNorm*shakeDistance*} 实现了一个简单的shader,能够指定变化颜色,其主要原理是对像素器进行自身变白。通过流失时间来控制白色数,以达到按时间渐变的效果。由于没有对顶UnitySurfaceShaderShader代码编写即能够快速的相机的还分为两种形式,一个是位移,又称平动,相机保持拍摄的方向不变,进行上下左右二维的晃动;另一个是轴向,又称旋转,相机的位置不变,浩宇单纯使用位移,能够更好地模拟击打时的感觉,而位移用于、等好似受到冲击,给玩家更强力度反馈。为了制作较好的效果,此处采用Unity资值、位移幅度(向量、轴向幅度(向量而对每一个打击而言,都能分别设置不同的强度。5.6HUDUIUIUI的显示位置不是与UIHUD在游戏场景中GameObject的子节点进行管理,这样一来不仅所见即所得,而且已经实然而,UnityNGUIUIUI元素来显示效果会带来如3D2DUIRoot节点,会导致三维的场景和二维的节点交叉混合,破坏场景点统一性。NGUI机通常使用正交投影,而三维机都是投影,用不同的机拍HUD摆放摆放在目标位置不能真正让该HUD在游戏中切实地显示在响应的位置。HUDHUD被场景中的其它景物阻挡的问题,当3D2DUI有相当多的问题需要解决,最好能够找到其他UI跟随一个人物并且悬挂于该人物的头顶时,由HUD是一条捷径,在坚持这一点的情UI元素,同时在每帧更新时,将自身的屏幕位置投影到UI所在的机空间,并且主HUD显示的原理,而可以简单地认为这是一个嵌入三维场景中HUD,并且以子节点方式控制其跟随和相对位置。需要对人物的和绑定;缺点在于其更新过程需要进行矩阵计算。虽然有利有弊,但是在场景中HUD数量不多的情况下,性能损耗尚可接受。InfieldPanelUIHPNumberUI元素,更新其位置。UI组件进行更新,在C#编程中,使用event即可快速添加。然而,游戏中需要关注的参数太多,使用event一一为其建立的做法,每次修BUG在测试环节容易被发现,也容易修正,但是每次走一遍流程也会使效率降而且能够提高可性,减少错误发生的可能。那么这能否实现呢?这需要从C#语言上文也提到C#提供了event参数,能够方便地定义[11]。数值和定的event。Value属性的Set方法中将自动发出OnValueChange,OnValuepublicclass{publicMonitoredInt(int{_value=}[SerializeFieldprivateint_valuepublicintValue//给外界的Value属{get{return_value;}{intlastValue=_value=if(OnValueChangednull)在值改变时发送{}}}publicdelegatevoidOnValueChangedDelegate(intnewValue,publiceventOnValueChangedDelegateOnValueChanged;定义}MonitoredIntMonitoredInt类型的加减乘除运算符都需要重载。使得两个被监视符均进行重载,使得MonitoredInt能够与其他Int类型进行比较。C#implicitoperatorintInt类型的方法,重载了这个隐式转换之后,在需要使用Int作为参数的地方均可传入MonitoredInt。publicstaticimplicitoperatorint(MonitoredInt{return}publicoverridestringToString{return}由于C#不支持重载赋值操作符,每次修改MonitoredInt类型数值时,需要Monitored版本。这部分的代码的可UnityCollider组件可子节点控制的HUD以及参数监视类。法进行开发相比较,对工作流程的效率改善情况进评。20131219Glu在iOS平台上的《永恒战士3》作为参考[12],而主机平台上我们选取2008年1月31日在PS3、Xbox360上由公司的《鬼泣4》作为参考[13]。两状态切换的过渡处理表6.1所示:表.1主要动画切换过渡方法和效果4》中,主角的每一个招数后都能有数种后续的进攻方式,形成大量分支的4》中主状态起跑、跑步结束回到空闲、从状态末尾开始进入等等基本的过渡全部都是生切,而且生切前后的与动作趋势也都不相接近,效果极其生硬。只有连招状态之间的生切前后的基本能够衔接上。任何状态下释放技能也都没有过渡动画。Slash的效果如表6.2所示:表.24》中的角色在自由运动状态下都能做到动画与位移的完美配合,跑步、攻的演示人物,出招时,脚下位移配合人物动画快速上步前进,急速变缓的动作下,戏试玩并且对慢动作进行比对,对三款游戏的打击感细节做法如表6.3所示:《鬼泣4》作为老牌动作游戏厂商的优秀的主机平台动作游戏,其打击感各方面都相当到位,其中各种特效与的时机配合都非常完美,停顿特效改进表.3被人无无有有移和角度移和角度不同的范围,使得无论在挥舞过程中任意时刻敌人都能够发生准确的只是缺少闪白效果,稍稍减少了切实的感受。而《永恒战士3》的打击感有很大的问题,不仅时机稍早于动画,而且打击火花的位置只是简单地处理在被击物的中心、时间也是

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论