基于Unity3d引擎的ACT游戲設(shè)計與實現(xiàn)_第1頁
基于Unity3d引擎的ACT游戲設(shè)計與實現(xiàn)_第2頁
基于Unity3d引擎的ACT游戲設(shè)計與實現(xiàn)_第3頁
基于Unity3d引擎的ACT游戲設(shè)計與實現(xiàn)_第4頁
基于Unity3d引擎的ACT游戲設(shè)計與實現(xiàn)_第5頁
已閱讀5頁,還剩39頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

摘要從游戲誕生之始到現(xiàn)在,游戲市場就發(fā)生了非常大的變化,從卡帶的游戲機到現(xiàn)在的電腦,專門的游戲主機等。在此之中,像素游戲是一個很重要的過渡期,像素圖由于占空間少,顏色少,所以在最初階段的電子計算機上時代中,就被采用來作為制作游戲的標(biāo)準(zhǔn)圖片形式,因為最開始的游戲處理芯片比較低級,自然不能跟如今的3d游戲相比較了,能運行的圖片都有嚴(yán)格的顏色和大小的限制。而且圖片幾乎都是以動態(tài)的形式出現(xiàn)的。在如今的游戲開發(fā)中,Unity的工具的發(fā)明,使能向往游戲開發(fā)的人入門游戲開發(fā)不再困難。在本課題中,將使用Unity引擎開發(fā)像素風(fēng)格的2d橫板動作游戲,其中會復(fù)刻多個經(jīng)典像素游戲中的游戲技能,結(jié)合當(dāng)前火熱的Unity物理引擎,對以前的游戲以當(dāng)前的技術(shù)進行重現(xiàn),對以后游戲開發(fā)的思路有很大的參考價值關(guān)鍵詞:像素游戲2d橫板動作游戲Unity物理引擎AbstractFromthebeginningofthegametonow,thegamemarkethaschangedalot,fromthegamemachinewithcardtothecomputerandspecialgameconsole.Amongthem,thepixelgameisaveryimportanttransitionperiod.Becausethepixelimagetakesuplessspaceandcolor,itwasadoptedasthestandardimageformformakinggamesintheearlyeraofelectroniccomputer.Becausethefirstgameprocessingchipisrelativelylow-level,itcan'tbecomparedwithtoday's3Dgames,andthepicturesthatcanrunhavestrictappearanceColorandsizelimits.Andpicturesarealmostalwaysindynamicform.Intoday'sgamedevelopment,theinventionofunity'stoolmakesitnolongerdifficultforpeoplewhocanyearnforgamedevelopmenttostartgamedevelopment.Inthisproject,wewilluseunityenginetodevelop2Dboardactiongamewithpixelstyle,inwhichwewillcopythegameskillsofseveralclassicpixelgames,andcombinethecurrenthotunityphysicalenginetoreproducethepreviousgameswiththecurrenttechnology,whichhasgreatreferencevalueforthefuturegamedevelopmentideasKeywords:pixelgame2Dboardactiongameunityphysicalengine目錄1.研究課題及意義 研究課題及意義動作游戲(ActionGame)是游戲中的一種。它強調(diào)玩家的反應(yīng)能力和手眼的配合。以游戲機為主、電腦為輔。動作游戲的劇情一般比較簡單,主要是通過熟悉操作技巧就可以進行游戲。這類游戲一般比較有刺激性,情節(jié)緊張,聲光效果豐富,操作簡單。在動作游戲中,在FC游戲家用機的時代中,有一些比較著名的作品,如高橋名人的冒險島,松鼠大戰(zhàn)等的游戲橫板游戲作品,以引人入勝的劇情和巧妙地關(guān)卡設(shè)計,成為了8090年代地難忘的游戲之一,在現(xiàn)在的PC游戲作品中,動作游戲的優(yōu)秀作品更是數(shù)不勝數(shù),如StudioMDHR開發(fā)的游戲Cuphead,在在正式發(fā)售后大約一個月,這部作品銷量就已經(jīng)突破了百萬大關(guān),并達到了與《星露谷物語》《Undertale》《饑荒》等相當(dāng)?shù)乃剑缃襁@款游戲已經(jīng)成功登陸多個平臺,成為最炙手可熱的游戲作品之一。還有TeamCherry開發(fā)的空洞騎士,這是一款畫面清新,難度挑戰(zhàn)的動作冒險游戲,里面豐富的關(guān)卡設(shè)計和適中的難度,吸引了很多玩家為之瘋狂。雖然現(xiàn)在各種moba游戲和射擊游戲類的網(wǎng)游很多,但是在動作游戲從誕生至此,雖然不算是非常炙手可熱,但是經(jīng)過了多年依舊魅力不減,主要的玩家群體是有很多玩家愿意通過自己的探索,自己去進行游戲的探險,而不是與他人合作,這類游戲?qū)τ谕婕襾碚f就是對游戲作品的敬仰,對游戲開發(fā)者來說就是智力與創(chuàng)造力的挑戰(zhàn)動作游戲的分類其實有很多,而本次研究課題是動作游戲中的橫板闖關(guān)游戲,在游戲中,玩家通過控制主角用武器去攻擊敵人,消滅敵人以過關(guān)的游戲,在游戲中,將運用到游戲AI常用到的有限狀態(tài)機框架去開發(fā),這種框架在其他的一些游戲中非常常見,運用這個框架能使敵人AI更具有智能性,使游戲更具趣味,研究這個課題的目的是在于能運用自己所學(xué)的知識,開發(fā)出一個完整的游戲。為以后自己能力的提升提供一個踏腳石。游戲的設(shè)計工具游戲的設(shè)計工具有編程工具MicrosoftVisualStudio2017,圖片繪制工具photoshop,游戲引擎工具Unity3d編程工具VisualStudio2017:MicrosoftVisualStudio是VS的全稱。VS是美國微軟公司的開發(fā)工具包系列產(chǎn)品。VS是一個基本完整的開發(fā)工具集,它包括了整個軟件生命周期中所需要的大部分工具,如UML工具、代碼管控工具、集成開發(fā)環(huán)境(IDE)等等。在Unity與VisualStudio的關(guān)系中,在舊版本Visualstudio2015以前是難以支持Unity的開發(fā)的,知道Visualstudio2015中新增了VisualStudioToolsforUnity

