unity3d官方汽车教程的翻译版本car3.pdf_第1页
unity3d官方汽车教程的翻译版本car3.pdf_第2页
unity3d官方汽车教程的翻译版本car3.pdf_第3页
unity3d官方汽车教程的翻译版本car3.pdf_第4页
unity3d官方汽车教程的翻译版本car3.pdf_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

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

文档简介

TheTheTheThe CarCarCarCar TutorialTutorialTutorialTutorial PartPartPartPart 3 3 3 3 Creating a Racing Game for Unity 在Unity中创建赛车游戏 Part 3 Under the Hood 引擎盖之下 We ve covered how to assemble a working car from a 3d model scripts and built in Components We have also looked at the exposed variables and how they can be used to tweak the car s behavior 我们已经介绍了如何从3D模型 脚本和内建的组件开始组装一辆可以工作的汽车 我们也 看到披露出的变量和它们怎么被用来调整汽车的行为 Now it s about time we look more in depth at the fine mechanics inside the engine of the car The Car script 现在是时候我们来更深入的看看汽车引擎内的完美机械 汽车脚本 Double click on the Car jsCar jsCar jsCar js script to open it with your code editor 双击Car js脚本并在你的代码编辑器中打开它 This script can at first glance be a little intimidating spanning 500 lines of codes and comments and a lot of variables and functions Don t despair though The script is structured so that we have relatively small functions with meaningful names that does exactly what they say they do Following this the code is not littered with comments that explains everything again simply because the code is telling it s own story 这个脚本乍一看可能有点吓人 超过500行的代码和注释 并且有许多变量和函数 但不 要绝望 脚本已经被结构化了以便我们能得到一些相对小的且具有有意义的名字的函数 这 正是它们想说和想做的 在此之后 代码就不会到处都是再次解释每一件事情的注释了 很简单由代码来告诉我们它们的内容 The way we suggest you to look at it is to find the best entry points and then follow along In this case these entry points will be the Start Start Start Start Update Update Update Update and FixedUpdate FixedUpdate FixedUpdate FixedUpdate functions 方法是我们建议你找到一个最好的切入点 然后展开 这本例中这些切入点将会是Start Update 和FixedUpdate 函数 Each of these main functions are calling other functions So when we begin by looking at the Start Start Start Start function we see that the first function called is SetupWheelColliders SetupWheelColliders SetupWheelColliders SetupWheelColliders Locate that function in the code and study what it does andthengobacktoStart Start Start Start andgotothenextfunctionwhichis SetupCenterOfMass SetupCenterOfMass SetupCenterOfMass SetupCenterOfMass By following this code trail you get the overview over what is actually happening in code that makes the car work the way it does 每一个 main 函数都是用来调用其他函数的 所以当我们开始看Start 函数时 我 们看到调用的第一个函数是SetupWheelColliders 在代码中寻找那个函数并学习它是如 何做的 然后返回Start 函数继续下一个函数SetupCenterOfMass 循着这个代码线索 你将得到概括出在代码中实际发生了什么 这些和汽车的工作的方式一样 In the following we will look at all those functions We are not going to explain each line of code but we are providing an entry point and going through everything essential that takes place from the setup to what happens each frame So without further ado let us start at the beginning 在下面我们能看到所有这些函数 我们将不逐行解释代码 但我们提供了一个切入点和通过 在setup 时在每一帧中所发生的每一件必要的事情来了解 所以无需更多废话 让我们从 头开始吧 Which are the most important things 哪些是最重要的事情 Working inside Unity is easy in so many ways because of stuff like the editor the drag and drop workflow and all the built in components Setting up the Car is half way there Unity takes care of importing the model we get collision rendering and physics setup for us with just a few clicks to add the Components 在很多方面来说在Unity中工作是比较容易的 因为大家比较喜欢使用编辑器和拖拽所有内 置的组件来工作 在这里汽车是设置半成品 Unity照顾到了模型的导入 我们只是通过一 些单击增加了得到碰撞 渲染及物理设置的组件 Inside our script we are mainly working at manipulating these Components You will of course stumble upon a lot of calculations that we use to determine what happens to the car This is an unavoidable part of doing real games You have to setup some logic through for example scripting when you want to do more than just the basics But these calculations are just that Calculations to get the right values to feed to our Components 在我们的脚本中 我们主要的工作是维护这些组件 你当然会在许多我们用来确定汽车发生 了什么的计算前被绊倒 在做实际的游戏中这是一个不可避免的部分 你要通过例子脚本设 置一些逻辑 当你想要做的不仅仅是最基本的东西的时候 但这些计算仅仅是 计算并得到 正确的值提供给我们的组件 If you feel that the code is overwhelming and don t know where to start one approach could be to focus on the following items and consider most of what else is going on as something that affects and supports these items 如果你感到这些代码像一座大山并且不知道如何开始 一个方法是可以把目光放在以下项目 上 并考虑大多数那些可以影响和支持这些项目可以继续的事情 The RigidbodyRigidbodyRigidbodyRigidbody 刚体 The WheelWheelWheelWheel CollidersCollidersCollidersColliders 车轮碰撞体 The Calculations that we do and the order that we do them in 我们做的那些计算和我们做它们的顺序 Think of it like this 像这样的思考 By adding the rigidbody to our car model we have a way of controlling it in a physical way We do that by calculating the forces that drive it forwards and the forces that slows it down 通过给我们的汽车增加刚体使我们获得了在物理方式上控制它的一个方法 我们通过计算驱 动它向前的力和使它变慢 减缓下来的力来做到这些 By adding the Wheel Colliders we get control over where the Car meets the road 通过增加车轮碰撞器我们得到了汽车和路面相碰时的控制 Start the Setup设置 This is where we do the initialization needed for the car The Start Start Start Start function is executed only once in the beginning of the script before the UpdateUpdateUpdateUpdate functions Therefore Start is often used to set up the initial prerequisites in the code The first function we visit is 这里是我们需要在汽车中做初始化的地方 在脚本开始的时候 Start 函数仅执行一次 在Update 函数之前 因为在代码中Start 函数总是被是用来做初始条件的设置 所以第 一个函数我们先看它 SetupWheelColliders SetupWheelColliders SetupWheelColliders SetupWheelColliders 设置车轮碰撞器 We have four wheels attached to our car and we have put them into the FrontWheelsFrontWheelsFrontWheelsFrontWheels and Rear WheelsRear WheelsRear WheelsRear Wheels arrays from the Inspector In this function we create the actual colliders making the wheels interact with the surface below the car We start out in the function by visiting SetupWheelFrictionCurve SetupWheelFrictionCurve SetupWheelFrictionCurve SetupWheelFrictionCurve 我们的车上附着着四个车轮 在检查面板上我们把它们放在FrontWheels 前轮 和 Rear Wheels 后轮 数组中 在这个函数中我们建立一个实际的碰撞器 使得车轮与汽 车下面的地面进行交互 我们开始时是看SetupWheelFrictionCurve 函数 SetupWheelFrictionCurve SetupWheelFrictionCurve SetupWheelFrictionCurve SetupWheelFrictionCurve In SetupWheelFrictionCurve we simply create a new WheelFrictionCurveWheelFrictionCurveWheelFrictionCurveWheelFrictionCurve and assignitthevaluesthatwethinkareappropriateforourcar A WheelFrictionCurve is used by WheelColliders to describe friction properties of the wheel tire If you want to get serious with using Unity s built in WheelColliders stop by the documentation 在 SetupWheelFrictionCurve 函数中我们简单建立一个新的WheelFrictionCurve 并 且给它分配值对于我们的汽车来说我们认为是恰当的 一个WheelFrictionCurve 被车轮 碰撞器用来说明车轮轮胎的摩擦属性 如果你想获得使用Unity构造的车轮碰撞器重要内 容 停下看这个文档 WheelFrictionCurve 车轮摩擦曲线 从左图可以看出曲线可以分为三段 上升段 下降 段 水平段 按照 Unity 帮助说明 只取前两段 这个摩擦曲线的作用是根据这个曲线 输出一个随 时间变化的摩擦力 段的划分是以曲线某点的切线 的斜率为 0 为标准划分的 即 0 Extremum 极 值点 和 Extremum 极值点 Asymptote 渐 进点 这个滑动计算完全是建立在一个物理摩擦 模型基础上的 extremumSlip极值点滑动值 默认为 1 extremumValue极值点摩擦力值 默认 20000 asymptoteSlip渐进点滑动值 默认 2 asymptoteValue渐进点摩擦力值 默认 10000 stiffnessMultiplier极值点摩擦力值和渐进点摩擦力值的刚度系数 默认值 1 WheelFrictionCurve 会被用在 WheelCollider 对象中 例如 wfc new WheelFrictionCurve wfc extremumSlip 1 wfc extremumValue 50 wfc asymptoteSlip 2 wfc asymptoteValue 25 wfc stiffness 1 var wc WheelCollider go AddComponent typeof WheelCollider as WheelCollider wc sidewaysFriction wfc 轮子的摩擦曲线实例赋给碰撞器的侧向摩擦属性 而 摩擦 曲线 会被 放在 WheelCollider 的 WheelCollider forwardFriction 向前 摩擦 和 WheelCollider sidewaysFriction 侧向摩擦 属性中 在本教程中可以看出 只考虑了侧向摩 擦 SetupWheel SetupWheel SetupWheel SetupWheel 设置车轮 After setting up the curve we are back in SetupWheelColliders SetupWheelColliders SetupWheelColliders SetupWheelColliders ready to create the actual colliders and Wheel objects This is done by calling the function SetupWheel SetupWheel SetupWheel SetupWheel for each of our wheels If you look at that function you will see that it takes two parameters A Transform and a boolean and returns a Wheel object What we do is that we feed this function with the transform of each of our wheel transforms and stating whether or not this wheel is a front wheel The function then creates and returns a Wheel object that we put into our wheelswheelswheelswheels array which holds all our wheels for the rest of the script 在设置了曲线之后 我们返回到SetupWheelColliders 函数 准备建立一个实际的碰撞器 和车轮对象 这是通过每一个车轮调用SetupWheel 函数来完成的 如果你看那个函数 你将看到它带了两个参数 一个空间变换参数和一个布尔值参数 并且返回一个车轮对象 我们做了什么呢 我们给这个函数提供了每一个车轮的空间变换 并且说明不管这个车轮是 不是前轮 这个函数然后建立并返回一个车轮对象 我们把它放到我们的车轮数组中 那里 放置了所有我们在脚本中其余的车轮 for var t Transform in frontWheels wheels wheelCount SetupWheel t true wheelCount Inside SetupWheel SetupWheel SetupWheel SetupWheel it s actually rather simple what we do We create a new GameObject and give it the same position and rotation as the wheel we are currently processing Then we add a Wheel Collider component to that GameObject SetupWheel 函数内 我们做的实际上相当简单 我们建立一个新的游戏对象并且给它 一个我们当前进程中与车轮相同的位置和旋转 然后我们给游戏对象增加一个车轮碰撞器组 件 We set the properties of the WheelColliderWheelColliderWheelColliderWheelCollider from the suspension variables that we discussed when we tweaked the car the suspension range spring and damper 我们根据悬挂变量来设置车轮碰撞器的属性 那些在我们调整汽车时讨论过的 悬挂范围 弹簧和阻尼器 Then we create a new WheelWheelWheelWheel object and feed it the properties it needs The collider we created the WheelFrictionCurve the graphics for the wheel which is the DiscBrakeDiscBrakeDiscBrakeDiscBrake object we dragged to the inspector when we set up the car and the graphics for the tire which is the child of the DiscBrake 然后我们建立一个新的车轮对象并给他提供必须的属性 我们建立的碰撞器 摩擦曲线 车 轮图像 那里有在我们设置汽车时拖拽到检查面板上的盘式制动器对象 和轮胎图像 盘式 制动器的子对象 We set the radius of the wheel automatically based on the size of the tire 我们自动设置车轮的半径 基于轮胎的尺寸 wheel collider radius wheel tireGraphic renderer bounds size y 2 Finally we check whether the wheel we just created is a front wheel or a rear wheel by looking at the truetruetruetrue or falsefalsefalsefalse value that we passed to the SetupWheel SetupWheel SetupWheel SetupWheel If it is a rear wheel we set its drive Wheel variable to true and if it is a front wheel we instead set its steerWheel variable to true 最后我们检查我们刚刚创建的车轮是否是前轮和后轮 通过查看我们传递给SetupWheel 函数的值是True还是False 如果它是后轮 我们设置它的驱动轮变量为真 如果是前轮我 们替代的设置是转向轮变量为真 steerWheel 翻译成转向轮 Later in the code we are making sure that the car can only drive if at least one of the drive wheels are touching the ground and only steer if at least one steer wheel is on ground 在后面的代码我们确保车在至少一个驱动轮接触地面时才能被驱动 并且至少有一个转向轮 在地面上 Additionally we do a little manoeuvre for the front wheel by creating an extra game object that we put in between the frame of the car and the wheel This is the Steer Column that we use later when we rotate the wheel when turning Then we return the created wheel which gets put into the wheel array back in SetupWheelColliders SetupWheelColliders SetupWheelColliders SetupWheelColliders and when we have processed all wheels we exit the function and go back to Start Start Start Start Steer Column 转向杆 另外我们通过创建一个放置在车架和车轮之间的额外的游戏对象 对前轮使了个小花招 这 是一个以后当我们旋转车轮在转弯时用的转向杆 然后我们返回一个创建的车轮并把它放到 车轮数组中返回到SetupWheelColliders 函数中 并且当我们处理完所有的车轮 我们退 出这个函数返回到Start 函数 SetupCenterOfMass SetupCenterOfMass SetupCenterOfMass SetupCenterOfMass 设置质心 This is the next function that we visit This is a very small function that set the rigidbody s center of mass to the CenterOfMassCenterOfMassCenterOfMassCenterOfMass Game Object that we created earlier If the center of mass has not been set the rigidbody will use the default that Unity calculates 这是我们访问的下一个函数 这是一个非常小的函数 它给我们早前建立的CenterOfMass 游戏对象设置质量的刚体中心 如果质量中心没被设置 刚体将使用缺省的Unity计算结果 Then we convert the top speed entered in the inspector using a small utility function 然后我们使用一个小的工具函数转换在检查面板上输入的最高速度 topSpeed Convert Miles Per Hour To Meters Per Second topSpeed The function just multiplies the topSpeedtopSpeedtopSpeedtopSpeed variable with the number 0 44704 which translates it to meters per second This is setup so that we can input the desired speed in the inspector in miles per hour When calculating physics we operate with meters second We also have a small function doing the inverse calculation which is useful if you for instance want to output the speed of the car in miles per hour 这个函数只给topSpeed 最高速度 变量乘了个0 44704 翻译成米 秒 这个设置是为 了使我们能在检查面板上按公里 每小时输入速度 在物理计算时 我们按米 秒操作 我们 也可用一个小的函数做逆运算 这是有用的 例如 如果你要输出以英里每小时的车速 SetupGears SetupGears SetupGears SetupGears 设置档位 Gears are automatically setup in this function by assigning a top speed to each gear and calculating how much force is needed to accelerate the car to that given speed at each gear The force is calculated using the friction and drag values supplied in the public variables which means that this calculation is basically a linear z axis version of the friction calculation in the update functions A factor is multiplied on this force value to ensure that the car will accelerate to a speed higher than the ones assigned as thresholds for the gears 档位式在函数中当给每个档位分配了最高速度后系统自动设置的 并计算了需要多少力来加 速汽车 该给每个档位多大速度 该力是使用了提供的公共变量中的摩擦力和阻力来进行计 算的 这意味着这个在Update函数中的计算基本上是一个线性Z轴版本的摩擦力计算 一 这个力乘了个乘数因子是要确保汽车将加速到一个比给档位分配的那些阈值更高一些的速 度 SetUpSkidmarks SetUpSkidmarks SetUpSkidmarks SetUpSkidmarks 设置盘式制动器 This function finds the Skidmark game object in the scene and stores a reference to it and to it s ParticleEmitter used for smoke The code for the skidmarks is not covered in this tutorial but that shouldn t stop you from opening the script and investigate it on your own At the end of Start Start Start Start we assign the x value of our dragMultiplier array to a variable 这个函数是在场景中寻找盘式制动器游戏对象并且给它存一个参数 给它一个发烟的粒子系 统 盘式制动器的代码没包括在这个教程中 但这不能阻止你打开这个脚本和组织你去调查 它 在Start 函数的结尾 我们分配了一个我们的阻力系数数组的X值给一个变量 initialDragMultiplierX dragMultiplier x This is stored because we modify the x variable of the dragMultiplier when we are using the handbrake and then need to go back to the initial value again when we are not hand braking 这个存储是因为当我们是使用手刹时我们修改了阻力系数的X值 当我们不再使用手刹时w 我们呢需要再次返回到它的初始值 That s it for setting it all up in the Start Start Start Start function Now we ll move on to the main loop of the script in the Update functions which is what happens in each frame 这是它的设置 都在Start 函数中 现在我们将移动脚本的主循环到Update 函数中 每一帧都会发生什 Update GetInput GetInput GetInput GetInput The first thing we do in each frame is to read the user s input by calling the function GetInput GetInput GetInput GetInput The first two lines reads the vertical and horizontal axes and stores it in our throttle and steer variables 在每一帧里我们首先做的是通过调用GetInput 函数来读取用户的输入 首先两条线读垂 直和水平并存储它们到我们的牵引力和转向变量 throttle Input GetAxis Vertical steer Input GetAxis Horizontal The vertical and horizontal axes can be setup in Unity s Input Manager EditEditEditEdit ProjectProjectProjectProject SettingsSettingsSettingsSettings InputInputInputInput By default the vertical axis is set to the keys w and up arrow in the positive direction and s and down arrow for the negative direction and the value that we read here is used to apply the throttle force later The horizontal axis is set as the keys a and left arrow in one direction and d and right arrow in the other used for steering 垂直和水平轴能在Unity的输入管理中设置 Edit Project Settings Input 缺省 的垂直轴被设成 W 键和 up arrow 键正方向 S 键和 down arrow 为负方 向 我们读这些值以后应用到牵引力上 水平轴设置为 a 和 left arrow 为正方向 d 和 right arrow 为负方向 在其它中用来操纵控制 CheckHandbrake CheckHandbrake CheckHandbrake CheckHandbrake 检查手刹 After reading the input for controlling the car we call the CheckHandbrake CheckHandbrake CheckHandbrake CheckHandbrake function This is a specific function that checks if the space key is down and applies some logic accordingly 读完控制汽车的输入 我们调用CheckHandbrake 检查手刹函数 这个特殊的函数检查 如果空格键被按下 就执行一些逻辑代码 When we initially press space we set the handbrake variable to true starts a handbrake timer and changes the dragMultiplier x value making the car handling more shaky resembling hand braking As long as we keep on holding space nothing more will happen since the handbrake variable is now set to true 当我们在按下空格初始化时 我们设置手刹变量为真 开始一个手刹计时器并且改变 dragMultiplier x的值 使得汽车的操控更加不稳 像用手刹车 当我们继续按住空格 什么事都不会发生 因为手刹变量现在已经设为真了 When space is not registered as being pressed the code in the else block will be executed but only if handbrake is set to true This again means that the code will only happen when the user first lets go of space because we set the handbrake variable to false inside the block The coroutine StopHandbraking StopHandbraking StopHandbraking StopHandbraking will then be started 当空格键没有按下的时候 代码中的else块被执行 除了手刹变量被设为真 只有当用户离 开空格键才会再次执行这段代码 因为我们设置了手刹变量为假 同步StopHandbraking 函数这时将会开始 StartCoroutine StopHandbraking Mathf Min 5 Time time handbrakeTime StopHandbraking StopHandbraking StopHandbraking StopHandbraking 停止手刹函数 StopHandbraking StopHandbraking StopHandbraking StopHandbraking takes an input variable specifying the number of seconds it should spend on getting the dragMultiplier x back to it s initial state This value is given to it as the minimum of 5 and the handbrake timer that we started when we began handbraking The function then spends the specified amount of seconds getting the dragMultiplier x value back from it s current value to the initial value that we stored at the end of the Start Start Start Start function making the car handling normal again 停止手刹函数带来一个指定秒数的变量 它应该花在获得dragMultiplier x 的值并返会给 它的初始化状态 手刹时间的最小值是5秒 这个函数花费指定的秒数来获得 dragMultiplier x 的值返回个它的当前值 在start 函数的结尾我们存储了它的初始值 可以使汽车再次恢复正常操作 Check If Car Is Flipped Check If Car Is Flipped Check If Car Is Flipped Check If Car Is Flipped 检查汽车是不是翻了 Back in UpdateUpdateUpdateUpdate we now call the function Check If Car Is Flipped Check If Car Is Flipped Check If Car Is Flipped Check If Car Is Flipped to perform the Turtle check Inside that function we check the rotation of the car It s perfectly valid for the car to be flipped over or twisted in extreme angles for example if we a crashing or doing some kind of insane stunt but we want to eliminate the possibility that the car ends in a position where we can t drive anymore Therefore we check if the rotation is at an angle where the car is not drivable anymore and if it is we add the time since the last frame to the resetTimerresetTimerresetTimerresetTimer variable 返回 Update 函数我们现在调用Check If Car Is Flipped 函数执行 乌龟检查 在这个函数中我们检查汽车的旋转 对于汽车翻转和严重倾斜来说这个函数是完美有效的 举个例子我们有个碰撞或疯狂的特技之类的 但我们想在最后消除翻转后什么都不能驾驶了 的这种情况的可能性 如果是这样 我们给resetTimer变量增加自最后一帧以来的时间 X Y Z分别描述绕三个坐标轴的旋转角度 0 360 这三个角度称为欧拉角 绕X轴旋转的角称为俯仰角 pitch 绕Y轴旋转的角称为翻滚角 head或yaw 绕Z轴旋转的角称为摇摆角 roll 这里是用了判断摇摆角超过了80 小于280 且在这个状态下的时间大于resetTime 即判 断为侧翻 我猜想 看到这里你已经有了别的判断方法了 if transform loca

温馨提示

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

评论

0/150

提交评论