美文网首页
Unity强化篇(十) —— 基于Unity 2D的Pinbal

Unity强化篇(十) —— 基于Unity 2D的Pinbal

作者: 刀客传奇 | 来源:发表于2020-07-19 08:59 被阅读0次

    版本记录

    版本号 时间
    V1.0 2020.07.19 星期日

    前言

    Unity是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。Unity类似于Director,Blender game engine, Virtools 或 Torque Game Builder等利用交互的图型化开发环境为首要方式的软件。其编辑器运行在Windows 和Mac OS X下,可发布游戏至WindowsMacWiiiPhoneWebGL(需要HTML5)、Windows phone 8和Android平台。也可以利用Unity web player插件发布网页游戏,支持Mac和Windows的网页浏览。它的网页播放器也被Mac 所支持。网页游戏 坦克英雄和手机游戏王者荣耀都是基于它的开发。感兴趣的看下面几篇文章。
    1. Unity强化篇(一) —— 如何使用Vuforia制作AR游戏(一)
    2. Unity强化篇(二) —— 适用于Unity的HTC Vive教程(一)
    3. Unity强化篇(三) —— 适用于Unity的HTC Vive教程(二)
    4. Unity强化篇(四) —— Unity 和 Ethereum(一)
    5. Unity强化篇(五) —— Unity 和 Ethereum(二)
    6. Unity强化篇(六) —— 使用Unity和Photon进行多人游戏简介(一)
    7. Unity强化篇(七) —— Unity Sprite Shapes简介(一)
    8. Unity强化篇(八) —— 使用Unity运行时网格操作(一)
    9. Unity强化篇(九) —— Shader Graph简介(一)

    开始

    首先,我们看下写作内容:

    在本教程中,您将学习如何使用Unity2D技术通过排序组(sorting group),网格编辑器(mesh editor)等来构建老式的弹球游戏(pinball game)。内容来自翻译

    下面看下写作环境:

    C# 7.3, Unity 2019.3, Unity

    下面就是正文了。

    在本Unity 2D技术教程中,您将学习在Unity中构建2D游戏的高级技巧。学习如何在构建史诗般的老式弹球游戏“ Snap and Strike”时应用这些技术!

    如果您觉得本教程太高级,请先在Unity 2D游戏中研究此入门指南,然后再在Unity 2D教程中How to Make a Game Like Jetpack Joyride in Unity 2D开始。完成后,请返回并进一步提高2D Unity技能。

    本教程中的脚本编写很少,但是如果您具有C#编程的基本知识,则将更容易理解。要提高技能,请查看我们的Introduction to Unity Scripting教程。

    注意:本教程假定您熟悉使用Unity,并且了解使用Unity UI的方式。如果您不是,请花些时间先阅读我们的Introduction to Unity UI指南。

    在完成本教程时,您将了解更多有关以下内容的信息:

    • Sorting groups
    • Sprite masks
    • 9-slice sprites
    • 2D colliders and joints
    • The mesh editor
    • Types of effectors and 2D physics materials

    是时候让球滚动了!

    确保您使用的是Unity版本2019.3,可以通过Unity Hub下载。

    解压缩材料并在Unity中打开starter项目。 项目启动后,请切换到Scene视图,并确保您使用的是2D模式。

    1. Exploring the Starter Project

    首先浏览该项目。

    Assets / RW / Scenes中双击PinballWizard场景。 在层次结构中,您可以看到GameObjects分为以下类别:

    • SoundObjects
    • Main camera
    • Hotspots
    • Static colliders
    • Static panel
    • Animations

    单击Play,然后查看弹球表的当前状态。

    好吧,事情肯定很有趣! 但是图像目前正在互相争斗以在屏幕上渲染。

    您的第一个任务是调整最后三个组的Sorting Layer,以便它们以正确的顺序渲染。

    2. Adjusting Your Sorting Layers

    排序组(Sorting Group)是用于创建合并的Sorting Layers的一组组件。 即,预制件(prefab)的多个实例在不同的分类层上具有多个对象。

    此项目中的Sorting Layers应按以下顺序排列:

    • Panel (lowest layer)
    • Efx
    • Logo
    • Obstacles
    • Top
    • Cover (highest layer)

    现在,如下调整您的排序层Sorting Layers

    • 1) Static colliders - 静态碰撞器:这些具有碰撞器的对象构成弹球台的基本碰撞结构。 此处不需要排序组。
    • 2) Static panel - 静态面板:该组中的内容被隐藏。

    要显示该组,请在层次结构中选择Static Panel。 然后,单击Add Component,然后选择Rendering ▸ Sorting Group。 在新添加的Sorting Group组件中,找到Sorting Layer下拉菜单,然后选择Panel

    • 3) Animations - 动画:在“层次结构”中选择Animations,然后单击Add Component。 然后,选择Rendering ▸ Sorting Group

    Sorting Layer下拉列表中,选择Efx,然后单击Play

    您会发现弹球游戏的大多数细节已经在入门项目中。 现在该玩些有趣的东西了:添加动作!


    Getting the Ball Rolling

    首先,您需要创建一个空的GameObject来保存您的作品。

    通过在层次结构中右键单击空白空间,然后选择Create Empty来执行此操作。 现在,将新对象命名为Interactive Parts

    在检查器中,通过单击“设置”图标并选择Reset来重置其Transform值。

    接下来,再创建七个空的GameObject作为Interactive Parts的子代,并将其命名为:

    • ScrollingTrees
    • BillBoard
    • Plunger
    • Flippers
    • Float Piece Area
    • Road Tunnel Zone
    • Bumpy Parts

    确保还重置所有Transform值。

    注意:通过选择Interactive Parts游戏对象并按Alt-Shift-N来创建子游戏对象,可以快速创建这些游戏对象。 然后使用Control / Command-D将其复制六次! 然后剩下的就是重命名每个GameObject


    Scrolling Trees

    接下来,您将使用Sprite Mask仅显示动画的一部分。 看起来像这样:

    方法如下:

    • 1) 转到Assets / RW / Sprites,将trees_circle拖动到Hierarchy中的ScrollingTrees上,并将该sprite实例命名为TreeCircle
    • 2) 在检查器中,将Transform Position设置为(X:-0.7,Y:2.2,Z:0),并将其Rotation设置为(X:0 Y:0 Z:17)
    • 3) 在层次结构中右键单击ScrollingTrees,选择2D Object ▸ Sprite Mask,并将其命名为TreeMask
    • 4) 将Transform Position设置为(X:-1.91,Y:2.58,Z:0)并将缩放比例设置为(X:1.48,Y:1.58,Z:1)
    • 5) 在检查器中,转到“ Sprite Mask”组件的“ Sprite”字段,单击circle图标以启动Sprite资产列表,然后选择“trees_mask”
    • 6) 在层次结构中选择TreeCircle。 使用检查器找到Sprite Renderer,然后从Sorting Layer下拉列表中选择Efx。 从Mask Interaction下拉菜单中,选择Visible Inside Mask

    1. Scripting the Animation

    放置好图形后,就该添加控制动画的脚本了。

    双击Assets / RW / Scripts / AnimateController在代码编辑器中将其打开。

    在现有变量下面添加以下变量:

    public GameObject treeObject;
    private float turnSpeed = 30f;
    

    FixedUpdate下添加:

    private void FixedUpdate()
    {
        if (treeObject != null)
        {
            treeObject.transform.Rotate(new Vector3(0f, 0f, turnSpeed * Time.fixedDeltaTime));
        }
    }
    

    这样,无论播放器的帧频是30 FPS60 FPS还是在两者之间波动,都以一致的速度旋转分配给treeObject变量的精灵。 turnSpeed使您可以调整树木旋转的速度。

    注意:您可以在官方的Unity文档中了解有关FixedUpdate的更多信息。

    单击保存,然后返回到Unity。

    在层次结构中选择ScrollingTrees,单击Add Component,然后选择Scripts ▸ Animate Controller。 然后将TreeCircle从检查器拖到Tree Object字段中。

    单击Play预览新的工作动画。


    Adding the Billboard

    如果您无法超越自己的最后成绩,那就没有理由打弹球了! 为了帮助您做到这一点,您接下来将添加一个动画广告牌,其中包括闪烁的灯光。

    打开Assets / RW / Sprites / ani_billboard并将aniBillbord0001拖动到层次结构中的BillBoard中。 将子实例命名为AniBillboard

    Sorting Layer下拉列表中,选择Top。 单击Add Component,然后选择Miscellaneous ▸ Animator

    在检查器中,打开AnimatorController字段,然后单击旁边的circle图标以启动动画师控制器列表。 选择ani_Billboard

    Menu ▸ Window中打开Animation窗口,然后单击Play以预览广告牌的外观。

    9-slice sprite是另一种有用的2D技术。 调整大小时,此功能保留图形元素的角和边界。

    转到Assets / RW / Sprites / ani_billboard并选择一个精灵。 在检查器中,单击Sprite Editor图标以编辑精灵的可拉伸部分。

    用于此动画的精灵带有9片精灵,因此现在调整大小将不再是问题。 !

    这是在广告牌上使用9片切片的效果:

    1. Placing the Billboard

    现在,您需要将广告牌放置在弹球机上。

    转到层次结构中的AniBillboard,将其“位置”的Transform值设置为(X:1.5,Y:4.3,Z:0),并将其Scale更改为(X:-3.5,Y:2,Z:1)

    嗯...有点大,不是吗? 要解决此问题,请将“ Sprite Renderer”中的Draw Mode设置Tiled,将Size设置为Width:1 Height:1。 在Tile Mode下拉菜单中,选择Adaptive

    好多了!

    2. Adding the Score

    通过转到Assets / RW / Prefabs,将scoreText拖动到“层次结构”中的Billboard并将其比例更改为(X:0.41,Y:0.4,Z:1),将分数添加到您的广告牌中。

    单击Play以其时尚的新动画广告牌预览您的弹球游戏!


    Adding the Ping!

    设置好“bling”后,就该将“ping”添加到运动场了! 换句话说,您需要添加使游戏有趣的对撞机。

    首先转到“层次结构”,然后将“BumperRamps”“ CurveRamp”Static Colliders移动到Interactive Parts中。


    Adding the Plunger

    玩弹子球的第一件事就是plunger,这样您就可以从桶中射出一个球并开始游戏!

    在现实世界中,玩家会拉回与弹簧圈啮合的柱塞。 释放后,弹簧线圈将球推入运动场。 您希望在应用程序中拥有相同的感觉。

    要实现这些机制,请在“层次结构”中选择Plunger。 在Inspector中,添加Rendering ▸ Sprite Renderer组件。

    选择Sprite Renderer组件,单击Sprite字段旁边的circle图标,然后将cam资源分配给它。 将Sorting Layer设置为Top,并将Transform Position设置为(X:2.66,Y:-4.6,Z:0)

    现在,考虑一下plunger的物理原理。 这是一个有两个要素在起作用的春天:

    • The anchor - 锚点:锚固关节的活动部分,从而建立张力。
    • The spring joint - 弹簧接头:接头的运动部分,可产生力。

    接下来,您将需要执行物理操作,以使plunger表现出预期的效果。

    1. Adding the Anchor

    转到Assets / RW / Prefabs,然后将plungerAnchor拖动到层次结构中的Plunger中以创建子实例。 在检查器中,添加Physics 2D ▸ Rigidbody 2D并将其Body Type设置为Kinematic以固定其位置。

    2. Adding the Spring Joint

    现在,您已经创建了锚点,是时候创建spring joint了。 这就像拉回并启动plunger的弹簧一样。

    为此,请单击层次结构中plungerAnchor旁边的箭头符号以显示其嵌套内容。 选择Plunger-springjoint,然后通过Inspector向其中添加一个Spring Joint 2D

    确保选择2D Spring joint选项!

    注意:所有2D Joint组件均带有强制性的刚体2D(Rigidbody 2D)

    Rigidbody 2D中,将Body Type设置为Dynamic,将Mass设置为2

    展开Constraints部分,为“X”启用Freeze Position,为Z启用Freeze Rotation

    “Spring Joint 2D”中,选中Enable Collision。 禁用自动配置距离(Auto Configure Distance)。 将距离Distance设置为1,将Frequency设置为10

    Connected Anchor设置为(X:0,Y:-1),并将plungerAnchor分配为组件的Connected Rigid Body

    在层次结构中,将Assets / RW / Prefabs / plungerEffects拖动到Plunger对象中。 这将创建一个子对象实例。

    3. Adding the Plunger Script

    最后,是时候控制您添加到plungerspring joint中的物体了。

    在检查器中,仍然选择Plunger-springjoint,单击Add Component ,然后选择Scripts ▸ Launcher。 双击以在代码编辑器中启动它。

    在现有变量下面声明以下变量:

    private SpringJoint2D springJoint;
    private Rigidbody2D rb;
    private float force = 0f;          // current force generated
    public float maxForce = 90f;
    

    然后,在Start末尾添加以下内容:

    springJoint = GetComponent<SpringJoint2D>();
    springJoint.distance = 1f; 
    rb = GetComponent<Rigidbody2D>();
    

    Update中的//#1之后,添加以下行:

    // calculates current force of exertion
    force = powerIndex * maxForce;
    

    最后,在类末尾添加以下FixedUpdate

    private void FixedUpdate()
    {
        // When force is not 0
        if (force != 0)
        {
            // release springJoint and power up
            springJoint.distance = 1f;
            rb.AddForce(Vector3.up * force);
            force = 0;
        }
    
        // When the plunger is held down
        if (pressTime != 0)
        {
            // retract the springJoint distance and reduce the power
            springJoint.distance = 0.8f;
            rb.AddForce(Vector3.down * 400);
        }
    }
    

    保存文件并返回到Unity

    plungerEffects实例中的plungerEfxZoomplungerEfxLight分配给组件的区域。 将Max Force设置为200

    4. Test Your Work

    现在,您就可以测试您的新工作的pinball plunger了。

    Assets / RW / Prefabs / ball拖到层次结构中以创建实例。 将其Transform Position设置为(X:2.84,Y:-1.08,Z:0)。 单击Play,然后按下并释放空格键以测试您的plunger

    现在,您正在滚动!


    Adding the Flippers

    现在,球从枪管射出,进入比赛区,然后从底部掉落并进入太空。

    是时候添加flippers了 - pinball胜利的主要武器! 您将从左侧的flipper开始。

    在层次结构中,右键单击Flippers,然后选择Create Empty。 重命名GameObject FlipLeft-hingejoint。 在检查器中,将Transform Position设置为(X:-1.26,Y:-3.8,Z:0),将Scale设置为(X:1.05,Y:1.05,Z:1)

    对于右flipper,复制左flipper,并将其重命名为FlipRight-hingejoint。 将其位置设置为(X:0.46,Y:-3.8,Z:0)

    再次考虑一下flippers将如何工作。 就像plunger一样,只是这一次您需要使用以下组件旋转flippers

    • Hinge joints - 铰链接头:在旋转点处固定可移动部件。
    • Flipper:活动的flipper-y部分。

    接下来,转到Assets / RW / Prefabs,然后将flipperLeft预制件拖入FlipLeft-hingejoint,并将flipperRight预制件拖入FlipRight-hingejoint

    1. The Hinge Joints

    在层次结构中选择FlipLeft-hingejoint。 转到检查器并添加一个Hinge Joint 2D。 将“刚体”的Body Type设置为Kinematic。 这使该关节成为flipper的固定旋转点。

    Hinge Joint 2D中,将flipperLeft实例指定为其Connected Rigid Body

    启用Use Limits,然后将Angle Limits设置为“下限”为-30,将“上限”设置为30

    突击测验! 由于Left HingeJoint的旋转极限在-30至30度之间,您认为Right HingeJoint的旋转极限应该是什么?

    FlipRight-hingejoint创建一个新的Hinge Joint 2D组件。 将其Rigidbody 2D Body Type设置为Kinematic

    Right HingeJointAngle Limits为:下限:30和上限:-30

    请记住,将flipperRight实例分配为其Connected Rigid Body

    2. Adding a Script to Flip

    现在,添加脚本以使flippers正常工作。

    Assets / RW / Scripts中打开FlipControlLeft.cs

    在现有变量下面声明以下变量:

    public float speed = 0f;
    private HingeJoint2D hingeJoint2D;
    private JointMotor2D jointMotor;
    

    Start中添加以下内容以获取您的参考:

    hingeJoint2D = GetComponent<HingeJoint2D>();
    jointMotor = hingeJoint2D.motor;
    

    然后,在FixedUpdate中的if语句中,添加代码以接合joint’s motor

    // set motor speed to max
    jointMotor.motorSpeed = speed;
    hingeJoint2D.motor = jointMotor;
    

    最后,将else语句添加到同一块block中:

    else
    {
        // snap the motor back again
        jointMotor.motorSpeed = -speed;
        hingeJoint2D.motor = jointMotor;
    }
    

    尝试为右flipper重复上述代码:

    • 1) 声明所需的变量,以访问对象的HingeJoint2DJointMotor2D组件。
    • 2) 创建一个变量,该变量存储电动机的速度值。
    • 3) 在FixedUpdate中侦听用户交互并触发其motor速度。

    唯一的区别是,您翻转了速度变量,因为您以另一种方式旋转了flipper

    FlipControlRight.cs中,声明相同的变量:

    public float speed = 0f;
    private HingeJoint2D hingeJoint2D;
    private JointMotor2D jointMotor;
    

    Start中存储你的引用

    hingeJoint2D = GetComponent<HingeJoint2D>();
    jointMotor = hingeJoint2D.motor;
    

    FixedUpdate中的if语句中,添加:

    // set motor speed to max
    jointMotor.motorSpeed = -speed;
    hingeJoint2D.motor = jointMotor;
    

    最后,添加其余的else语句到相同的block中:

    else
    {
        // snap the motor back again
        jointMotor.motorSpeed = speed;
        hingeJoint2D.motor = jointMotor;
    }
    

    保存文件并返回到Unity

    将脚本组件FlipControlLeft附加到FlipLeft-hingejoint,将FlipControlRight附加到FlipRight-hingejoint。 将其速度值设置为1700

    单击Play,然后使用左右箭头键尝试使用flippers


    Road Tunnel Zone

    如果您能够将球插入,则在运动场顶部的弯曲轨道会增加球进入CurveRamp的机会,从而获得更多分!

    在此步骤中,您将在入口处创建一个涡流,将球吸进隧道,并在另一端吐出。 呜!

    1. Force Field With Area Effector 2D

    将球实例的Transform Position设置为(X:-2.28,Y:1,Z:0)。 在层次结构中,右键单击Road Tunnel Zone,然后选择Create Empty。 将此对象命名为Force Field

    单击Add Component,然后选择Physics 2D ▸ Polygon Collider 2D

    在检查器中,单击Edit Collider图标,然后将矢量移动到隧道入口之外的区域。 启用Is TriggerUsed By Effector

    单击Add Component,然后选择Physics 2D ▸ Area Effector 2D。 启用Use Global Angle。 然后,将Force Angle设置为90,将Force Magnitude设置为20。在Force Target下拉列表中,选择Rigidbody

    点击Play并测试您的新漩涡。

    注意:将Force Magnitude增加到200还会使球通过隧道。 但是您将无法使用Surface Effectors 2D,因此在本教程中,将其设为弱漩涡。

    2. A Guided Path With Surface Effector 2D

    “弱”涡旋仅具有将球推到隧道入口的力量。 接下来,您将创建一条路径来引导球穿过隧道的其余部分。

    • 1) 在层次结构中的Road Tunnel Zone上单击鼠标右键,然后选择Create Empty。 将此新对象命名为Road Surface
    • 2) 在检查器中,单击Add Component,然后选择Physics 2D ▸ Edge Collider 2D
    • 3) 单击Edit Collider图标,然后相应地移动向量。
    • 4) 启用Used By Effector并将Edge Radius增加到0.03

    接下来,单击Add Component,然后选择Physics 2D ▸ Surface Effector 2D。 将Force Speed设置为15,将Force Scale设置为1。单击Play

    等一下,那个球在做什么? 下一部分将修复行为。

    3. Mesh Editing in Unity

    此时,当您预览作品时,您会看到球的动作很奇怪。

    转到“层次结构”,选择Static Colliders/WallBoard,然后在“检查器”中启用Sprite Renderer。 在这里,您会找到罪魁祸首-一些媒介正在阻挡隧道的入口。

    要解决此问题,请转到Polygon Collider 2D,单击Edit Collider图标,然后将令人讨厌的向量移开。 差距不要太大。

    注意:为了更快地进行网格编辑:

    按住Alt键并单击鼠标左键将光标更改为“手形”图标以移动画布。
    Command(Mac)Control(Windows)突出显示顶点,然后单击鼠标左键删除。

    再次单击播放。 好了,一切顺利!

    4. Blocking With Platform Effector 2D

    现在,ForceField将球推到路面上,然后将其沿着隧道引导并直接回到射手,然后……

    哇...? 它直接从滑道下降到plunger

    那不是很正确。

    您需要一个对撞机,以防止球掉入Plunger。 但同时,您需要让球在发射后离开射手。

    追溯过去,您可能会使用if-else步步为营。 但是现在,Platform Effector 2D在这里可以节省一天!

    在层次结构中的Road Tunnel Zone上单击鼠标右键,选择Create Empty并命名新对象Block Platform

    在检查器中,单击Add Component,然后选择Physics 2D ▸ Edge Collider 2D。 然后Edit Collider以移动将阻止出口的矢量。 启用Used By Effector并将Edge Radius设置为0.03

    接下来,单击Add Component,然后选择Physics 2D ▸ Platform Effector 2D。 禁用Use Collider Mask。 然后,将Rotational Offset的值设置为90,将Surface Arc的值设置为130。启用Use One Way

    点击Play...您已经解决了问题!


    Float Piece Area

    玩家可以得分更高的另一个好地方是浮动区域。

    要实现它:

    • 1) 将球实例的Transform Position设置为(X:-2.2,Y:-0.5,Z:0)
    • 2) 转到Assets / RW / Sprites,然后将floatpiece拖动到Hierarchy中的Float Piece Area对象中。
    • 3) 将子实例命名为Float Area
    • 4) 在检查器中,将Transform Position设置为(X:-2.63,Y:0.18,Z:0),然后选择Logo作为其Sorting Layer
    • 5) 单击Add Component,然后选择Physics 2D ▸ Polygon Collider 2D。 启用Is TriggerUsed By Effector
    • 6) 从Physics 2D ▸ Buoyancy Effector 2D中添加另一个组件。 将Density设置为50。在Damping下,将Linear DragAngular Drag设置为10
    • 7) 将Flow Variation设置为-5,可使浮动效果有所移动。

    点击Play查看漂浮效果。

    1. Code the Float

    现在,您将设置浮动持续时间。 在Assets / RW / Scripts中,双击Floatpiece.cs以在代码编辑器中启动文件。

    在现有变量下面声明以下变量:

    private BuoyancyEffector2D floatEffector;
    public float floatingTime = 0f; // floating duration
    private float runningTime = 0f; // the current duration since startTime
    private float startTime = 0f;
    

    Start下面,添加:

    floatEffector = GetComponent<BuoyancyEffector2D>(); // assign component to this instance
    

    替换OnTriggerEnter2Difblock为下面:

    // on enter zone, start float
    floatEffector.density = 50;
    // start timer
    if (startTime == 0f)
    {
        startTime = Time.time;
        sound.bonus.Play();
        scoreBoard.gamescore += 10;
        golightRenderer.sprite = golightAniController.spriteSet[0];
        StartCoroutine(BeginFloat());
    }
    

    替换整个BeginFloat的方法为下面:

    IEnumerator BeginFloat()
    {
        while (true) 
        {
            // calculate current duration
            runningTime = Time.time - startTime; 
    
            // play animation loop
            int index = (int)Mathf.PingPong(handcamAniController.fps * 
                        Time.time, handcamAniController.spriteSet.Length);
            handcamRenderer.sprite = handcamAniController.spriteSet[index];
            yield return new WaitForSeconds(0.1f);
            
            // when time is up            
            if (runningTime >= floatingTime)  
            {
                // stop float and reset timer
                floatEffector.density = 0;    
                runningTime = 0f;
                startTime = 0f;
      
                // stop sound & animation 
                sound.bonus.Stop();
                golightRenderer.sprite = golightAniController.spriteSet[1];
                handcamRenderer.sprite = handcamAniController.spriteSet 
                              [handcamAniController.spriteSet.Length - 1];
                break;
            }
        } 
    }
    

    单击保存,然后返回到Unity

    这是整个教程中需要编写的最多代码! 其中很多是调用已经为您定义的东西。

    首先,您声明了一些变量,这是对您在场景中添加的BuoyancyEffector2D组件的引用以及一些计时器。

    当球进入Float Area时,您将调用OnTriggerEnter。 您启动计时器,启动一些声音和动画效果,并向玩家奖励一些积分。 然后启动BeginFloat协程。

    BeginFloat中,您可以跟踪球在Float Area中的停留时间,并运行一些精灵动画。

    时间到时,您将重置所有计时器,停止所有动画和声音效果,并将BuoyancyEffector2D.density减小为0。这将导致球掉落到Float Area中并重新进入比赛!

    2. Implementing the Float Area

    转到Assets / RW / Prefabs,然后将floatEffects拖动到层次结构中的Float Piece Area对象中,以创建一个子实例。 单击floatEffects旁边的箭头图标以展开内容。

    在层次结构中选择Float Area。 单击Add Component,然后选择Scripts ▸ Floatpiece。 在检查器中,将floatEffects分配给Handcam Obj,将StaticLight分配给Golight Obj。 将Floating Time值设置为2

    点击Play进行测试:


    Triangle Bumpers

    弹球游戏几乎完成了! 剩下的就是使用point effectorsphysics material来增强游戏性。

    为此,您需要在游戏中添加bumpers。 如果球碰到这些bumpers中的任何一个,它将朝相反的方向射击。

    要创建这些bumpers,请转至Assets / RW / Prefabs并将dragerTriangleLeft拖动到层次结构的Bumpy Parts中。 将球ball实例放在bumpers的前面。

    单击Play以查看球如何从斜坡上滚下来。

    Physics Material 2D Versus Point Effector 2D - 物理材料2D与点效应器2D

    在Unity中,要在碰撞时为动画对象添加动量,您有两个选择:

    Physics Material 2D:在整个对象表面上,速度始终保持一致,而不管碰撞点如何。

    Point Effector 2D:速度取决于对象的质心及其碰撞点。

    随意使用两个选项。 使用不同的设置进行实验,以找到游戏中不同碰撞元素的最佳效果。

    在“层次结构”中选择bumperTriangleLeft。 在检查器中找到Polygon Collider 2D,并启用Is TriggerUsed By Effector

    接下来,单击Add Component,然后选择Physics 2D ▸ Point Effector 2D。 将Force Magnitude设置为500,并将Damping设置调整为Drag: 5000Angular Drag: 1000

    现在,将bumperTriangleRightAssets / RW / Prefabs拖动到Bumpy Parts中。 将其设置与左bumpers完全相同。

    然后将球实例的Transform Position设置为(X:-1.6,Y:-1.6,Z:0)。 单击Play以测试新的bumpers

    看! 球太快了,看不到它。

    1. Adding More Bumpers

    您可以尝试另外两种预制件,以探索更多的2D物理引擎:bumperCirclesbumperDividers。 要将它们添加到您的弹球游戏中,请将它们拖到HierachyBumpy Parts中。

    入门项目已经为您设置了这些。 但是,您可以使用Point Effectors 2DPhysics Material 2D调整碰撞的影响。

    最后,将ball实例的位置设置为(X:2.8,Y:-1,Z:0)

    单击Play,然后享受“弹指一击”的乐趣!

    要扩展此游戏,您可以构建菜单系统并将玩家限制在只有三个球才能获得高分。 或者,您可以将其与Facebook挂钩并设置高分表来挑战您的朋友。

    后记

    本篇主要讲述了基于Unity 2DPinball游戏的简单实现,感兴趣的给个赞或者关注~~~

    相关文章

      网友评论

          本文标题:Unity强化篇(十) —— 基于Unity 2D的Pinbal

          本文链接:https://www.haomeiwen.com/subject/vkqfkktx.html