插件,給Unity的程序開發(fā)工作提供了支持,時至現(xiàn)在,在Visualstudio2017版本已經(jīng)是完全支持Unity3d的程序開發(fā)了,在Visualstudio2017版本中能夠快速找到Unity3d的腳本組件,為Unity3d的程序開發(fā)提高了效率。圖片繪制工具photoshop:AdobePhotoshop,簡稱“PS”,是由AdobeSystems開發(fā)和發(fā)行的圖像處理軟件。Photoshop主要處理以像素所構(gòu)成的數(shù)字圖像。使用其眾多的編修與繪圖工具,可以有效地進行圖片編輯工作。至今在各個領(lǐng)域中活躍著,如平面設(shè)計等,在2d游戲的開發(fā)中,必然少不了的是游戲素材,使用Photoshop能快速地繪制我們所需的2d游戲素材,在AdobePhotoshop中能導(dǎo)出多種格式的圖片,在Unity3d中都能很好地支持。游戲引擎工具Unity3d:Unity3D是由UnityTechnologies開發(fā)的一個讓玩家輕松創(chuàng)建諸如三維視頻游戲、建筑可視化、實時三維動畫等類型互動內(nèi)容的多平臺的綜合型游戲開發(fā)工具,是一個全面整合的專業(yè)游戲引擎。使用Unity3d可以創(chuàng)建屬于自己地2d和3d游戲,Unity3d內(nèi)部有很多功能豐富的API,能很多地滿足了游戲開發(fā)人員的各種開發(fā)需求。而且Unity3d是完全基于.net環(huán)境的,c#語言對其有很好的支持。游戲詳細設(shè)計本詳細設(shè)計將對游戲中重要的,復(fù)雜的邏輯進行詳細講解,具體詳細地講解游戲中各種邏輯地實現(xiàn),為后續(xù)希望開發(fā)同類游戲的開發(fā)者提供借鑒與參考。設(shè)置游戲場景地地圖由于2d游戲的地圖是采用sprite精靈圖片,由于手動擺放地圖圖片十分浪費時間,而且難以保證圖片之間是否存在縫隙,地圖由于是不規(guī)則形狀,為地圖設(shè)置碰撞器也是十分困難,而且十分耗費時間的事情。使用Unity系統(tǒng)自帶的tilemap地圖構(gòu)建系統(tǒng),這個新功能是Unity2017.2以及以上版本提供了這樣的新功能,這個新功能代替了傳統(tǒng)的2d游戲地圖的制作方式,大大提高了開發(fā)人員制作游戲地圖的速度。首先,介紹一下Tilemap的基本概念,Tilemap用起來其實就和現(xiàn)實中畫畫一樣,它由以下五個基本部分組成:Sprite(精靈):紋理的容器。大型紋理圖集可以轉(zhuǎn)換為精靈圖集(SpriteSheet)。Tile(瓦片):包含一個精靈,以及二個屬性,顏色和碰撞體類型。使用瓦片就像在畫布上畫畫一樣,畫畫時可以設(shè)置一些顏色和屬性。Palette(調(diào)色板):當(dāng)你在畫布(Canvas)上畫畫時,會需要一個位置來保存繪畫的結(jié)果。類似地,調(diào)色板(Palette)的功能就是保存瓦片,將它們繪制到網(wǎng)格上。Brush(筆刷):用于將畫好的東西繪制到畫布上。使用Tilemap時,可以在多個筆刷中任意選擇,繪制出線條、方塊等各種形狀。Tilemap(瓦片地圖):類似Photoshop中的圖層,我們可以在Tilemap上畫上Tile。只有有了Tilemap的工具,開發(fā)人員就可以根據(jù)美術(shù)素材,快速進行2d場景地圖的繪制了Tilemap部分其它工具Grid(網(wǎng)格):用于控制網(wǎng)格屬性的組件。Tilemap是Grid的子對象。Grid類似于UICanvas(UI畫布)。Tilemap渲染器(TilemapRenderer):用于控制Tile在Tilemap上的渲染,控制諸如排序、材質(zhì)和遮罩等。利用Tilemap開始進行地圖制作有了上面的理論之后,就開始進行實際的地圖制作了實現(xiàn)點擊window菜單按鈕,打開2d->tilepalette,打開調(diào)色板,創(chuàng)建一個新的調(diào)色板,命名為TileSet1,把素材用的精靈圖片拖到調(diào)色板上此時在層次面板上,點擊右鍵2dObjecttileMap,創(chuàng)建出一個Gird節(jié)點的物體在Gird節(jié)點下創(chuàng)建游戲需要的地板,背景和其他的一些裝飾等的一些Tilemap節(jié)點,分別命名為Platforms,Background,Decoration,F(xiàn)oregroundDecoration點擊Platforms,同時在調(diào)色板面板上的ActiveTilemap這里選擇Platforms,點擊筆刷工具,開始繪制地板點擊Gird節(jié)點的Background節(jié)點,同時在調(diào)色板面板上的ActiveTilemap這里選擇Background,這里雖然之前繪制了Platform的Tilemap,但是只要在ActiveTilemap選擇了另外的層之后,就不會影響之前的Platform。由于繪制了多層的Tilemap之后,而且tilemap和圖片一樣,都有繪制的順序的,要考慮到Tilemap之間的渲染順序,所以,在每個Tilemap的Tilemaprenderner組件的AdditionalSettings的sortinglayer中,為每個Tilemap添加對應(yīng)的sortinglayer。因為主角必須在地上行走,所以為地板和墻壁的Tilemap添加碰撞體,雖然tilemap本質(zhì)上是精靈圖片,可以加盒子碰撞器,但是按照傳統(tǒng)的盒子碰撞器的添加方法,效率不高,所以,采用的是Tilemap獨有的碰撞器添加方法添加Tilemapcollider2d,但是這種方法為每個tilemap的格子都添加盒子碰撞器,會消耗大量資源,因此,再為這個tilemap添加一個CompositeCollider2d,這種碰撞器會根據(jù)Tilemap的形狀計算,壓縮一些不必要的Tilemap碰撞器,只要在Tilemapcollider2d組件上,UsedByComposite勾選,CompositeCollider2D才會生效但是,在設(shè)置完后,運行游戲發(fā)現(xiàn)游戲的地板和墻壁掉下來,于是將地板和墻壁的Tilemap的2d剛體設(shè)置為Static,因為地板和墻壁是不會動的制作動畫將玩家各個動作的序列圖拖到層次面板上,將產(chǎn)生的動畫文件保存到Animatons的文件夾下,將野豬和稻草人的各個動作各個動作的序列圖拖到層次面板上,將產(chǎn)生的動畫文件保存到Animatons的文件夾下,制作玩家的控制方式(安卓控制腳本開發(fā))本游戲是支持pc平臺以及安卓平臺的,pc平臺主要是通過鍵盤按鍵輸入實現(xiàn)對玩家的控制,而安卓平臺是通過屏幕的觸摸檢測,通過按下手機屏幕設(shè)置的UI按鈕實現(xiàn)對玩家的控制,本小節(jié)介紹如何設(shè)置手機上的UI,實現(xiàn)對玩家的輸入。本小節(jié)的核心思路是通過觸摸插件EasyTouch,對玩家的輸入進行操作由于已經(jīng)導(dǎo)入了Easytouch插件,所以在層級面板上,就像普通的UGUI創(chuàng)建組件一樣,右鍵創(chuàng)建EasytouchControlsButton,創(chuàng)建出左右鍵,和攻擊跳躍等按鍵。又因為需要腳本掛載的游戲物體,所以在層級面板上,創(chuàng)建一個空物體scripts,在這個腳本上,掛載一個Mobilescrpts在這個腳本中,編寫玩家移動的方法,編寫玩家攻擊跳躍等的方法在玩家控制腳本上,使用下面的兩套預(yù)處理模板,分別處理當(dāng)游戲在安卓平臺上運行移動攻擊邏輯和當(dāng)游戲在標(biāo)準(zhǔn)windows平臺上運行時的玩家移動攻擊邏輯,這樣就能實現(xiàn)無論是在windows平臺或者是安卓平臺,游戲都能運行。

