unity 2d俯视射击游戏怎么实现敌人被击后退

扫码下载官方App
学习过该课程的人还学习过:
其他联系方式
所属系列课程
网易公司()旗下实用技能学习平台。与优秀讲师、专业机构、院校合作,为您提供海量优质课程,以及创新的在线学习体验,帮助您获得全新的个人发展和能力提升。
关注我们:
& 网易公司 版权所有
Unity5之2D游戏 射击游戏,庖丁解牛系列,用Unity5完成一个2D的射击游戏,
从第一步第一行代码开始,到最后一步最后一行代码,全程手把手操作敲代码、注释、演示和讲解,让学员完成untiy5的2D射击游戏开发,
内容包含:
添加背景和前景
用代码实现天鹅随机飞行
创建小豆人动画
给小豆人添加2D物理碰撞功能
控制小豆人的左右移动和跳跃
实现小豆人射击功能
实现与敌人的互动和暂停功能
适用人群:有c#或java语言基础,对游戏开发感兴趣的所有人扫一扫,访问微社区
后使用快捷导航没有帐号?
签到成功!您今天第{todayrank}个签到,签到排名竞争激烈,记得每天都来签到哦!已连续签到:{constant}天,累计签到:{days}天
Unity学习笔记2 简易2D横版RPG游戏制作(二)
阅读&6717 |
十二、敌人受攻击时的闪烁和Player的生命值的修正上一篇中,我们利用Controller2D中的IEnumerator TakenDamage接口,使得我们的Player受到攻击时会进行闪烁,我们同样地也希望在我们的敌人身上可以实现相同的效果。所以我们现在需要复制Controller2D脚本里面的两个内容到我们的Enemy2D脚本里面去:第一个内容:[csharp]&第二个内容:[csharp]&接下来我们需要对Bullet脚本进行处理,使其在碰撞到我们的敌人时,向敌人发送一个闪烁的信号:(修改内容如下)[csharp]&其实就是增加了一句:[csharp]&解决了敌人的闪烁之后,我们接下来要处理另外一个问题了。这个问题就是,我们的角色每消灭一些敌人就会增加经验,而经验的增加会自动补充HP,这个有点不对头和不合理,我们升级的时候增加的应该是最大HP,在每个等级下,我们应该设置一个当前的最大HP,不能无限制地增加HP才对,所以呢,我们需要将原来的GameManager脚本里面的playersHealth变量改名为curHealth,并且增加一个maxHealth变量,同时设置为3,将原本的playersHealth++修改为maxHealth++,这样的话,消灭敌人只会增加你的最大HP,而不会增加你当前的HP,至于升级之后是不是要让HP全满呢,这个功能很容易实现,我暂时不想加进去。接下来我们就需要考虑下一个问题了,那就是角色的战斗力必须随着等级的提升而得到提升才比较合理。不能每次攻击都只扣敌人一滴血啊。而且敌人只有3到6滴血的设定不太合理,其实反正敌人的血是不显示出来的,完全可以设置一些大一点的数值,比如100,500之类的,这个就到后面有需要再改吧。现在暂时先不动。十三、补血药的设置在这一讲里面,首先要处理一个问题:我们的Player应该是有战斗力的,而不是每次只向敌人发送1滴的伤害值。利用某某++的方法可以很容易实现升级时增加战斗力,这个就不说了。关键是怎么弄成用我们的战斗力去减敌人的血值。首先,我们在GameManager脚本里面添加这么一行:[csharp]&然后把我们的curHealth,也就是当前HP的值也改成static public。这里顺便补充一下,static在c#中的作用。静态分配的,有两种情况:
1. 用在类里的属性、方法前面,这样的静态属性与方法不需要创建实例就能访问,
通过类名或对象名都能访问它,静态属性、方法只有“一份”:即如果一个类新建有N个
对象,这N 个对象只有同一个静态属性与方法;
方法内部的:
方法内部的,执行完值不消失,再次执行此对象的方法时,值仍存在,
它不是在栈中分配的,是在静态区分析的, 这是与最大的区别;如果这个说得不具体的话,那么可以看一下下面这个,红黑联盟里面讲的,非常形象,保证一看马上就明白了:(我也是在看视频教程的过程中碰到了static不懂,然后看下面这个理解透彻的)提起static,一般理解为静态、全局。何为static?我理解的static属于程序的直属单位,而非static就是非直属单位。举一个非常常见的例子,中国有4个直辖市,北京、上海、天津、重庆,这些相当于static,而广州、南京、杭州等就是非static,中央可以直接管理北京、上海、天津、重庆,而广州、南京、杭州应由各省政府管理,Main方法可以直接调用static,而调用非static需要实例化。[csharp]&讲的形象就达到目的了,为刚开始学习的同学加把劲儿。原链接:好啦,然后我们继续。接着我们打开我们的Bullet脚本,把里面的内容修改成这样:[csharp]&其实上面的内容只是将[csharp]&这一行进行了处理,我们原本的那个damageValue变量已经被删掉,然后替换成我们GameManager里面的bulletDamage,因为我们的这个bulletDamage已经修改为static,所以现在可以这样调用了。以后如果想要升级增加角色的杀伤力的话,就容易多了。接下来我们想要在运行游戏中按C的时候顺便显示我们的战斗力,这个太简单了,只需要对GameManager里面做一点点修改:[csharp]&这一部分大家可以随便修改,你想显示什么就修改什么。至于在画面中的位置,可以调整GUIStats的transform,这个就不再赘述。我稍微做了点修改。接下来我们需要在场景中新增一个quad,去掉Mesh Collider,加上Box Collider,然后Box&Collider的size全部改成1,transform里面的position的z值别忘了设成0,名字随便起,是用来做成补血药的,我命名为HealthPotion,然后为它增加一个同名的tag。为了区分,我顺便弄了一个同名的material扔上去,将颜色调成粉红色。(呵呵……感觉是毒药而不是血药啊……)接着我们打开上次弄的那个StickToPlatform脚本,把里面的东西复制到我们的Controller2D上面,其实因为两个脚本都是绑定在Player身上,就没必要弄两个脚本了,直接合并成一个就成了。然后我们再增加一段小代码来使得我们的Player碰到带有HealthPotion的物体时,将这个物体摧毁并且curHealth值加1。[csharp]&很简单吧,现在补血药就已经做好了。想要做出补多少血的补血药都已经不是什么问题了。想要做出补蓝、增加战斗力什么的补血药,也不是什么问题了哈哈。有个地方需要大家注意一下,那就是curHealth必须加上static,否则会出现An object reference is required to access non-static member这样的报错显示。在全局静态函数里面是不可以使用非全局静态变量的。吃药前(注意左上角两个红心)吃药后,哈哈,疗程短见效快,一粒补一滴血~关于Box Collider的范围的问题,可以参考上一篇讲到的Player的Character Controller组件的问题,所以我们可以顺便把药物的Box Collider的size的X值改为1.3。十四、游戏暂停和游戏存档游戏存档看似简单,不过也是个比较蛋疼的问题。我们打开GameManager脚本:首先,我们增加一个布尔值:[csharp]&然后我们增添以下代码:[csharp]&然后保存脚本。现在我们在运行游戏的过程中按P键,就可以调出一个这样的画面:当我们点击保存游戏时,就会保存相应的数据。我们可以先杀掉一只小怪,然后保存,然后重新运行,然后点击“显示保存的数据”,这个时候就会看到:但是这个时候有两个问题,第一个问题是,虽然在这里我们可以看到保存的数据,但是实际上在游戏里面,如果我们按C键查看角色的属性时,发现经验值并没有保存下来。第二个问题是,我们的存档还不知道怎么删除……接下来马上解决这个问题:十五、载入游戏和删除存档好了,我们继续修改我们的GameManager脚本,首先我们要增加一个void Awake()函数,这个东西和void Start()有什么不同呢?我顺便摘录了一段网上搬过来的笔记:这是博客园的一篇介绍的原链接:初学者经常把Awake和Start混淆。简单说明一下,Awake在MonoBehavior创建后就立刻调用,Start将在MonoBehavior创建后在该帧Update之前,在该Monobehavior.enabled == true的情况下执行。[javascript]&&我们通常书写的脚本,并不会定义[ExecuteInEditMode]这个Attribute,所以Awake和Start都只有在Runtime中才会执行。例1:[javascript]&&以上代码,在Awake中我们调用了enabled = 禁止了这个MonoBehavior的update。由于Start, Update, PostUpdate等属于runtime行为的一部分,这段代码将使Start不会被调用到。在游戏过程中,若有另外一组代码有如下调用:[javascript]&&这个时候,若该MonoBehavior之前并没有触发过Start函数,将会在这段代码执行后触发。例2:player.cs[javascript]&&other.cs[javascript]&&以上代码中,我们在player Awake的时候去为handAnchor赋值。如果我们将这步操作放在Start里,那么在other.cs中,当执行GetWeapon的时候就会出现handAnchor是null reference.总结:我们尽量将其他Object的reference设置等事情放在Awake处理。然后将这些reference的Object的赋值设置放在Start()中来完成。当MonoBehavior有定义[ExecuteInEditMode]时当我们为MonoBehavior定义了[ExecuteInEditMode]后,我们还需要关心Awake和Start在编辑器中的执行状况。&&& 当该MonoBehavior在编辑器中被赋于给GameObject的时候,Awake, Start 将被执行。&&& 当Play按钮被按下游戏开始以后,Awake, Start 将被执行。&&& 当Play按钮停止后,Awake, Start将再次被执行。&&& 当在编辑器中打开包含有该MonoBehavior的场景的时候,Awake, Start将被执行。值得注意的是,不要用这种方式来设定一些临时变量的存储(private, protected)。因为一旦我们触发Unity3D的代码编译,这些变量所存储的内容将被清为默认值。下面再来看看Unity圣典中的解释。&Awake()当一个脚本实例被载入时Awake被调用。Awake用于在游戏开始之前初始化变量或游戏状态。在脚本整个生命周期内它仅被调用一次.Awake在所有对象被初始化之后调用,所以你可以安全的与其他对象对话或用诸如 GameObject.FindWithTag 这样的函数搜索它们。每个游戏物体上的Awke以随机的顺序被调用。因此,你应该用Awake来设置脚本间的引用,并用Start来传递信息。Awake总是在Start之前被调用。它不能用来执行协同程序。Start()Start仅在Update函数第一次被调用前调用。Start在behaviour的生命周期中只被调用一次。它和Awake的不同是Start只在脚本实例被启用时调用。你可以按需调整延迟初始化代码。Awake总是在Start之前执行。这允许你协调初始化顺序。好了,这样就清楚为什么要用Awake()函数了吧。接下来我们就这样弄,首先我们设置一个int saved,让它等于零。(如果不赋值的话,它也会默认等于零)[csharp]&接下来我们就写下这么一个Awake函数:[csharp]&在运行这个Awake函数的时候,就会让saved先获取我们保存的值。(等一下在下面存档的那部分脚本里面,我们会保存先把saved赋值为1,再进行保存),因为PlayerPrefs不能保存布尔值,所以我们用一个int的0和1来代替就行了,一样的。如果我们的游戏没有存档的话,saved读取不到任何数据,就会默认为零,那么就相当于不会接下去读取我们保存的数据了,反之,如果读取到了1,就相当于读取到了“已经有保存的数据”的情况,就需要继续执行。在保存数据部分,我是这样弄的:[csharp]&我们可以看到,在保存之前,我们先将saved赋值为1,然后再保存,这样的话,当我们重新载入游戏时,就会进行一个是否保存了游戏的判断。至于下面那个“显示保存的数据”的按钮功能,只是我用来debug.log的,没什么用,纯属调试,可以无视。可能有人会说,保存游戏就直接保存,然后直接读取数据不就行了,为什么还要弄一个saved来判断呢?我一开始也是没有弄这个玩意的,后来发现了一个问题,在这里解释一下:假设我们现在删除了游戏存档,而没有这个用来判断是否有存档的saved值的话,那么我们的脚本自然就不管三七二十一,你没有存档它也会当成你是有存档的,这样会出现什么问题呢?这样的话,我们的curEXP = PlayerPrefs.GetInt ("Player EXP");和level = PlayerPrefs.GetInt ("Player Level");这两句话就会得不到任何数据,那么就会默认为零,那么,下面的maxEXP = level * 50;还有maxHealth = level + 2;这两句的计算就肯定会出问题了。maxEXP会变成0,而maxHealth会变成2,最大经验值变成零也就算了,我们的血值还从3变成了2,这不是坑爹么……哈哈,所以,这下子明白为什么要做一个是否saved的判断了吧。对于我这样的小游戏来说,就已经需要制作一个是否saved的判断了,对于需要保存大量数据的大游戏来说那就更是如此。希望大家如果是制作RPG类型的游戏的话,也可以养成类似的习惯。接着要解决删档的问题。这个也是RPG游戏的一个重点内容。我们打开MainMenu脚本,然后在if (showGUIOutline)里面加入以下内容:[csharp]&其实主要就是添加一个PlayerPrefs.DeleteAll();而已,没什么复杂的。当然,为了方便我们在窗口中调整GUI的位置,我们也增加了guiPlacementX3还有guiPlacementY3这两个public的float值。这里就没必要贴出来了。接着在Mainmenu场景里面的Maincamera上面调整好三个GUI按钮的位置:接着我们来测试运行一下,我们进入Mainmenu场景,然后运行,点击“删除存档”按钮:我们会看到print出了一句已删除存档的提示。接着我们载入游戏,来到我们那个丑丑的游戏场景,然后按C,查看一下我们当前的各项状态。现在我们还是初始状态,我们去随便刷掉两只怪,然后顺便去作死一下,扣掉一滴血。然后按P键调出保存菜单。现在我已经按了保存,然后我按了“显示保存的数据”按钮,现在我们可以从右边的Console列表里面看到我们保存的数据。好了,我们退出,重新进来~,再查看一下:细心一点的朋友应该注意到,这次稍微有了点不同。那就是我又恢复成3滴血了。这是因为我们重新加载的时候,curHealth会变成当前等级的maxHealth,所以我们重新载入之后不是2滴血,而是3滴血。现在我们重新进入Mainmenu场景,然后删除存档,再重新进来一遍:可以看到,我们的角色的全部资料都清零了。(右手边的Console显示了我刚刚有进行“删除存档”按钮的点击操作,没有造假,哈哈)好了,现在我们已经解决了角色存档的问题。这部分可能自己实际操作的时候会碰到一些问题,需要大家多做几次,特别是不同的游戏,情况肯定不一样,这个没办法有统一的标准,这里只是提供一个思路。十六、自动存档前面我们提到了存档的方法了。有些游戏是即时存档的,就是在Update每一帧都进行一次存档的操作,对于小游戏来说,这种做法无可厚非,但是对于类似宠物小精灵这种有庞大数据的游戏来讲,即时存档是不太可行的。也许有其他优化的方法,比如在独立游戏Terraria中,它就是支持大数据即时存档的,目前我尚不知道这种方法要如何实现。下面,我们可以利用类似技能冷却的原理,设置一个定时自动存档器,比如说每隔五秒钟或者十秒钟自行存档一次,为了让玩家知道有自动存档的情况,我们可以调用一些GUI来显示(我这里就直接print了)。同理,我们也可以在场景中布置一些特殊物体,进行自动的存档,比如说某一个关卡末尾的大门,我们的Player碰到大门之后就会跳到下一个关卡,同时自动保存我们Player身上的全部数据。(至于这个场景跳转门或者说是位置跳转门能不能双向跳动,这个就要看你的游戏是怎么布置的了。)废话不多说,马上开始:首先我们需要在GameManager脚本里面创建一个叫做SaveGame()的函数,然后改为public类型(为什么要这样做后面会解释),然后把我们前面在if(pauseMenu)里面的部分内容移到这个函数里面去:[csharp]&只有加上public,才能在外部进行调用嘛。好了,现在我们增加下面的内容:[csharp]&想要跳到下一个关卡有个很简单的函数可以使用,就是Application.LoadLevel(),可是有个问题,就是如果我们直接选择加载某一个关卡的话,我们这个脚本就不能重复利用了。也就是说,我们想要做成一个只要一碰到就会自动跳转到下一关的功能的脚本,这样就不必在每一个关卡里面都来写一个特定的脚本。首先,我们用string thisLevel = Application.loadedLevelN这句话获取当前关卡的名字,我们之前将关卡命名为Scene1,现在直接改成1就行了。这样的话,我们就相当于得到了关卡的序列号。理论上来讲,我们只需要Application.LoadLevel(thisLevel+1);就应该是可以跳转到下一个关卡的了。如果这样的话那就很方便了。可是实际上有个很大的问题,那就是关卡的名字是字符串,字符串可不能直接做加减法的,所以我们需要将字符串强制转换为int类型。C#里面有Convert.ToInt32的转换方法,但是我在unity里面没办法使用(难道是我的打开方式不对?)所以我采用了另一种方法,也就是上面脚本的int intThisLevel = int.Parse(thisLevel);这样,我们获取当前的字符串名称1就会变成整数1(为了实现这个功能,我们必须将除了Mainmenu关卡之外的其他关卡全部命名为阿拉伯数字名称,即1、2、3……)然后我们对这个整数1进行加1的处理,即:int intNextLevel = intThisLevel+1;接着,我们将得到的这个新的整数重新转换为字符串string nextLevel = intNextLevel.ToString();到这里,加载下一个关卡的任务就完成了,最后我们加上这么一句:Application.LoadLevel(nextLevel);即可跳转到下一关卡。关于强制类型转换的,可以参考这个:C#,int转成string,string转成int1,int转成string用toString&或者Convert.toString()如下&例如:int varInt = 1;&string varString = Convert.ToString(varInt);&string varString2 = varInt.ToString();2,string转成int如果确定字符串中是可以转成数字的字符,可以用int.Parse(string s),该语句返回的是转换得到的int值;如果不能确定字符串是否可以转成数字,可以用int.TryParse(string s, out int result),该语句返回的是bool值,指示转换操作是否成功,参数result是存放转换结果的变量。例如:string str = string.Estr = "123";int result=int.Parse(str);string str = string.Estr = "xyz";int.TryParse(str, out result);接下来处理下一个问题,我们在刚刚的if (other.tag == "Door") {}里面插入一句gameManager.SaveGame();当然,在此之前,我们需要在这个脚本里面加上这么一行:[csharp]&这个应该很好理解,就不再赘述了。使用public的原因是为了在外部进行拖拽操作,如果不将其设置为public的话,就会出现NullReferenceException: Object reference not set to an instance of an object字样的报错,这个我们在上一篇学习笔记里面已经有提到过了。出现这个的原因是因为我们此处引用了GameManager里面的一个SaveGame()函数,但是unity并不知道你到底在用哪个GameManager,所以会报Null,最简单的解决方法就是拖拽大法,也可以用GetComponent&&的方法。看下面,这个是我的Player身上的Controller2D脚本的设置,我已经把GameManager物体拖放到相应位置了。刚开始的时候,原作者并没有使用这个方法,而是直接复制了Bullet脚本里面的other.gameObject.SendMessage("TakenDamage",SendMessageOptions.DontRequireReceiver);这句进行修改。现在我们顺便来想想为什么不可以采用这种方法。因为这种方法是对着other.gameObject发送信号,而我们是对着自己发送信号啊。可能有人会说,那还不简单,我们直接把other.gameObject.删掉不就可以了吗?原视频的作者也试了一次,不行。但是他没解释。我想了一段时间,终于明白了。因为SendMessage不可以把内容发送给自己这个脚本。发送给同个物体身上的不同脚本还是行得通的,但是自己发送给自己就不行了。所以,这种方法是行不通的,就只能用上面提到的那种方法了。现在我们已经实现了场景跳转和按键存档功能,接下来就是自动存档功能了。我们在GameManager脚本的Update函数里面进行如下增添:[csharp]&上面的autoSaveTimer是自定义的一个int变量,我顺便设置成public,方便在外面修改。我将它改为10,也就是每隔10秒就会自动保存一次,前面我们将保存的功能整合成一个SaveGame()函数就是为了这个目的。那句print(“保存啦~~”)只是用来卖萌和提示自己的,嘿嘿~每次保存之后autoSaveTimer这个自动保存的计时器就会清零,然后重新进入下一轮的计时,这样就可以实现循环保存的功效了。因为我们的游戏数据比较小,所以可以每隔一段时间就自动保存一次,大数据的游戏就不建议这样弄了。这一讲很长,也涉及到了很多问题。所以我花了很长时间整理。如果大家有什么不太清楚的话,最好多看几遍,然后自己再试着操作一下试试。当然,这个是针对新手说的,各路大神可以无视哈。十七、关卡选择在这一讲里面,我们首先创建一个新的场景(为了方便测试,我把上一次弄的场景2直接重命名为场景LevelSelect,你要新建一个当然也没问题,这个不是重点,哈哈),这个场景的作用就是在进入时可以用来选择进入各个关卡的。很多横版的闯关游戏由于关卡比较多,所以在游戏开始的时候都会有这样的选择画面,让玩家自行选择这次要玩哪一关,就不必要每次都从第一关开始玩起了。而且由于Unity在游戏保存这一块非常给力,所以我们完全不需要担心数据丢失方面的问题。接着我们先点击进入我们的Mainmenu场景,在摄像机的MainMenu脚本里面,把Level里面原本的Scene1改成现在的LevelSelect,这样我们就可以通过点击按钮直接跳转到我们现在要用到的这个LevelSelect场景了。接着进入这个场景,然后创建一个同名脚本扔到摄像机上面,然后我们开始编辑:[csharp]&内容很简单,我就不做解释了。前面两个int是因为觉得打screen.width和screen.height很麻烦,所以才那样弄的,至于那个public string Level,之前介绍过了就不再解释为什么要这样做了。我这里只是随便弄了一个出来,大家可以在这个LevelSelect的脚本里面设置一堆不同的按钮,每个按钮连接到你的各个不同关卡里面去,这样就达到了关卡选择的效果啦。接下来看看我们之前的Controller2D脚本,我们在这个脚本里面有这么一段:[csharp]&看了原作者的视频,他是打算做一个叫做Door的脚本,把上面的那部分功能转移到这个脚本里面去,然后再去把这个东西拉到我们的Door物体上,其实这一步可做可不做。我想来想去,这么做的好处大概就是可以为每一个Door弄一个public string Level,然后设置那些穿越什么的方便一些吧。视频里面的Door脚本里面的GameManager脚本还是采用将它改为public,然后再在外面进行拖拽的方法。那么有没有什么方法可以不进行这些拖拽呢?当然可以的啊。只要利用GetComponent就可以了。下面贴出我写的脚本:[csharp]&我们首先要定义一个GameObject来利用FindGameObjectWithTag得到它(使用这种方法需要增加tag,其实和拖拽方法大同小异,这个就看个人喜好了。两种方法大家都可以使用的)当然,我们要给GameManager加上一个同名的tag。接着我们就利用这个:gameManager = gameObject.GetComponent&GameManager&();很简单,我就不解释了,不过需要注意一下格式。如果在函数上有什么不太明白的,建议大家自己去查查手册。链接:另外呢,在实际操作过程中,如果大家按照我上面的脚本照抄一遍,就会出现这样的黄字警告:Assets/Scripts/Door.cs(8,16): warning CS0108: `Door.gameObject' hides inherited member `ponent.gameObject'. Use the new keyword if hiding was intended&这到底是怎么回事呢?一开始我真的想不明白,用百度和Google也找不到解答。后来自己想了想,然后又查了一下词典,总算明白到底是怎么一回事了。我们都知道,黄字警告一般是不会影响游戏的运行的,但是肯定是有某些不太合理的地方,所以我们的Unity会非常人性化地给我们提个醒。我经常碰到的黄字提醒一般都是定义了某个变量,但是从未使用过。而这次碰到的这个情况,是脚本里面的gameObject变量和系统里面本身自带的gameObject实例名称重复了。因为我们知道,gameObject是个关键词,所以如果我起了个这样的名字的话,虽然是可以运行的,但是Unity也许容易混淆,所以它就会给我们一个这样的提醒。这里也顺便提醒一下大家,在定义变量的时候尽量不要使用和系统自定义的关键词重复的东西。否则可能会出现比较严重的问题。上面的这个问题,我们只需要把gameObject改成gameObjectGM,就不会报错了。好了,那么这一讲想要实现的功能就都实现了。我们可以接着下一讲的内容了:(顺便说一下,我不是很喜欢unity4.3版本里面自带的monodevelop脚本编辑器,所以我改成了VS2013,这篇写完之后我会写一篇替换编辑器的内容。)这是我处理过的VS2013的界面,感觉还是挺和谐的嘻嘻。下一篇我们再聊这个。由于排版方面出了很奇怪的问题,所以第二篇就只能先到这里结束了。大概是因为我弄了太多天的同一篇,又有些东西是复制进来的,导致排版的时候总是出错吧。先这样吧,下一篇我会将没有说完的补完。unity3d 2d横版
作者的其他最新博客
评论 ( 个评论)Unity 2D游戏开发快速入门(内部资料)
Unity 2D游戏开发快速入门(内部资料)
介绍:本书通篇介绍了一个2D游戏–RageTanks(狂怒坦克)的详细开发过程,包从导入游戏资源、游戏逻辑设计到最后游戏逻辑的实现。本书将这一开发过程分成了6个部分来讲解,力求读者在每一部分都能实现一个可见的效果,而这些效果的综合体现就是最后的RageTanks。
Unity 2D游戏开发快速入门4
淘宝店地址:
试读样张:
Unity是一款综合的游戏开发工具,也是一款全面整合的专业游戏引擎。使用它开发的游戏,可以部署到所有的主流游戏平台,而无需做任何修改。这样,开发者只需把精力集中到制作高质量的游戏即可。
没用过Unity?没关系,这里有详细的操作步骤;
没学过C#?没关系,这里有详细的注释和解释,更何况C#本来就不难;
得学习很久吗?不,即时你是新手,依然可以在一个月内做出本书介绍的这个游戏!
喔~说的夸张吗?一点儿也不!为什么这么自信,因为我是作者!我精心设计了这个游戏!它简单、结构清晰,而且也很有趣!我相信你通过对这个游戏的学习,可以增进对3个方面的理解:
Unity、2D游戏开发流程和脚本代码的编写。
1.学习所需的系统和软件
安装Windows 7操作系统
安装Unity 4.5.3
2.学习建议
大家学习之前,可以致信到xxxx,获取相关的资料和软件。如果大家在学习过程遇到问题,也可以将问题发送到该邮箱。我们尽可能给大家解决。
创建一个简单的2D游戏 1
游戏精灵 3
精灵动画 7
Animation 7
Animator 9
使用脚本实现游戏逻辑 12
精灵动画状态的控制 12
监听精灵当前的动画状态 14
2D游戏的运行效果 17
为游戏精灵添加更多状态 19
摄像头追踪功能 19
精灵的死亡和重生 22
添加多个地面 27
精灵的跳跃状态 28
精灵的开火状态 34
让游戏精灵不再孤单 40
为游戏添加反派角色 40
精灵与反派角色碰撞后死亡 44
精灵主动攻击反派角色 46
添加反派角色销毁时的效果 48
添加多个反派角色到游戏中 50
为游戏添加更多背景元素 52
为游戏场景补充更多元素 52
限制精灵的移动范围 52
添加背景元素 54
让背景元素动起来 55
让粒子效果显示在前面 58
记录分数 59
动态生成更多的敌人 61
终极战斗 66
引入究极敌人 66
究极敌人的行为逻辑 67
让究极敌人的出场更威风些 72
究极敌人的攻击方式 74
玩家精灵的反击 77
让游戏更完善 85
游戏关卡 85
游戏标题以及开始按钮 88
导入标题和按钮资源 88
表示游戏状态的类 89
单击开始按钮,进入游戏 92
游戏最终运行效果展示 94}

我要回帖

更多关于 unity 2d射击游戏 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信