#ifUNITY_ANDROID安卓代碼運行處#endif和#ifUNITY_STANDALONE_WINwindows標(biāo)準(zhǔn)平臺運行處#endif創(chuàng)建角色的攝像機由于游戲是采用2d的游戲模式,玩家移動時候需要有一個攝像機進行玩家移動跟隨。在Unity的Packagemanage中,內(nèi)置了一個Cinemachine的插件,CineMachine能創(chuàng)建各種類型的攝像機,非常適合在本項目中使用。同時,CineMachine還提供了多種功能讓我們方便實現(xiàn)游戲中的其他功能。由于本項目是2d游戲,在菜單欄中,點擊Cinemachine的菜單項創(chuàng)建一個2dCamera角色跟隨功能的實現(xiàn)在Cinemachine中,由于這個組件已經(jīng)為我們內(nèi)置了非常多的常見的相機功能,也包括角色跟隨的功能,用這個插件,實現(xiàn)這個功能的步驟非常簡單,只需將整個角色的游戲物體的transform拖進新創(chuàng)建的2dCamera中開發(fā)玩家主角的各種狀態(tài)地面狀態(tài)由于是2d游戲,玩家需要在地面上行走,還有當(dāng)玩家需要進行跳躍時,要檢測是否能進行跳躍,所以檢測玩家是否在地上,是必不可少的條件。以往在3d游戲中,都只是直接在玩家身上只是添加一個全身的碰撞盒子,用全身的碰撞盒子和地面進行碰撞檢測,但是,在本項目中,存在墻壁,以及其他狀態(tài)都站在地上,很難和其他狀態(tài)進行區(qū)分,在以后的工作中,還需要進行墻壁的碰撞檢測,因此只是用玩家一個碰撞盒進行檢測和以后的墻壁碰撞檢測相互矛盾,因此,在玩家的物體上掛載一個空物體,用這個空物體進行碰撞檢測,但是,如果給這個空物體添加碰撞盒,必然會和玩家身上的碰撞盒發(fā)生碰撞,對檢測造成不必要的錯誤,因此,使用其他的方法進行碰撞檢測,在這里,使用物理函數(shù)Physics2D.OverlapCircle()進行射線檢測物理函數(shù)Physics2D.OverlapCircle()函數(shù)是檢測某個碰撞體是不是在某個圓形區(qū)域內(nèi),返回碰撞體。在玩家的物體下,掛一個空物體,命名為GroundCheck,用于檢測玩家是否已經(jīng)著地,如下圖所示檢測玩家是否著地是用Physics2D.OverlapCircle()函數(shù)來檢測是否著地,其中有三個參數(shù),第一個參數(shù)點,第二個參數(shù)是檢測的半徑,第三個參數(shù)是檢測的層定義三個參數(shù),其中第一個是transform類型公有變量groundCheck,groundCheck.position這個參數(shù)傳進檢測函數(shù)里面,用于指定檢測的物體的點,第二個參數(shù)是半徑groundCheckRadius,第三個是定義一個公有的Layermask變量whatIsGround,等腳本編譯后,在Unity編輯器里將Platforms的tilemap添加一個Layer為ground,把Platforms拖進腳本的ground中核心實現(xiàn)代碼如下:publicTransformgroundCheck;//檢測玩家是否著地publicLayerMaskwhatIsGround;//地面層isGrounded=Physics2D.OverlapCircle(groundCheck.position,groundCheckRadius,whatIsGround);設(shè)置多段跳(二段跳)由于玩家在跳躍的過程中,y軸上的速度有明顯的區(qū)別,在玩家上跳的過程中,玩家的速度方向沿著y軸的正方向增加,下落的過程中,玩家的速度方向沿著y軸的負方向減少。因此,可以用玩家速度的方向,把一套完整的跳躍的部分區(qū)分開。把一套跳躍動作分為三個部分,在Animator的參數(shù)列表中定義一個y軸上的速度,以y軸上的速度制作玩家跳躍的混合樹,混合樹分為三個階段,第一個階段是上升,第二個階段是上升到頂點,第三個階段是玩家達到最高點之后的下落階段墻壁滑動狀態(tài)在游戲中,玩家觸碰到墻壁并且按著前方向的話,玩家不會因為重力馬上掉下地面,而是和墻壁類似一種摩擦力讓玩家游戲?qū)ο缶徛龔膲Ρ谏匣聛?。由于玩家是在空中,并且觸碰到墻按著前方向的時候,才能擁有這種行為,因此,玩家需要滿足多項條件,第一項,玩家是在空中的狀態(tài),而不是在地上的狀態(tài),在地上觸碰到墻,是無法擁有這種狀態(tài)的。第二項,玩家是觸碰到墻,因為這種狀態(tài)只有觸碰到墻才能發(fā)生,第三項是,玩家按的方向和玩家游戲?qū)ο蟮那胺较蛞恢拢^前方向,就是玩家的正面面向的方向,只有滿足這三個狀態(tài),才能觸發(fā)玩家沿著墻壁緩慢滑下的行為。在玩家的物體下,掛一個空物體,命名為wallCheck,用于檢測玩家是否已經(jīng)觸碰墻壁檢測玩家是否著地是用射線檢測的方式檢測玩家是否觸碰墻壁,在本項目中不使用碰撞盒子檢測的方法,而是使用射線檢測,其對應(yīng)的函數(shù)是Physics2D.Raycast(),用射線檢測的好處是不用主角身上掛載太多碰撞盒子,其中有四個參數(shù),分別是檢測物體的點,方向,射線距離,射線檢測的層。定義四個參數(shù),其中第一個是transform類型公有變量wallCheck,wallCheck.position這個參數(shù)傳進檢測函數(shù)里面,用于指定檢測的物體的點,第二個參數(shù)是方向,傳進transform.right,即玩家的前方向,第三個參數(shù)是射線距離,定義一個float類型變量wallCheckDistance傳進函數(shù)中,第四個參數(shù)是射線檢測的層,把whatIsGround作為參數(shù)傳進函數(shù)中因為玩家身上具有多種狀態(tài),狀態(tài)與狀態(tài)如果不用一些標(biāo)志位進行區(qū)分,就會造成程序的混亂,為此,為玩家的滑動狀態(tài)創(chuàng)建一個標(biāo)志位變量isWallSliding在游戲的進行過程中,必須每個時候都要檢測玩家當(dāng)前所處的狀態(tài),因此,創(chuàng)建一個函數(shù)CheckIfWallSliding,用來檢測玩家是否處于墻壁滑動的狀態(tài)。實現(xiàn)檢測的核心代碼如下privatevoidCheckIfWallSliding(){if(isTouchingWall&&movementInputDirection==facingDirection&&rb.velocity.y<0&&!canClimbLedge){isWallSliding=true;//如果已經(jīng)觸碰到了墻壁,y軸上的速度是小于0(下落中),按鍵輸入的方向是玩家正面的朝向}else{isWallSliding=false;}}有了能檢測玩家是否處于滑動狀態(tài)的函數(shù),就必然要有處理玩家滑動行為的方法,在檢測玩家滑動狀態(tài)結(jié)果中,根據(jù)檢測的結(jié)果,處理玩家墻壁滑動的行為,實現(xiàn)滑動行為的代碼如下if(isWallSliding)//當(dāng)玩家正在處于墻壁滑動的狀態(tài)時{if(rb.velocity.y<-wallSlideSpeed){rb.velocity=newVector2(rb.velocity.x,-wallSlideSpeed);}}玩家向前跳由于自己定義的方法只能是在原地進行跳躍,在游戲中,常常需要根據(jù)玩家輸入的方向進行相應(yīng)方向的跳躍,所以,在原來的基礎(chǔ)上,結(jié)合輸入的方向,往該方向添加相應(yīng)的力便能往該方向進行跳躍。實現(xiàn)步驟:因為開始的跳躍是只是在原地進行跳躍,由于游戲有多個跨度比較大的平臺,玩家需要跳躍到對應(yīng)的平臺完成任務(wù),所以定義一個在空中移動的力量movementForceInAir定義一個Vector3的變量,把movementForceInAir*movementInputDirection的值傳進這個變量。作為x的值。剛體通過AddForce(),添加這個力添加到玩家剛體上二段跳躍和蹬墻跳躍在一些游戲中,二段跳和蹬墻跳躍是拓展玩家操作的一個有實際意義的操作。二段跳的使用場景玩家在跳上一些跨度比較大,或者高度比較高的平臺的時候,二段跳可以幫助玩家彌補跳躍寬度或者跳躍高度不足的缺陷。蹬墻跳的使用場景是玩家在一些需要跳躍一些比較高的高臺時,而且玩家使用二段跳也無法達到的高度時,玩家可以借助墻壁,將自己身體反彈,通過不斷反彈,達到玩家能夠達到的高度。二段跳:當(dāng)玩家在空中按下一次跳躍時,再按下跳躍鍵的時候,讓玩家往一個方向上產(chǎn)生一定大小的力蹬墻跳:玩家觸碰到墻,通過判斷玩家是否能達到能蹬墻跳的條件,然后根據(jù)玩家的朝向,往一定方向產(chǎn)生一定大小的力檢測蹬墻跳的核心代碼if(!isGrounded&&isTouchingWall&&movementInputDirection!=0&&movementInputDirection!=facingDirection){WallJump();//如果不在地上,觸碰到墻,有輸入方向}實現(xiàn)蹬墻跳核心代碼:///<summary>///墻壁跳躍///</summary>privatevoidWallJump(){if(canWallJump){rb.velocity=newVector2(rb.velocity.x,0.0f);//用一個力來跳躍,而不是像正常跳躍那樣直接設(shè)定速度,如果我們有一個向下的速度,我們失去了力,向下的速度越大,在你加上力后,我們向上的速度就越小isWallSliding=false;//一開始就將y軸的速度設(shè)置為0amountOfJumpsLeft=amountOfJumps;amountOfJumpsLeft--;Vector2forceToAdd=newVector2(wallJumpForce*wallJumpDirection.x*movementInputDirection,wallJumpForce*wallJumpDirection.y);rb.AddForce(forceToAdd,ForceMode2D.Impulse);//1,2是右上角的方向jumpTimer=0;//計時器清零isAttemptingToJump=false;//嘗試跳躍關(guān)閉checkJumpMultiplier=true;turnTimer=0;canMove=true;canFlip=true;hasWallJumped=true;wallJumpTimer=wallJumpTimerSet;lastWallJumpDirection=-facingDirection;}}墻角攀爬系統(tǒng)墻角攀爬系統(tǒng)是玩家除了二段跳和蹬墻跳之外的一種玩家移動的拓展方式。墻角攀爬系統(tǒng)是當(dāng)玩家通過跳躍,跳上一個平臺的角落邊緣下落時,能夠??吭谶吘壍奈恢茫⑶耶a(chǎn)生一小段的位移,到達平臺上,即玩家能進行一個攀爬動作,然后登上這個平臺,而不至于玩家因為跳躍高度只能達到墻角跳不上平臺,掉下地面首先判斷地圖中,那些是屬于平臺墻角的物體,只要玩家接觸到這些墻角,就能自動播放攀爬的動作,所以,首先是判定玩家什么時候才能懸掛。如圖所示,判斷的條件應(yīng)該是,首先,玩家的頭頂上沒有額外的平臺,和墻壁,并且下方應(yīng)該是有其他的墻壁的,還有游戲角色判定應(yīng)該離墻壁不是那么地遠,角色的頭頂發(fā)出的射線沒有碰撞到物體,而角色身體的射線應(yīng)該有碰撞到物體,只有符合這個條件,才能判定為懸掛狀態(tài)檢測的核心代碼如下isTouchingWall=Physics2D.Raycast(wallCheck.position,transform.right,wallCheckDistance,whatIsGround);isTouchingLedge=Physics2D.Raycast(ledgeCheck.position,transform.right,wallCheckDistance,whatIsGround);if(isTouchingWall&&!isTouchingLedge&&!ledgeDetected){ledgeDetected=true;ledgePosBot=wallCheck.position;//把攀爬下緣設(shè)置為身體射線的位置}等播放完玩家的攀爬動畫之后,玩家的游戲?qū)ο髸鶕?jù)墻角攀爬系統(tǒng)計算出來的結(jié)果而產(chǎn)生一段小的位移,到達平臺上面:具體的實現(xiàn)代碼如下privatevoidCheckLedgeClimb(){if(ledgeDetected&&!canClimbLedge){canClimbLedge=true;if(isFacingRight){ledgePos1=newVector2(Mathf.Floor(ledgePosBot.x+wallCheckDistance)-ledgeClimbXOffset1,Mathf.Floor(ledgePosBot.y)+ledgeClimbYOffset1);ledgePos2=newVector2(Mathf.Floor(ledgePosBot.x+wallCheckDistance)+ledgeClimbXOffset2,Mathf.Floor(ledgePosBot.y)+ledgeClimbYOffset2);}else{ledgePos1=newVector2(Mathf.Ceil(ledgePosBot.x-wallCheckDistance)+ledgeClimbXOffset1,Mathf.Floor(ledgePosBot.y)+ledgeClimbYOffset1);ledgePos2=newVector2(Mathf.Ceil(ledgePosBot.x-wallCheckDistance)-ledgeClimbXOffset2,Mathf.Floor(ledgePosBot.y)+ledgeClimbYOffset2);}canMove=false;canFlip=false;anim.SetBool("canClimbLedge",canClimbLedge);}if(canClimbLedge){transform.position=ledgePos1;}}在動畫狀態(tài)機中,設(shè)置好攀爬動畫的轉(zhuǎn)換條件和動畫和動畫之間轉(zhuǎn)換的參數(shù)之后,在攀爬動畫中,調(diào)出Animation面板,在Animation面板中打開攀爬動畫,在攀爬動畫的最后一幀,添加動畫事件,把動畫播放完之后要調(diào)用的事件函數(shù)傳進去玩家前沖殘影效果前沖殘影是指當(dāng)玩家輸入了前沖的操作時,玩家以一個十分迅速的速度進行一段比較長的位移,因為是玩家短時間內(nèi)進行一段比較長的位移,使用殘影效果突出玩家移動的迅捷。所謂殘影現(xiàn)象,是指眼睛捕獲移動事物的速度不及事物自身的移動速度時,使眼睛無法看清事物在運動中的位置,但因視覺暫留的影響,眼睛能看見事物之前位置的影像,這種影像被稱為殘影。襯托玩家的移動速度快,使用殘影最合適不過了。在玩家移動的過程中,記錄玩家移動過的位置,將玩家移動過的位置存進一個物體中,讓這個物體跟隨著物體,根據(jù)移動的距離的不同,設(shè)置相應(yīng)數(shù)量的殘影,殘影的透明度也會隨著玩家位置的增多而變淡。核心原理是對象池技術(shù),由于在游戲中,頻繁調(diào)用銷毀方法,生成方法會極大地消耗系統(tǒng)地資源,而對象池技術(shù)能很好地彌補了這個缺點。對象池背后的理念其實是非常簡單的。我們將對象存儲在一個池子中,當(dāng)需要時在再次使用,而不是每次都實例化一個新的對象。池的最重要的特性,也就是對象池設(shè)計模式的本質(zhì)是允許我們獲取一個“新的”對象而不管它真的是一個新的對象還是循環(huán)使用的對象。創(chuàng)建一個腳本PlayerAfterImageSprite,掛載到一個空物體上,這個腳本用來記錄玩家經(jīng)過的單個位置,玩家的旋轉(zhuǎn),以及玩家位置變化的透明度值再創(chuàng)建一個空腳本PlayerAfterImagePool,掛載到一個空物體上,這個腳本用來管理每個AfterImage的產(chǎn)生與銷毀,充當(dāng)對象池的作用實現(xiàn)對象池具體代碼如下[SerializeField]privateGameObjectafterImagePrefab;privateQueue<GameObject>availableObjects=newQueue<GameObject>();publicstaticPlayerAfterImagePoolInstance{get;privateset;}privatevoidAwake(){Instance=this;GrowPool();}privatevoidGrowPool(){for(inti=0;i<10;i++){varinstanceToAdd=Instantiate(afterImagePrefab);instanceToAdd.transform.SetParent(transform);AddToPool(instanceToAdd);}}publicvoidAddToPool(GameObjectinstance){instance.SetActive(false);availableObjects.Enqueue(instance);}publicGameObjectGetFromPool(){if(availableObjects.Count==0){GrowPool();}varinstance=availableObjects.Dequeue();instance.SetActive(true);returninstance;}殘影的具體實現(xiàn)過程是通過記錄玩家的經(jīng)過的單個位置,以及單個位置之間的距離,然后從對象池中取出數(shù)據(jù),并將玩家當(dāng)前的位置賦值給對象池中最后的位置,完成對象池的更新,最后的判斷邏輯是當(dāng)玩家當(dāng)前的位置和對象池中最后的一個位置之間的差值大于殘影之間的距離時,將玩家當(dāng)前的位置賦值給殘影的最后一個。另外再聲明一個函數(shù)CheckDash,用于檢測玩家前沖的狀態(tài),關(guān)鍵的語句是if(Mathf.Abs(transform.position.x-lastImageXpos)>distanceBetweenImages){PlayerAfterImagePool.Instance.GetFromPool();lastImageXpos=transform.position.x;}玩家攻擊系統(tǒng)在游戲中,玩家需要不斷向目標(biāo)地點前進,必然要掃清前進路上的障礙,所以玩家需要攻擊路上遇到的怪物,消滅怪物,才能達到目標(biāo)地點:需求分析:玩家的精靈圖片是附帶武器的,所以用整個玩家作為攻擊檢測必然不適合,所以,在玩家身上添加一個空物體,玩家移動時,空物體也會隨著移動,在空物體上進行無碰撞盒的碰撞檢測。同時,要保證玩家攻擊時間的間隔還有攻擊動畫的正常播放。即使玩家輸入了攻擊動作,但是如果這個時候的狀態(tài)不允許攻擊的話,還是不能進行攻擊的,所以,聲明一個函數(shù)CheckAttacks,用于檢測玩家這個時候是否符合攻擊的條件,以Time.time>=lastInputTime+inputTimer來判定玩家不能進行攻擊修正玩家攻擊時的細節(jié)攻擊動畫播放的時候,玩家是不允許翻轉(zhuǎn)身體的方向的,即x軸的方向,但是玩家攻擊動畫播放完之后,就可以翻轉(zhuǎn)了,所以,要定義兩個方法,一個方法DisableFlip,用于禁用玩家翻轉(zhuǎn),一個方法EnableFlip,用于恢復(fù)玩家翻轉(zhuǎn)的功能打開玩家的攻擊動畫的Animation的面板,在攻擊動畫的開始幀,添加事件,選中DisableFlip方法。將近動畫結(jié)束的時候的附近的一幀,添加事件,選中EnableFlip.添加一個方法FinishAttack1,這個方法用于當(dāng)玩家的攻擊動畫播放完的時候,將攻擊動作清零,打開玩家的攻擊動畫的Animation的面板,在每段攻擊動畫的結(jié)束幀,添加事件,選中FinishAttack1方法玩家攻擊邏輯實現(xiàn)添加一個方法CheckAttackHitBox,用于檢測玩家攻擊到的物體,核心原理是:在玩家的節(jié)點下,掛載一個Attack1Position的空物體,使用Physics2D.OverlapCircleAll的方法,獲取到攻擊空物體Attack1Position觸碰到的物體,遍歷循環(huán)玩家攻擊空節(jié)點CheckAttackHitBox觸碰到的物體,用SendMessage的形式,給碰撞到的物體的父節(jié)點發(fā)送消息,執(zhí)行Damage方法,其中attackDetails是一個數(shù)組,保存著玩家攻擊對象,以及攻擊位置的x值實現(xiàn)代碼是:privatevoidCheckAttackHitBox()//檢測攻擊物體{Collider2D[]detectedObjects=Physics2D.OverlapCircleAll(attack1HitBoxPos.position,attack1Radius,whatIsDamageable);attackDetails[0]=attack1Damage;attackDetails[1]=transform.position.x;foreach(Collider2DcolliderindetectedObjects){collider.transform.parent.SendMessage("Damage",attackDetails);//調(diào)用碰撞物體的父親節(jié)點上的方法//Instantiatehitparticle}}敵人系統(tǒng)敵人系統(tǒng)分為兩個作為示范,第一個是無攻擊力的稻草人模型,第二個是具有攻擊力,能讓玩家受到傷害的敵人野豬稻草人模型游戲中的稻草人是無攻擊力的,稻草人在受到玩家的攻擊時,會朝著玩家攻擊的方向的反方向進行后退,造成被玩家擊退的效果,在稻草人的生命值下降為0時,稻草人會有一個炸開的效果,即給人一種玩家把稻草人劈斷的效果攻擊用稻草人將稻草人的全身分為三部分,第一部分為Alive,是整個完整的稻草人的精靈圖片,第二部分是BrokenTop,是除去稻草人下部分的精靈圖片,第三部分是稻草人的下部BrokenBottom,全部分Alive的層級設(shè)置為Damageable,將稻草人的其他部分的層級設(shè)置為Dead,因為稻草人由三部分組成,每個部分都有自己的碰撞體,因此,當(dāng)?shù)静萑俗鳛橐粋€整體移動的時候,稻草人之間會產(chǎn)生碰撞,發(fā)生錯誤。由于游戲里設(shè)定為玩家可以穿過稻草人,所以稻草人和玩家之間不會產(chǎn)生碰撞,所以,將稻草人的各個部分,以及稻草人和玩家之間的碰撞忽略掉,所以,打開EditProjectSetting,打開Physics2D面板,將Damageable層和Damageable層碰撞去掉,將Damageable層和Dead層的碰撞去掉,將Player層和Dead層的碰撞去掉,將Dead層和Dead層的碰撞去掉。開始的時候,在腳本里獲取了稻草人的三個部分的剛體以及gameobject對象,在start方法中把稻草人的上半部和下半部都隱藏,只留下稻草人的完整部分Alive實現(xiàn)代碼是aliveGO=transform.Find("Alive").gameObject;brokenTopGO=transform.Find("BrokenTop").gameObject;brokenBotGO=transform.Find("BrokenBottom").gameObject;aliveGO.SetActive(true);brokenTopGO.SetActive(false);brokenBotGO.SetActive(false);而稻草人的邏輯是獲取玩家的面向,當(dāng)?shù)静萑说难刻幱诮】禒顟B(tài)的時候,產(chǎn)生擊退的效果。擊退效果的實現(xiàn)原理是:當(dāng)?shù)静萑吮煌婕覔糁械臅r候,往玩家的相反的方向產(chǎn)生一個速度,實現(xiàn)代碼是privatevoidKnockback(){knockback=true;knockbackStart=Time.time;rbAlive.velocity=newVector2(knockbackSpeedX*playerFacingDirection,knockbackSpeedY);//被砍后,往這個方向產(chǎn)生速度}根據(jù)時間,判斷稻草人是否能進行被擊打后產(chǎn)生后退效果,一面稻草人后退的頻率太過于頻繁,實現(xiàn)代碼是privatevoidCheckKnockback(){if(Time.time>=knockbackStart+knockbackDuration&&knockback){knockback=false;rbAlive.velocity=newVector2(0.0f,rbAlive.velocity.y);}}添加一個函數(shù)Die,用于處理稻草人生命值為0的時候的死亡邏輯。具體的邏輯是:當(dāng)?shù)静萑说纳禐?時,不再播放后退動畫,然后把稻草人的全身部分Alive進行隱藏,將稻草人的上半部分和下半部分顯示出來,稻草人的上半部分和下半部分都獲得了一個速度,然后使用AddTorque方法,對上半部分的剛體施加一個旋轉(zhuǎn)力,使上半部分和下半部分進行分離實現(xiàn)的核心代碼是:privatevoidDie(){aliveGO.SetActive(false);brokenTopGO.SetActive(true);brokenBotGO.SetActive(true);brokenTopGO.transform.position=aliveGO.transform.position;brokenBotGO.transform.position=aliveGO.transform.position;rbBrokenBot.velocity=newVector2(knockbackSpeedX*playerFacingDirection,knockbackSpeedY);rbBrokenTop.velocity=newVector2(knockbackDeathSpeedX*playerFacingDirection,knockbackDeathSpeedY);rbBrokenTop.AddTorque(deathTorque*-playerFacingDirection,ForceMode2D.Impulse);}在玩家攻擊到稻草人的時候,在稻草人的全身Alive上產(chǎn)生一個粒子效果。具體實現(xiàn)是,在傷害稻草人的函數(shù)處理中,實例化一個粒子效果的預(yù)制體,而且粒子效果的預(yù)制體上掛載一個銷毀自身的腳本野豬模型敵人野豬是具有多種狀態(tài),碰到玩家的身體,能對玩家造成一定傷害的敵人需求分析:敵人野豬具有多種狀態(tài),有巡邏狀態(tài),被攻擊的狀態(tài),死亡的狀態(tài),控制的腳本一定要方便對敵人野豬的各種狀態(tài)進行切換和野豬狀態(tài)的進一步擴展敵人野豬的邏輯可以采用有限狀態(tài)機的方式來控制,有限狀態(tài)機的含義:有限狀態(tài)機,也稱為FSM(FiniteStateMachine),其在任意時刻都處于有限狀態(tài)集合中的某一狀態(tài)。當(dāng)其獲得一個輸入字符時,將從當(dāng)前狀態(tài)轉(zhuǎn)換到另一個狀態(tài),或者仍然保持在當(dāng)前狀態(tài)。任何一個FSM都可以用狀態(tài)轉(zhuǎn)換圖來描述,圖中的節(jié)點表示FSM中的一個狀態(tài),有向加權(quán)邊表示輸入字符時狀態(tài)的變化。如果圖中不存在與當(dāng)前狀態(tài)與輸入字符對應(yīng)的有向邊,則FSM將進入“消亡狀態(tài)(DoomState)”,此后FSM將一直保持“消亡狀態(tài)”,而有限狀態(tài)機中,最重要的是狀態(tài)之間的切換,更新,以及進入,如下代碼所示:在本游戲中,將使用簡單版本的有限狀態(tài)機對野豬行為進行驅(qū)動.privatevoidEnterMovingState()//進入移動狀態(tài)privatevoidUpdateMovingState()//更新狀態(tài)rivatevoidExitMovingState()//離開狀態(tài)按照有限狀態(tài)機的模板,定義野豬的行為狀態(tài),以及各種狀態(tài)之間的切換,以及編寫野豬的幾種狀態(tài)的切換首先定義野豬的所有行為的枚舉privateenumState//定義敵人的全部狀態(tài){Moving,Knockback,Dead}分別處理編寫野豬的三個不同狀態(tài)時的處理邏輯開發(fā)敵人野豬的行走(Moving,)狀態(tài),使用射線檢測,檢測敵人野豬是否觸碰到地面,和檢測敵人野豬是否觸碰到墻壁,如果觸碰到墻壁,就讓敵人野豬往后走(翻轉(zhuǎn)敵人野豬的身體),如果沒有的話,就進行敵人野豬的行走模式,這個方法寫在UpdateMovingState方法中,用于一直檢測敵人野豬移動狀態(tài)的更新privatevoidUpdateMovingState()//更新狀態(tài){groundDetected=Physics2D.Raycast(groundCheck.position,Vector2.down,groundCheckDistance,whatIsGround);wallDetected=Physics2D.Raycast(wallCheck.position,transform.right,wallCheckDistance,whatIsGround);CheckTouchDamage();if(!groundDetected||wallDetected){Flip();}else{movement.Set(movementSpeed*facingDirection,aliveRb.velocity.y);aliveRb.velocity=movement;}}開發(fā)野豬的受攻擊(Knockback)的狀態(tài),使用玩家的位置和敵人野豬位置做比較,判斷野豬受到攻擊后,野豬被擊退的方向,如果野豬受攻擊后,敵人野豬的當(dāng)前血量大于0,則調(diào)用SwitchState函數(shù),將當(dāng)前狀態(tài)設(shè)置為進入擊退狀態(tài),即EnterKnockbackState,在EnterKnockbackState的處理邏輯是把當(dāng)前的邏輯存儲起來,然后給野豬一個后退的速度,播放野豬Knockback的動畫,在ExitKnockbackState函數(shù)的處理邏輯是將野豬的Knockback動畫停止播放,在UpdateKnockbackState函數(shù)中的處理邏輯是判斷當(dāng)前時間是否滿足后退的時間,如果不滿足的話,就將敵人野豬設(shè)置為行走狀態(tài)privatevoidEnterKnockbackState(){knockbackStartTime=Time.time;movement.Set(knockbackSpeed.x*damageDirection,knockbackSpeed.y);aliveRb.velocity=movement;aliveAnim.SetBool("Knockback",true);}制作敵人野豬死亡時候的狀態(tài),具體過程是玩家擊殺野豬后,血跡粒子綻開,留在地上,過一會消失,為粒子再添加上碰撞體,制作好血跡粒子效果后,把血跡粒子拖到項目文件夾中,使之成為預(yù)制體,在野豬進入死亡函數(shù)中實例化這個死亡粒子。具體代碼是privatevoidEnterDeadState(){Instantiate(deathChunkParticle,alive.transform.position,deathChunkParticle.transform.rotation);Instantiate(deathBloodParticle,alive.transform.position,deathBloodParticle.transform.rotation);Destroy(gameObject);}游戲的小地圖(Minimap)由于游戲是橫板游戲,在游戲過程中將會有很多的分岔路,玩家為了實現(xiàn)某種目的,或為了尋找某種道具,或者是達到Boss所在的地方,為了減少玩家的尋找時間,游戲中通常會有小地圖幫助玩家快速到達目的地或者完成任務(wù).開發(fā)思路是另外創(chuàng)建一個攝像機,這個攝像機用于拍攝整個地圖,創(chuàng)建一個RenderTexture,用于把整個地圖的拍攝情況報存下來,另外再在層級面板創(chuàng)建一個RawImage,把RawImage放在整個場景的中間,將創(chuàng)建出的RenderTexture拖到RawImage面板上,讓RawImage來顯示拍攝的內(nèi)容在地圖下創(chuàng)建簡單版的地圖,放在原來地圖下面,作為地圖的子物體,把場景中相應(yīng)的簡單版的縮略圖放在場景中對應(yīng)的物體下,成為那個物體的子物體為地圖的子物體,和場景中各個物體對應(yīng)的縮略圖添加一個Minamap的層,把這些物體全部添加進這個層點擊主攝像機,選擇主攝像機的Camera組件,選擇Camera組件中的Cullingmask,把Minimap的層級去掉,這樣主攝像機就不會渲染到小地圖(Minimap)層級的內(nèi)容了而實際上,小地圖是這樣擺放的小地圖用的是青色的圖片,在去掉小地圖渲染之后,地板還是原來的顏色復(fù)制主攝像機,調(diào)整相關(guān)參數(shù),刪除多余的AudioSource,把新的Camera的Camera組件中可渲染層設(shè)置為Minimap,這樣這個camera只是負責(zé)渲染出minimap的內(nèi)容了創(chuàng)建一個RawImage,把這個RawImage放到場景右下角,創(chuàng)建一個Rendertexture,把新攝像機拍攝到的內(nèi)容用Rendertexture存儲起來,然后把這個Rendertexture賦值給RawImage,運行游戲,就可以看到游戲縮略圖中,玩家在小地圖中的運行情況對話系統(tǒng)由于游戲是橫板游戲,為了讓游戲更具有趣味性,讓玩家能投入其中,決定加入對話系統(tǒng),對話系統(tǒng)能交代游戲的背景劇情,或者讓玩家接收一些任務(wù),指引玩家去完成這些人物獲取相應(yīng)的獎勵游戲?qū)υ捪到y(tǒng)的實現(xiàn)方法有很多,如使用傳統(tǒng)的UGUI模式去開發(fā),使用一定的邏輯進行句子的插入。但是游戲中對話系統(tǒng)的插件有很多,這個游戲采用Fungus插件進行開發(fā)Fungus插件是一個強大的文字游戲插件,它支持多種方式創(chuàng)建游戲中人物的對話,它采用Unity流行的可視化的流程開發(fā)插件,打開Fungus后,它以窗口的形式來創(chuàng)建來創(chuàng)建一個管理全部人物對話的管理者,在管理者中,分為一個一個Flowchart工作流程,在每個工作流程中創(chuàng)建人物完整的一段對話,每個流程中又以線標(biāo)志著流程與流程之間的轉(zhuǎn)換關(guān)系玩家的觸碰敵人受到傷害和玩家死亡后的重生系統(tǒng)玩家在攻擊敵人的時候,有時候難免會被敵人攻擊到,因此,需要對玩家進行受到傷害的檢測。在玩家的生命值耗盡的時候,玩家會死亡,在玩家死亡的時候,為了能讓玩家重新進行游戲,需要讓玩家重新生成,不需要重新開始游戲,這時候需要玩家死亡后的重生系統(tǒng)玩家觸碰到敵人受到傷害是通過在敵人身上的傷害盒子進行碰撞檢測的,實現(xiàn)玩家重生系統(tǒng),當(dāng)玩家死亡之后,經(jīng)過一定的時間將玩家重新生成到指定的位置,因為玩家死亡的時候攝像機也是會丟失跟隨的對象的,當(dāng)重新生成玩家的時候,必須在生成玩家的同時,重新指定攝像機跟隨的對象。實現(xiàn)步驟:玩家碰撞傷害檢測具體使用的函數(shù)是Physics2D.OverlapArea,游戲?qū)⑹褂肅ollider2DOverlapArea(Vector2pointA,Vector2pointB,intlayerMask);形式的重載函數(shù),這個函數(shù)具體的作用是檢測由PointA和PointB組成的區(qū)域的碰撞體,在上一個步驟中,通過計算出傷害盒的左下角的點的值和傷害盒的右上角的值,傳進這個函數(shù)中,即檢測這兩個點組成的矩形區(qū)域,把創(chuàng)建出的whatIsPlayer玩家層級傳進函數(shù)的第三個參數(shù)中實現(xiàn)代碼如下:privatevoidCheckTouchDamage(){if(Time.time>=lastTouchDamageTime+touchDamageCooldown){touchDamageBotLeft.Set(touchDamageCheck.position.x-(touchDamageWidth/2),touchDamageCheck.position.y-(touchDamageHeight/2));touchDamageTopRight.Set(touchDamageCheck.position.x+(touchDamageWidth/2),touchDamageCheck.position.y+(touchDamageHeight/2));Collider2Dhit=Physics2D.OverlapArea(touchDamageBotLeft,touchDamageTopRight,whatIsPlayer);if(hit!=null){lastTouchDamageTime=Time.time;attackDetails[0]=touchDamage;attackDetails[1]=alive.transform.position.x;hit.SendMessage("Damage",attackDetails);}}}在使用這個函數(shù)后,把對玩家的傷害用attackDetails[0]保存起來,把接觸的點用attackDetails[1]保存起來,接觸的點保存起來,創(chuàng)建玩家控制類的受傷害函數(shù)中,用來指定玩家受到傷害之后后退的方向,最后用SendMessage方法發(fā)送消息給這個碰撞傷害盒通過碰撞檢測檢測到的物體hit(玩家),讓hit運行受傷Damage方法。在玩家腳本里編寫玩家受到傷害后后退的函數(shù),具體的實現(xiàn)方法和野豬稻草人的擊退函數(shù)形式一樣。實現(xiàn)PlayerCombatController中Damage函數(shù)的邏輯,將Damage函數(shù)的形式參數(shù)寫為float[]attackDetails,把之前保存的attackDetails[0],和attackDetails[1]進行后續(xù)的邏輯處理實現(xiàn)代碼如下:privatevoidDamage(float[]attackDetails){if(!PC.GetDashStatus()){intdirection;PS.DecreaseHealth(attackDetails[0]);if(attackDetails[1]<transform.position.x){direction=1;}else{direction=-1;}PC.Knockback(direction);}}重生系統(tǒng)在玩家死亡后,經(jīng)過一定的時間,重新復(fù)活玩家對象在某一個指定的地點在管理玩家健康的類中,根據(jù)玩家剩下的血量判斷玩家是否已經(jīng)死亡,如果死亡就執(zhí)行玩家死亡的邏輯,然后經(jīng)過一定的時間重新生成玩家在一個指定的地點定義一個Transform類型的變量respawnPoint,用于表示玩家重生地點的引用。定義一個Gameobject類型的變量player,并且把player做成預(yù)制體,然后根據(jù)時間變量,對玩家進行重新的生成對象下面是進行玩家重生的核心代碼:privatevoidCheckRespawn(){if(Time.time>=respawnTimeStart+respawnTime&&respawn){varplayerTemp=Instantiate(player,respawnPoint);respawn=false;}}由于玩家死亡,被銷毀后,在場景的攝像機的跟隨的目標(biāo)也會丟失,所以定義一個CinemachineVirtualCamera類型的變量CVC,用于引用場景中的PlayerCamera的CinemachineVirtualCamera組件通過時間判斷,玩家是否可以重生,如果可以進行重生,則將玩家的預(yù)制體生成在指定的地點,然后將CVC跟隨的對象設(shè)置為生成的對象,所以在上面的重生代碼中加入下面代碼:CVC.m_Follow=playerTemp.transform;//將相機的跟隨對象設(shè)置為玩家的位置輔助工具Gizmos在日常開發(fā)中,免不了要經(jīng)常進行Debug測試,在Unity自帶的組件中,點擊對象,查看改對象的屬性面板,在對象的屬性面板中,有一個SelectIcon的按鈕,選擇其中的一個,就可以繪制Unity自帶的debug對象。但是,在本游戲中,涉及到圓形碰撞,方形碰撞等的幾何圖片的debug,Unity自帶的debug是不具備這些功能的,在本項目中,很多地方用了射線檢測,以及碰撞盒子檢測等功能,但是實際上,開發(fā)人員是不知道這些射線具體有多長,必須用數(shù)據(jù)多次進行測試,還需要多次點擊運行按鈕,為了給開發(fā)人員能夠直觀地觀察到效果,而且又不用多次運行,Unity提供了一個方便的,能夠進行拓展的可視化Debug的函數(shù)入口,OnDrawGizmos,在此函數(shù)中,Unity會根據(jù)我們給出的條件,在Scene窗口中繪制我們指定的形狀,供我們在運行時,時刻在Scene窗口中查看情況,以供隨時調(diào)整參數(shù)在游戲中,有幾處地方是用到OnDrawGizmos玩家的射線檢測,玩家在地面的碰撞檢測,玩家與墻壁的碰撞檢測玩家與敵人野豬的碰撞檢測以玩家的射線檢測為例,說明實現(xiàn)的步驟:在玩家的控制腳本中,PlayerController中,添加OnDrawGizmos函數(shù),因為玩家的射線檢測是由玩家身上的wallCheck空物體發(fā)出射線,進行檢測,所以,在OnDrawGizmos函數(shù)中,添加Gizmos.DrawLine函數(shù),這個函數(shù)的作用是在指定的位置上,繪制一條線段,函數(shù)有兩個參數(shù),分別為初始向量和結(jié)尾向量,所以,在玩家的射線檢測中,功能寫為Gizmos.DrawLine(),只要向該函數(shù)中傳入所需要的參數(shù),scene窗口就能繪制出需要的效果了。野豬的Gizmos的代碼實現(xiàn)如下:privatevoidOnDrawGizmos(){Gizmos.DrawLine(groundCheck.position,newVector2(groundCheck.position.x,groundCheck.position.y-groundCheckDistance));Gizmos.DrawLine(wallCheck.position,newVector2(wallCheck.position.x+wallCheckDistance,wallCheck.position.y));Vector2botLeft=newVector2(touchDamageCheck.position.x-(touchDamageWidth/2),touchDamageCheck.position.y-(touchDamageHeight/2));Vector2botRight=newVector2(touchDamageCheck.position.x+(touchDamageWidth/2),touchDamageCheck.position.y-(touchDamageHeight/2));Vector2topRight=newVector2(touchDamageCheck.position.x+(touchDamageWidth/2),touchDamageCheck.position.y+(touchDamageHeight/2));Vector2topLeft=newVector2(touchDamageCheck.position.x-(touchDamageWidth/2),touchDamageCheck.position.y+(touchDamageHeight/2));Gizmos.DrawLine(botLeft,botRight);Gizmos.DrawLine(botRight,topRight);Gizmos.DrawLine(topRight,topLeft);Gizmos.DrawLine(topLeft,botLeft);}開發(fā)總結(jié)本課題研究的課題到此就完成了,在開發(fā)的過程中,存在著很多的問題。從游戲題材的選擇,開發(fā)方式的選擇,以及功能的實現(xiàn)思路,全部都有很講究的學(xué)問在里面。在開發(fā)的過程中,使用到非常多的數(shù)學(xué)知識,我這才體會到游戲開發(fā)和數(shù)學(xué)知識的掌握是有著密不可分的關(guān)系,在玩家的移動,以及玩家的一些狀態(tài)的開發(fā)中,都需要用到數(shù)學(xué)的計算,因為這些部分完全就是和自己掌握數(shù)學(xué)知識的程度有關(guān),已經(jīng)和自己的程序編程能力沒太大關(guān)系了,程序編程只是一個工具,關(guān)鍵是怎么去計算,因為自己數(shù)學(xué)能力的不足,走過了不少的彎路,在解決問題的過程中,有翻閱以前學(xué)到的數(shù)學(xué)知識,也有網(wǎng)上查閱資料和虛心請教老師和同學(xué)們,最終,因為重新掌握了這些基礎(chǔ)的數(shù)學(xué)知識和請教了很多的同學(xué)和老師后,問題也能解決,因為這次的開發(fā)經(jīng)驗,也體會到了一個完整的游戲從構(gòu)思到實現(xiàn)遇到的種種困難,為以后獨立開發(fā)的道路上,打好了一定的基礎(chǔ)。參考文獻[1]設(shè)計模式與游戲完美開發(fā)[蔡升達][清華大學(xué)出版社][2017.01][477頁][14179794][2]Unity5實戰(zhàn)使用C#和Unity開發(fā)多平臺游戲[清華大學(xué)出版社][3]手機游戲角色設(shè)計民族化研究[D].[王金婷]長春工業(yè)大學(xué),2016.[4]基于Android平臺的智力猜牌游戲設(shè)計與開發(fā)[D][胡勁松].東南大學(xué),2016.[5]基于Android平臺的手機游戲的設(shè)計與開發(fā)[D][秦成].云南大學(xué),2015.[6]基于Unity3D游戲動作的控制和設(shè)計[J][郭睿靜,張帥].蘭州文理學(xué)院學(xué)報(自然科學(xué)版),2015,[7]吳亞峰,索依娜.Uinty5.X3D游戲開發(fā)技術(shù)詳解與典型案例[M].北京:人民郵電出版社,2016.[8]金璽曾.Uinty3D\2D手機游戲開發(fā)(第二版)[M].北京:清華大學(xué)出版社,2014.[9]徐婉珍,李強,魏菊霞。在游戲開發(fā)實踐中培養(yǎng)程序設(shè)計能力[J].計算機教育,2017,(02):104-106.[10]晉錚,章立。游戲設(shè)計中的極簡主義風(fēng)格研究[J].包裝工程,2016,(14):161-164.[11]Unity官方文檔/ScriptReference/index.html.[12]謝韜.基于Unity3D粒子系統(tǒng)的游戲特效實現(xiàn)[J].現(xiàn)代計算機(專業(yè)版),2015(24):30-32.[13]邱竟峰,王洪源,陳慕羿.Unity3D引擎實

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論