基于Unity3D的RPG解謎類游戲_第1頁(yè)
基于Unity3D的RPG解謎類游戲_第2頁(yè)
基于Unity3D的RPG解謎類游戲_第3頁(yè)
基于Unity3D的RPG解謎類游戲_第4頁(yè)
基于Unity3D的RPG解謎類游戲_第5頁(yè)
已閱讀5頁(yè),還剩42頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

緒論1.1選題研究背景及意義隨著數(shù)字媒體技術(shù)的發(fā)展和人們審美水平的日益提高,數(shù)字游戲在集引人入勝的畫面、如夢(mèng)似幻的聲音、扣人心弦的情節(jié)等要素于一身后,自成第九大藝術(shù)體。RPG(Role-PlayingGame)角色扮演游戲是許多玩家喜愛(ài)的游戲類型之一。玩家在游戲中扮演某個(gè)角色并遵循游戲世界中的規(guī)則,控制角色在游戲中進(jìn)行游戲活動(dòng),完成各種各樣的任務(wù)。RPG游戲不僅在娛樂(lè)方面展露頭角,而且廣泛運(yùn)用于各種領(lǐng)域,如教育教學(xué)的模擬,醫(yī)學(xué)解剖等。近年來(lái),各種各樣的游戲?qū)映霾桓F,2014年UstwoGamesLtd開(kāi)發(fā)的角色扮演解密類手機(jī)游戲“紀(jì)念碑谷”在游戲行業(yè)中熠熠生輝,2017年“紀(jì)念碑谷2”再創(chuàng)佳績(jī)。玩家在游戲中扮演公主艾達(dá),通過(guò)視覺(jué)錯(cuò)位的關(guān)卡,隱秘的路徑來(lái)?yè)魯貘f人從而走出紀(jì)念碑迷陣。該游戲一問(wèn)世,它就以其詩(shī)意的圖像和配樂(lè)而聞名。一款備受推崇的游戲離不開(kāi)別出心裁的故事情節(jié),精妙絕倫的關(guān)卡設(shè)計(jì)以及美輪美奐的畫面和音效。游戲設(shè)計(jì)與開(kāi)發(fā)的挑戰(zhàn)性就在于此,在游戲開(kāi)發(fā)的過(guò)程中不僅要豐富玩家的游戲體驗(yàn),讓玩家身臨其境,而且要增強(qiáng)游戲的趣味性可玩性,能讓玩家沉浸于此并樂(lè)在其中。游戲開(kāi)發(fā)離不開(kāi)游戲引擎的支持。在眾多游戲引擎中,Unity3D是業(yè)內(nèi)廣泛使用的游戲引擎,Unity3D是丹麥開(kāi)發(fā)的完全集成的專業(yè)游戲引擎,允許開(kāi)發(fā)人員輕松創(chuàng)建多平臺(tái)游戲開(kāi)發(fā)工具,尤其適用于開(kāi)發(fā)3D游戲[1]。內(nèi)置編輯器,跨平臺(tái)部署,地形編輯,著色,碰撞器,腳本,網(wǎng)絡(luò),物理,UGUI框架,版本控制等功能可以為開(kāi)發(fā)人員提供更多開(kāi)發(fā)。Unity3D不僅界面簡(jiǎn)單易用,功能易于運(yùn)行,而且配置文件版本對(duì)于開(kāi)發(fā)人員來(lái)說(shuō)是免費(fèi)的,而它也可以運(yùn)行在多個(gè)平臺(tái)上開(kāi)發(fā)的游戲[2]。國(guó)內(nèi)3D游戲始于2003年,比國(guó)外3D游戲的開(kāi)發(fā)晚得多。游戲開(kāi)發(fā)和技術(shù)支持的概念存在不可逾越的差距[13]。目前,Unity3D游戲引擎在國(guó)內(nèi)和國(guó)際游戲產(chǎn)業(yè)中占據(jù)主導(dǎo)地位,其工作和功能對(duì)于游戲的未來(lái)發(fā)展和監(jiān)控游戲質(zhì)量具有重要意義[3]。由于此引擎具有:優(yōu)越的游戲表現(xiàn)力——粒子系統(tǒng)、后期渲染特效、可視化界面等為游戲的畫面感提供了強(qiáng)大的幫助,多平臺(tái)發(fā)布的簡(jiǎn)單操作性,省去了底層編碼的環(huán)節(jié),縮短了游戲開(kāi)發(fā)周期,降低開(kāi)發(fā)成本。本項(xiàng)目是一款基于Unity3D引擎開(kāi)發(fā)的RPG解謎類游戲“第七元素”,結(jié)合了典型的動(dòng)作RPG游戲的人物操作競(jìng)技性和打擊感以及解謎類游戲的寓教于樂(lè)的益智性和趣味性。1.2國(guó)內(nèi)外RPG游戲研究現(xiàn)狀國(guó)內(nèi)RPG游戲源形成于上世紀(jì)八十年代初的中國(guó)臺(tái)灣,此時(shí)歐美及日式RPG游戲如日中天,國(guó)內(nèi)游戲《軒轅劍》、《俠客英雄傳》等第一批劍俠RPG游戲誕生。國(guó)內(nèi)外RPG的形式由于地域文化差異而有所不同,比如歐美RPG游戲《上古卷軸》、《無(wú)冬之夜》、《巫師》;日式RPG游戲《勇者斗惡龍》、《最終幻想》,我國(guó)的RPG游戲源于古裝劍俠情愫,如《仙劍奇?zhèn)b傳》。西方RPG強(qiáng)調(diào)游戲自由,玩家通過(guò)與不同人物的對(duì)話以及執(zhí)行支線任務(wù)達(dá)到不同結(jié)局效果。而東方RPG強(qiáng)調(diào)旅途觀感體驗(yàn),玩家在游戲中與NPC有更多的互動(dòng),注重故事情節(jié)的多元化和游戲世界的氛圍。隨著全球互聯(lián)網(wǎng)的迅速發(fā)展,手機(jī)、電腦、平板電腦、游戲機(jī)等電子產(chǎn)品的快速迭代,預(yù)計(jì)到2020年全球游戲市場(chǎng)將達(dá)到最佳規(guī)模1285十億美元,與2016年274億美元的增長(zhǎng)相比,將達(dá)到27.11%的增長(zhǎng)幅度。中國(guó)、韓國(guó)和日本是三大最具規(guī)模的游戲市場(chǎng),在該地區(qū)網(wǎng)民對(duì)游戲有強(qiáng)烈需求,游戲用戶的高滲透性,17年達(dá)到63.45%,在世界上排名第一[11]。到2016年,中國(guó)游戲市場(chǎng)的實(shí)際銷售收入1655.7億元,超過(guò)美國(guó)成為世界最大的電子游戲市場(chǎng),在2017年,中國(guó)游戲產(chǎn)業(yè)的市場(chǎng)規(guī)模已超過(guò)200億人民幣。游戲產(chǎn)業(yè)已成為中國(guó)文化娛樂(lè)業(yè),對(duì)電子游戲的研究也從文化的內(nèi)涵、信息、通訊、教育學(xué)的角度,轉(zhuǎn)向經(jīng)濟(jì)和產(chǎn)業(yè)發(fā)展為主的方向[4]。與國(guó)外相比,中國(guó)的移動(dòng)端游戲也正在成為文化產(chǎn)業(yè)的一個(gè)強(qiáng)有力的分支,如今,中國(guó)經(jīng)濟(jì)正在迅速增長(zhǎng),智能手機(jī)和4G網(wǎng)絡(luò)的迅速傳播為電子游戲的發(fā)展創(chuàng)造了良好的環(huán)境。從整體游戲行業(yè)來(lái)看,中國(guó)手機(jī)游戲正處于快速發(fā)展時(shí)期,玩家數(shù)量和市場(chǎng)規(guī)模持續(xù)保持穩(wěn)步的增長(zhǎng)。根據(jù)國(guó)內(nèi)移動(dòng)渠道代表硬核聯(lián)盟發(fā)布的報(bào)告顯示,2013年中國(guó)移動(dòng)游戲異軍突起,手機(jī)游戲市場(chǎng)規(guī)模達(dá)到148.4億元。2014年,中國(guó)移動(dòng)游戲市場(chǎng)規(guī)模達(dá)到276億元,而在過(guò)去的2015年,其市場(chǎng)規(guī)模高達(dá)407億元[15]。與此同時(shí),國(guó)家正在積極支持游戲業(yè),以高效的方式創(chuàng)建與技術(shù)專業(yè)的發(fā)展相關(guān)的專業(yè),相信在不久的將來(lái),我們自己的電子游戲?qū)殡S我們的生活,并將成為我國(guó)的支柱產(chǎn)業(yè)[12]。1.3研究?jī)?nèi)容與研究框架本文經(jīng)過(guò)構(gòu)思整體游戲結(jié)構(gòu)、進(jìn)行需求分析、對(duì)各個(gè)模塊進(jìn)一步細(xì)化開(kāi)發(fā),并結(jié)合3D游戲開(kāi)發(fā)案例和網(wǎng)上學(xué)習(xí),基于Unity3D引擎設(shè)計(jì)開(kāi)發(fā)了一款RPG解謎類游戲。其主要框架和內(nèi)容如下:第一章首先介紹了游戲行業(yè)的現(xiàn)狀,然后分析了該行業(yè)在國(guó)內(nèi)外的發(fā)展?fàn)顩r,最后闡述了本研究的背景和重要性。第二章對(duì)此項(xiàng)目的開(kāi)發(fā)環(huán)境——Unity3D引擎進(jìn)行了簡(jiǎn)單介紹,首先闡述了市場(chǎng)上主流的開(kāi)發(fā)引擎Cocos2D-X,Unreal4,然后介紹了Unity3D引擎的特點(diǎn)。第三章是對(duì)游戲項(xiàng)目的設(shè)計(jì)和規(guī)劃,首先是游戲劇情的設(shè)定,其次對(duì)游戲需求進(jìn)行分析,最后進(jìn)行游戲功能模塊化的設(shè)計(jì)。第四章是對(duì)游戲的開(kāi)發(fā)實(shí)現(xiàn),總體分為七個(gè)模塊:角色行為控制模塊,道具展示使用模塊,關(guān)卡邏輯模塊,UI交互展示模塊,攝像機(jī)控制模塊,音效模塊,最后是游戲后期特效處理的Shader模塊。第五章是對(duì)游戲的測(cè)試和優(yōu)化改進(jìn)。2開(kāi)發(fā)環(huán)境2.1主流游戲引擎比較2.1.1Cocos2D-XCocos2D-X是二維多平臺(tái)便攜式游戲的開(kāi)源平臺(tái),可以用C++或Lua開(kāi)發(fā)。并且可以在iOS,Android,Blackberry和其他操作系統(tǒng)上構(gòu)建并易于使用,還支持桌面操作系統(tǒng),如Windows,Mac和Linux。因此,開(kāi)發(fā)人員編寫的源代碼很容易在桌面操作系統(tǒng)上進(jìn)行修改和更正。由于Cocos2d-x使用OpenGLES進(jìn)行圖形顯示,所以提高移動(dòng)設(shè)備的圖形處理器性能較高。2.1.2UnrealUnreal(UNREALENGINE)是世界上最著名頂級(jí)的商業(yè)游戲引擎,占比全球80%的市場(chǎng)份額,很多大型的PC游戲的引擎都使用的虛幻引擎。EpicGames公司于2009年11月發(fā)布了虛幻引擎開(kāi)發(fā)工具包UDK虛幻引擎。UDK不含源代碼,但包括UnrealEngine3引擎的獨(dú)立游戲開(kāi)發(fā)中所有的工具,有些是非常昂貴的插件開(kāi)發(fā)的中間件。由于這個(gè)原因,UDK虛幻3引擎,在游戲性能上表現(xiàn)突出[5]。UDK可供大家免費(fèi)使用,但是在商業(yè)發(fā)布之前需要花費(fèi)99美元購(gòu)買授權(quán),如果發(fā)布的作品收入超過(guò)50000美元,則還需要支付超過(guò)部分的25%作為版稅[6]。2.2Unity3D引擎特點(diǎn)2.2.1Unity3D引擎開(kāi)發(fā)框架 Unity3D工程都是由場(chǎng)景(Scene),2D或者3D的游戲?qū)ο螅℅ameObject),組件(Component)組成。完整的游戲可能有很多個(gè)場(chǎng)景組成,每個(gè)場(chǎng)景中有多個(gè)不同種類的游戲?qū)ο?,每個(gè)游戲?qū)ο笥刹煌墓δ芙M件組成。場(chǎng)景(Scene):游戲中可見(jiàn)的建筑物等整體的游戲世界,包括其中的所有游戲元素在內(nèi)。游戲?qū)ο螅℅ameOject):組成場(chǎng)景的游戲元素,如游戲中人物角色,房屋,植被等,是組成場(chǎng)景的各個(gè)部分。組件(Component):各個(gè)游戲?qū)ο蟮膶傩裕缛宋飳?duì)話框上掛的組件有RectTransform(可改變其平移,大小,錨點(diǎn)),Text(可設(shè)置對(duì)話文本的字體顏色大小等)。例如一個(gè)游戲角色屬于場(chǎng)景中的游戲?qū)ο螅瑨煸谒砩系慕M件由Transform(可控制玩家的位移,旋轉(zhuǎn)和縮放),CharacterController(人物碰撞器組件:主要用于人物控制器。),Animator(動(dòng)畫控制器組件:該組件需要引用AnimatorController,它定義了要使用的動(dòng)畫片段,并控制何時(shí)以及如何在它們之間進(jìn)行混合和轉(zhuǎn)換。)2.2.2Unity3D引擎功能腳本腳本通常被理解為包含特定描述信息的可執(zhí)行文件,并以特定格式記錄。而在Unity3D中,游戲腳本一般是指繼承了MonoBehaviour類的一系列代碼文件。這些腳本代碼通??煽芍苯颖挥螒蛞嫠R(shí)別,并依照一定的生命周期規(guī)律來(lái)運(yùn)行,從而對(duì)游戲?qū)ο螽a(chǎn)生作用。[7]圖2-1Unity3D腳本的生命周期Unity3D腳本的生命周期如下:Awake():對(duì)象被實(shí)例化,事件被喚醒的時(shí)候執(zhí)行,只執(zhí)行一次。OnEnable():?jiǎn)⒂媚_本時(shí)啟用一次事件。Start():對(duì)象的第一幀時(shí)被調(diào)用的,標(biāo)志著腳背生命周期的開(kāi)始,而且是在Update()之前。以上三個(gè)方法可用于初始化相關(guān)的操作。FixedUpdate():固定更新事件,執(zhí)行多次。每0.02s執(zhí)行一次,通常所有的物理組件相關(guān)的操作都在該事件中處理。Update():每幀執(zhí)行,可用于檢測(cè)玩家的操作輸入等,但當(dāng)游戲執(zhí)行比較復(fù)雜和繁瑣時(shí)不建議寫在此方法中,會(huì)影響游戲性能。LastUpdate():執(zhí)行次數(shù)比Update()方法多一次。OnDisable():禁用事件,在OnDestory()執(zhí)行之前執(zhí)行一次。禁用腳本組件時(shí)也會(huì)操作此方法。OnDestory():當(dāng)腳本的游戲?qū)ο蟊讳N毀時(shí),會(huì)執(zhí)行一次該事件。聲明周期事件是由系統(tǒng)定義好的,且由系統(tǒng)調(diào)用。3游戲設(shè)計(jì)3.1游戲劇情設(shè)計(jì) RPG游戲引人入勝之處在于其豐富的故事情節(jié)和人物的可操作性。玩家通過(guò)控制虛擬世界中的游戲角色進(jìn)行游戲活動(dòng),在此過(guò)程中加入趣味性關(guān)卡設(shè)計(jì),畫面感和游戲場(chǎng)景的相互配合便能使游戲的可玩性得到極大的增強(qiáng)。 故宮博物館和網(wǎng)易攜手合作開(kāi)發(fā)了一款把中國(guó)山水畫做成了解謎類的游戲《繪真妙筆千山》。游戲背景是由傳統(tǒng)的中國(guó)山水畫構(gòu)成,加入了很多中國(guó)風(fēng)元素,讓玩家在游戲中發(fā)現(xiàn)中國(guó)國(guó)粹的博大精深和藝術(shù)意義。于此同時(shí),玩家必須在潺潺流水和裊裊炊煙的畫卷中找到更多的線索,解開(kāi)謎題。[8]另一款游戲《彩虹墜入》是由NEXTStudio團(tuán)隊(duì)開(kāi)發(fā)和制作,游戲畫風(fēng)具有非常統(tǒng)一和純粹的黑色、白色、光線概念,類似一部黑色童話小說(shuō),它用一種獨(dú)特的黑白技術(shù),營(yíng)造了光感并留存在封陰影閉的空間。該游戲于2018年9月8日獲得“重識(shí)游戲——功能藝術(shù)游戲展”文化藝術(shù)傳播獎(jiǎng)。[8]類似的優(yōu)秀游戲作品不勝枚舉。 本文開(kāi)發(fā)的《第七元素》游戲是RPG解謎類游戲,受密室逃脫類游戲的啟發(fā),玩家在游戲中是一個(gè)受困于陰森神秘的中世紀(jì)教堂中的角色,通過(guò)尋找教堂中的各個(gè)聯(lián)系緊密的線索找尋通往自由的道路,最終實(shí)現(xiàn)自我救贖。 此項(xiàng)目中的游戲視覺(jué)使用了第三人稱,玩家通過(guò)移動(dòng)跳躍鼠標(biāo)操作等行為動(dòng)作觸發(fā)游戲中隱藏的線索,進(jìn)而獲取解謎關(guān)鍵的物件,開(kāi)啟新的場(chǎng)景。游戲最后以玩家解開(kāi)所有隱藏謎題,打開(kāi)最后一扇門取勝。圖3-1游戲玩法策略圖3.2游戲需求分析與設(shè)計(jì) 根據(jù)以上游戲設(shè)計(jì)的玩法和策略可將游戲分為七個(gè)模塊。其需求分析如下:3.2.1角色模塊分析 游戲角色在虛擬世界中需要通過(guò)鍵盤控制其前進(jìn)左右移動(dòng)、翻越障礙物的跳躍活動(dòng)等,角色的控制應(yīng)該靈活自如使玩家控制起來(lái)可操作性強(qiáng)。 角色的動(dòng)作由Unity3D自帶的Animator組件和動(dòng)畫狀態(tài)控制機(jī)通過(guò)代碼來(lái)實(shí)現(xiàn)。3.2.2攝像機(jī)模塊分析 游戲中的視覺(jué)應(yīng)隨著角色的移動(dòng)而變化,攝像機(jī)應(yīng)該實(shí)時(shí)檢測(cè)玩家位置、跟隨玩家的步伐,為了使游戲體驗(yàn)感良好,還應(yīng)該具備視野縮放,視野移動(dòng)等功能。3.2.3關(guān)卡邏輯模塊分析 關(guān)卡邏輯在解謎游戲中的地位舉足輕重,動(dòng)作元素和解謎元素始終要處于動(dòng)態(tài)平衡的狀態(tài),即玩家操作控制復(fù)雜的動(dòng)作時(shí),解謎元素應(yīng)該簡(jiǎn)單、可控性強(qiáng),而當(dāng)玩家操作簡(jiǎn)單時(shí),解謎元素比重就應(yīng)該有所增加。 整個(gè)解謎的過(guò)程應(yīng)該伴隨著動(dòng)作元素和解謎元素的占比不同而有所變化。否則玩家會(huì)因?yàn)殡y以操作的動(dòng)作和不知所云的謎題而煩躁不堪甚至對(duì)此游戲不再感興趣。3.2.4UI交互模塊分析 UI交互模塊應(yīng)包括信息提示和獲得物品的展示,即實(shí)時(shí)隨著觸發(fā)機(jī)關(guān)的時(shí)機(jī)而出現(xiàn)不同的消息提示機(jī)制,隨著獲取道具和消耗道具而在屏幕上出現(xiàn)或隱藏相應(yīng)的UI圖標(biāo)。 同時(shí),還應(yīng)該讓玩家有交互體驗(yàn)的樂(lè)趣,比如圖紙可以在屏幕上由玩家自由拖動(dòng),或是鼠標(biāo)的圖標(biāo)隨著點(diǎn)擊的物品而變化成相應(yīng)的UI圖標(biāo)。3.2.5道具模塊分析 道具模塊是玩家獲取解謎信息的關(guān)鍵,通過(guò)獲取其中的一部分道具進(jìn)而產(chǎn)生與下一個(gè)線索的緊密聯(lián)系。道具出現(xiàn)的時(shí)機(jī)應(yīng)該隨著玩家觸發(fā)機(jī)關(guān)的時(shí)機(jī)而變化,同時(shí),道具的使用也要具有一定的常理化,可交互性。3.2.6聲音模塊分析 音效是渲染游戲氛圍的重中之重,背景音樂(lè)的選擇一定要切合游戲的主題和類型,點(diǎn)擊UI圖標(biāo)和道具獲取時(shí)增加音效也會(huì)有事半功倍的效果。3.2.7Shader模塊分析 游戲酷炫的效果離不開(kāi)特效的協(xié)助,Shader可以做出很多不錯(cuò)的效果,因?yàn)樗遣逶阡秩竟艿览锩娴某绦?,一?lái)是性能好,是GPU執(zhí)行的,不需要CPU再去做額外的處理,二來(lái)就是可控性強(qiáng),可以控制到每個(gè)頂點(diǎn),每個(gè)像素的著色。比如把一張圖片置灰,插入一個(gè)像素Shader,每個(gè)像素在紋理著色的時(shí)候把整個(gè)RGBA求一個(gè)灰度出來(lái),這樣就變成一個(gè)灰色的圖片,這就是一個(gè)典型的像素Shader的使用。 Shader在游戲中使用屬于點(diǎn)睛之筆。3.3游戲特色1.游戲場(chǎng)景和畫面引人入勝 一款游戲在開(kāi)始玩的時(shí)候,給人印象深刻的便是游戲場(chǎng)景的精美與否,比起粗糙的場(chǎng)景和UI,玩家更青睞與玩視覺(jué)體驗(yàn)感強(qiáng)的游戲。2.關(guān)卡設(shè)計(jì)鍛煉思維環(huán)環(huán)相扣的關(guān)卡設(shè)計(jì)可以激發(fā)玩家探索和解謎的好奇心,也能引發(fā)玩家從不同的角度去思考問(wèn)題,拓寬思維??简?yàn)用戶的操作,可玩性特別高[14]。3.UI交互系統(tǒng)的樂(lè)趣性 玩家通過(guò)點(diǎn)擊不同道具的UI會(huì)使鼠標(biāo)的圖標(biāo)轉(zhuǎn)化為相應(yīng)的圖標(biāo)。增加玩家與游戲的互動(dòng)性。4游戲?qū)崿F(xiàn)4.1角色模塊的實(shí)現(xiàn) 游戲角色人物Playman能通過(guò)用按鍵輸入控制其走跑跳躍的動(dòng)作,人物游戲物體上有CharacterController組件,主要用于不使用剛體物理的第三人稱或第一人稱控制器。其行為動(dòng)作的動(dòng)畫是由組件Animator引用一個(gè)動(dòng)畫狀態(tài)控制機(jī),由于人物移動(dòng)較復(fù)雜,其行為動(dòng)作動(dòng)畫需要平滑過(guò)渡,所以在動(dòng)畫控制狀態(tài)機(jī)內(nèi)加了行為混合樹(shù),讓多個(gè)動(dòng)畫的順接能平滑、自然過(guò)渡,其中的動(dòng)畫切換用代碼寫了相應(yīng)的腳本組件掛在人物游戲物體上。圖4-1角色行為動(dòng)畫混合樹(shù)圖4-2角色狀態(tài)混合樹(shù)參數(shù)設(shè)置面板 代碼控制原理:獲取按鍵輸入的水平垂直的位移對(duì)其進(jìn)行速度移動(dòng)控制,當(dāng)速度大于某個(gè)特定值,向障礙物發(fā)射射線,射線碰撞到的物體的tag為“Obstacle”,當(dāng)射線距離大于一定值時(shí),射線射到的位置來(lái)確定游戲人物左右手的高度,從而確定人物起跳的位置。Raycast(Vector3origin,Vector3direction,outRaycastHithitInfo,floatmaxDistance);//發(fā)射射線的方法。MatchTarget(Vector3matchPosition,QuaternionmatchRotation,AvatarTargettargetBodyPart,MatchTargetWeightMaskweightMask,floatstartNormalizedTime,[Internal.DefaultValue("1")]floattargetNormalizedTime);//這個(gè)方法就是讓動(dòng)畫與目標(biāo)點(diǎn)進(jìn)行匹配,最終實(shí)現(xiàn)一些攀爬,跳躍一類的動(dòng)作。4.2攝像機(jī)控制模塊實(shí)現(xiàn) 攝像機(jī)在游戲世界中是不可或缺的元素,它實(shí)時(shí)渲染著游戲中的物體的狀態(tài),玩家通過(guò)攝像機(jī)能看到游戲世界中的一切事物。在《第七元素》游戲中,攝像機(jī)實(shí)時(shí)跟隨玩家移動(dòng)旋轉(zhuǎn),而在一個(gè)密閉的空間中,需要考慮的就是攝像機(jī)隨著人物移動(dòng)到墻的轉(zhuǎn)角或是狹小的空間中時(shí)攝像機(jī)的視野不被遮擋,這樣才能讓玩家有良好的游戲體驗(yàn)。 此項(xiàng)目中,共有兩個(gè)腳本控制攝像機(jī)的行為,一個(gè)腳本是實(shí)時(shí)跟隨玩家且保證視野不被墻體遮擋。其原理是再定義幾個(gè)相機(jī)視野位置然后通過(guò)射線檢測(cè)來(lái)進(jìn)行判斷能否看到人物進(jìn)行相應(yīng)的調(diào)整。核心代碼如下:privatevoidUpdate(){Vector3beginPos=distance+player.transform.position;Vector3endPos=distance.magnitude*Vector3.up+player.transform.position;Vector3pos1=Vector3.Lerp(beginPos,endPos,0.25f);Vector3pos2=Vector3.Lerp(beginPos,endPos,0.5f);Vector3pos3=Vector3.Lerp(beginPos,endPos,0.75f);Vector3[]posArray=newVector3[]{beginPos,pos1,pos2,pos3,endPos};Vector3targetPos=posArray[0];for(inti=0;i<5;i++){RaycastHithitInfo;if(Physics.Raycast(posArray[i],player.transform.position-posArray[i],outhitInfo)){if(hitInfo.collider.tag!="Playman"){continue;}else{targetPos=posArray[i];break;}}else{targetPos=posArray[i];break;}}QuaternionnowRotation=transform.rotation;transform.LookAt(player.transform);transform.rotation=Quaternion.Lerp(nowRotation,transform.rotation,rotateSpeed*Time.deltaTime);transform.position=Vector3.Lerp(transform.position,targetPos,moveSpeed*Time.deltaTime);}其中endPos中distance.magnitude*Vector3.up表示為只要相機(jī)的高度Y坐標(biāo)通過(guò)加上人物的坐標(biāo)就是獲得人物正上方的坐標(biāo),將此坐標(biāo)設(shè)定為最差情況(相機(jī)豎直朝下拍攝),然后通過(guò)插值運(yùn)算對(duì)中間3個(gè)變量三維坐標(biāo)賦值,可以理解為由beginPos到endPos兩點(diǎn)之間形成的直線按照一定比例賦值,最后再用四元數(shù)和向量的插值運(yùn)算控制相機(jī)旋轉(zhuǎn)和位置移動(dòng)(更加順滑過(guò)渡)。 另一個(gè)腳本控制攝像機(jī)視野的上下左右移動(dòng)和視野縮放。核心代碼如下://點(diǎn)擊鼠標(biāo)左鍵進(jìn)行視野上下左右的移動(dòng)if(Input.GetMouseButton(0)){if(axes==RotationAxes.MouseXAndY){floatrotationX=Camera.main.transform.localEulerAngles.y+Input.GetAxis("MouseX")*sensitivityX;rotationY+=Input.GetAxis("MouseY")*sensitivityY;rotationY=Mathf.Clamp(rotationY,minimumY,maximumY);Camera.main.transform.localEulerAngles=newVector3(-rotationY,rotationX,0);}elseif(axes==RotationAxes.MouseX){Camera.main.transform.Rotate(0,Input.GetAxis("MouseX")*sensitivityX,0);}else{rotationY+=Input.GetAxis("MouseY")*sensitivityY;rotationY=Mathf.Clamp(rotationY,minimumY,maximumY);Camera.main.transform.localEulerAngles=newVector3(-rotationY,Camera.main.transform.localEulerAngles.y,0);}}///按鼠標(biāo)滾輪縮放voidZoom(){//實(shí)現(xiàn)滑輪拖動(dòng)floatfov=Camera.main.fieldOfView;fov+=-Input.GetAxis("MouseScrollWheel")*sensitivity;fov=Mathf.Clamp(fov,minFov,maxFov);Camera.main.fieldOfView=fov;}4.3關(guān)卡邏輯模塊的實(shí)現(xiàn) 邏輯級(jí)塊是游戲過(guò)程中不可或缺的一部分。邏輯的實(shí)現(xiàn)主要取決于碰撞檢測(cè)功能的實(shí)現(xiàn)。它們主要分為三個(gè)部分:第一部分是碰撞檢測(cè):兩個(gè)游戲物體必須有碰撞,其中一個(gè)對(duì)象必須有一個(gè)Rigidbody組件。第二部分是觸發(fā)器觸發(fā)檢測(cè):通過(guò)Unity3D內(nèi)置的Colider并檢查IsTrigger以獲取觸發(fā)器的狀態(tài)并應(yīng)用內(nèi)部封裝的碰撞檢測(cè)的方法。第三部分是觸發(fā)條件:通過(guò)確定邏輯值是否滿足觸發(fā)條件來(lái)獲得。這三部分相互補(bǔ)充,有機(jī)結(jié)合。4.3.1碰撞器模塊檢測(cè) Collider:包含許多類型的一組組件,例如BoxCollider,MeshCollider等。這些碰撞的使用場(chǎng)景情況不同,但必須將它們添加到GameObjecet中。碰撞條件:每個(gè)對(duì)象碰撞必須具有碰撞并包含實(shí)體組件。 適用場(chǎng)景:模擬汽車被撞飛,皮球掉在地上又彈起的效果。 此項(xiàng)目中運(yùn)用場(chǎng)景:獲取圖紙時(shí),與圖紙外面的容器發(fā)生碰撞檢測(cè)。容器承載圖紙游戲物體,如果勾選了IsTrigger,圖紙會(huì)穿透容器。所以容器游戲物體添加了Rigidbody,并且要確保游戲角色碰撞到它的時(shí)候位置不發(fā)生偏移,不發(fā)生旋轉(zhuǎn),所以要注意勾選Rigidbody組件的限制條件。圖4-1圖紙容器碰撞器設(shè)置4.3.2觸發(fā)器模塊檢測(cè)觸發(fā)器:在碰撞器組件中勾選IsTrigger屬性選擇框。圖4-2觸發(fā)器設(shè)置觸發(fā)信息檢測(cè)的系統(tǒng)自帶方法:1.MonoBehaviour.OnTriggerEnter(Collidercollider)當(dāng)進(jìn)入觸發(fā)器2.MonoBehaviour.OnTriggerExit(Collidercollider)當(dāng)退出觸發(fā)器3.MonoBehaviour.OnTriggerStay(Collidercollider)當(dāng)滯留觸發(fā)器項(xiàng)目中大部分收集物品或者是關(guān)卡觸發(fā)都用到觸發(fā)檢測(cè)。通過(guò)設(shè)置游戲物體碰撞器組件的長(zhǎng)、寬、高以及位置等物理信息,從而設(shè)置物體的碰撞檢測(cè)的區(qū)域。IsTrigger勾選后可忽略對(duì)象的實(shí)際碰撞但可檢測(cè)到碰撞。即附加有該碰撞體的對(duì)象不會(huì)在物理上阻擋其他對(duì)象,但可檢測(cè)到是否與其他對(duì)象發(fā)生碰撞。[9] 如游戲中玩家與門發(fā)生碰撞時(shí),掛在門上的腳本中的OnTriggerEnter方法對(duì)進(jìn)入到門觸發(fā)器的碰撞器進(jìn)行檢測(cè),如果進(jìn)行碰撞的物體的tag為“Playman”,則UI界面的轉(zhuǎn)圈開(kāi)門機(jī)關(guān)觸發(fā)。voidOnTriggerEnter(Collidercol){if(col.gameObject.tag=="Playman"){TurnPlate.gameObject.SetActive(true);}} 碰撞器和觸發(fā)器的不同之處:觸發(fā)器是依靠碰撞器提供碰撞檢測(cè)的基礎(chǔ)上進(jìn)行的觸發(fā)檢測(cè),必須現(xiàn)有碰撞器才能有觸發(fā)器,即觸發(fā)器是碰撞器的一個(gè)屬性。區(qū)分使用的場(chǎng)景如需要檢測(cè)物體的運(yùn)動(dòng)但是不影響物體本身的位置,采用觸發(fā)檢測(cè);如果需要兩個(gè)物體的碰撞產(chǎn)生一定的實(shí)際效果,例如汽車撞墻等就需要碰撞器。4.3.3觸發(fā)條件模塊 以上兩種檢測(cè)方法在3D游戲中很常見(jiàn),條件的判斷在編程中使用得非常普遍。延伸到觸發(fā)器系統(tǒng)中,同樣需要一組觸發(fā)條件來(lái)觸發(fā)相應(yīng)的事件,當(dāng)條件滿足時(shí)觸發(fā)事件,否則不會(huì)觸發(fā)相應(yīng)事件,實(shí)現(xiàn)觸發(fā)條件時(shí)使用布爾邏輯來(lái)進(jìn)行組合便擴(kuò)展該系統(tǒng)的使用。[9]觸發(fā)條件模塊幾乎涵蓋道具觸發(fā)的各個(gè)類,舉例如下:OpenChest類:掛在寶箱游戲物體上,用于判斷玩家當(dāng)前是否滿足開(kāi)寶箱的條件,與觸發(fā)檢測(cè)聯(lián)合使用,當(dāng)玩家控制的游戲角色觸碰到寶箱時(shí),判斷玩家當(dāng)前收集到的金幣數(shù)是否為7并且之前沒(méi)有開(kāi)過(guò)寶箱,滿足以上兩個(gè)條件時(shí)執(zhí)行開(kāi)寶箱操作。voidOnTriggerEnter(Collidercol){if(col.gameObject.tag.Equals("Playman")){if(Coin.coinCount>=1&&!didOpenChest){didOpenChest=true;chestTop.transform.rotation=Quaternion.Euler(newVector3(180,90,90));chestAll.SetActive(false);cameraFollw.SetActive(false);playman.SetActive(false);if(isUsedCoinsToOpenChestAction!=null){isUsedCoinsToOpenChestAction();}UnityEngine.SceneManagement.SceneManager.LoadScene(2);}else{openChestTip.DOFade(1,0.5f);openChestTipTex.DOFade(1,0.5f);StartCoroutine(disappearTip());}}}ScrollHolder類:掛在裝圖紙的容器游戲物體上,當(dāng)玩家鼠標(biāo)左鍵點(diǎn)擊并且點(diǎn)擊到UI上相應(yīng)的斧子圖標(biāo)時(shí),執(zhí)行如下操作:從攝像機(jī)發(fā)射射線射到的物體的名字符合時(shí),出現(xiàn)線索提示,容器設(shè)置為不可見(jiàn),圖紙卷軸掉在地上。//通過(guò)射線檢測(cè)點(diǎn)擊3D物體,檢測(cè)其名字與tag是否與尋找的物體的相同if(Input.GetMouseButtonDown(0)&&ClickAxeImg.isClickImg){Rayray=Camera.main.ScreenPointToRay(Input.mousePosition);if(Physics.Raycast(ray,outhit)){obj=hit.collider.gameObject;if(.Equals("fi_vil_cath_wall_01")){openChestTipTex.text="Somethingdrops...";openChestTip.DOFade(1,0.3f);openChestTipTex.DOFade(1,0.3f);StartCoroutine(disappearTip());}}}4.4UI交互模塊的實(shí)現(xiàn) Unity3D中的UI架構(gòu)主要包括兩種,Unity引擎自帶的GUI和國(guó)外開(kāi)發(fā)者開(kāi)發(fā)的NGUI插件。而如今最受歡迎的是UGUI——Unity3D自帶的UI系統(tǒng),相較于NUUI來(lái)說(shuō)更加操作簡(jiǎn)單。圖4-3NUGI和UGUI比較 本項(xiàng)目使用的是UGUI系統(tǒng)即Unity3D內(nèi)置的UI編輯系統(tǒng)。它包括各種常用的UI控件,如按鈕(Button),文本框(Text),進(jìn)度條(Slider)等。此游戲的UI交互模塊可分為加載頁(yè)面UI模塊、開(kāi)始游戲UI模塊、游戲進(jìn)行時(shí)UI模塊。具體實(shí)現(xiàn)如下:圖4-4游戲UI模塊4.4.1加載頁(yè)面 創(chuàng)建加載頁(yè)面的背景圖,自帶生成Canvas,Canvas是所有UI的父物體。Canvas下的CanvasScaler組件可以用來(lái)控制Canvas畫布下所有元素的縮放。GraphicRaycaster射線檢測(cè)組件,其作用是用于獲取用戶選中的UGUI控件,當(dāng)禁用這個(gè)組件的時(shí)候用戶在無(wú)法獲取到控件對(duì)控件進(jìn)行操作。 再創(chuàng)建游戲加載的進(jìn)度條(Slider),通過(guò)代碼對(duì)進(jìn)度條動(dòng)畫進(jìn)行控制。首先在Start方法中對(duì)進(jìn)度條的值進(jìn)行初始化,游戲開(kāi)始時(shí)保證進(jìn)度條始終從0開(kāi)始加載,之后在Update里面對(duì)進(jìn)度條變化的值做動(dòng)畫。privatevoidUpdate(){progressSlider.value+=Time.deltaTime;if(progressSlider.value==1){coverImg.GetComponent<CanvasGroup>().DOFade(0,1);}}4.4.2開(kāi)始頁(yè)面 在開(kāi)始頁(yè)面中添加開(kāi)始游戲的按鈕控件,點(diǎn)擊按鈕時(shí)進(jìn)入游戲頁(yè)。其點(diǎn)擊事件如下:voidOnClickPlayBtn(){playBtn.GetComponent<RectTransform>().DOLocalMoveY(-343,0.1f);coverImg.DOFade(1,2f);UnityEngine.SceneManagement.SceneManager.LoadScene(1);}并在Start方法里通過(guò)按鈕點(diǎn)擊事件來(lái)響應(yīng)playBtn.onClick.AddListener(OnClickPlayBtn);4.4.3游戲進(jìn)行時(shí)UI實(shí)現(xiàn)1.提示UI: 當(dāng)觸發(fā)到場(chǎng)景中的一個(gè)道具線索時(shí),提示信息會(huì)以圖片背景加提示文本的形式出現(xiàn),文本的內(nèi)容隨著觸發(fā)的游戲物體的不同而有不同的顯示。提示UI是使用了DoTween插件——一款強(qiáng)大的動(dòng)畫編碼插件,很多的Unity3D游戲的動(dòng)畫交互中大都用的這個(gè)插件??筛鶕?jù)不同的需求寫出不同的動(dòng)畫效果,其中包括位置偏移、旋轉(zhuǎn)、縮放、UI通過(guò)改變透明度實(shí)現(xiàn)的漸隱漸現(xiàn)的效果,項(xiàng)目中場(chǎng)景切換的過(guò)渡就用到了此效果。提示UI的實(shí)現(xiàn)如下:voidStart(){openChestTip.DOFade(0,0f);openChestTipTex.DOFade(0,0f);axeImage.DOFade(0,0);}voidOnTriggerEnter(Collidercol){if(col.gameObject.tag.Equals("Playman")){openChestTipTex.text="Yougotaaxe";openChestTip.GetComponent<Image>().DOFade(1,0.3f);openChestTipTex.GetComponent<Text>().DOFade(1,0.3f);StartCoroutine(disappearTip());StartCoroutine(axeImageAnimation());}}IEnumeratordisappearTip(){yieldreturnnewWaitForSeconds(0.5f);openChestTip.GetComponent<Image>().DOFade(0,0.3f);openChestTipTex.GetComponent<Text>().DOFade(0,0.3f);}腳本開(kāi)始作用時(shí)將提示UI的透明度設(shè)置為0,防止出現(xiàn)時(shí)機(jī)過(guò)早,當(dāng)出發(fā)到某一個(gè)線索物體時(shí),將Text組件的text設(shè)置為提示內(nèi)容。并且透明度置為1。提示的信息持續(xù)時(shí)間有限,這里啟用了協(xié)程,將提示信息的持續(xù)時(shí)間設(shè)置為0.5秒,之后提示信息的圖片背景和文本內(nèi)容透明度設(shè)置為1。2.物品欄UI:物品欄UI圖標(biāo)的顯示和消失時(shí)機(jī)隨著觸發(fā)的游戲物體收集或使用時(shí)機(jī)而變化,物品的收集都是循序漸進(jìn)的,并且每個(gè)物品的UI的位置是根據(jù)前一個(gè)UI位置緊密排列,也就是說(shuō),前面物品的UI圖標(biāo)被使用并且消失后,后一個(gè)UI圖標(biāo)應(yīng)該往前挪,保證中間的位置不留空。所以物品收集和使用后都要對(duì)物品的UI進(jìn)行位置的判斷和移動(dòng)。具體的消息傳遞機(jī)制由收集到的鑰匙來(lái)舉例: GetKey是掛在鑰匙游戲物體上的腳本組件,當(dāng)玩家控制游戲角色與鑰匙發(fā)生碰撞時(shí)收集到鑰匙,鑰匙物體的激活狀態(tài)為false,并且出現(xiàn)提示UI,"Igotakey."s具體實(shí)現(xiàn)如下:[SerializeField]privateTexttipTex;[SerializeField]privateImagetip;publicstaticboolisGetKey;publicstaticActionisUsedScrollAction;voidStart(){tip.DOFade(0,0f);tipTex.DOFade(0,0f);}voidOnTriggerEnter(Collidercol){if(col.gameObject.tag=="Playman"){tipTex.text="Igotakey.";if(isUsedScrollAction!=null){isUsedScrollAction();}tip.DOFade(1,0.3f);tipTex.DOFade(1,0.3f);isGetKey=true;StartCoroutine(delay());}}IEnumeratordelay(){yieldreturnnewWaitForSeconds(1f);tip.DOFade(0,0.3f);tipTex.DOFade(0,0.3f);gameObject.SetActive(false);} 當(dāng)管理UI腳本DontDestroyTool類中Update方法中獲取到收集到鑰匙的布爾條件為ture時(shí),再判斷前面收集到的物品是否被使用,如果沒(méi)有使用,則收集到的鑰匙排在其后面,否則往前挪一個(gè)位置。物體UI圖標(biāo)收集到時(shí)使用了DoTween動(dòng)畫,提示玩家收集到了此物品。具體實(shí)現(xiàn)如下:if(GetKey.isGetKey){if(icon2Image.IsActive()){icon2RectTram.anchoredPosition=newVector2(icon2RectTram.anchoredPosition.x-150,icon2RectTram.anchoredPosition.y);StartCoroutine(imageToIconAnimation(keyRectTram,icon2RectTram,150,keyImage));}else{//key前面沒(méi)有icon2則是第一個(gè)StartCoroutine(noPreviousRec(keyRectTram,0,keyImage));}GetKey.isGetKey=false;}物品UI的動(dòng)畫用的是同一個(gè)方法,將物品UI的錨點(diǎn)設(shè)置在屏幕中間,放大和移動(dòng)的動(dòng)畫同時(shí)播放,循環(huán)3次。IEnumeratorimageToIconAnimation(RectTransformrect,RectTransformpreviousRec,floatdistance,Imageimg){yieldreturnnewWaitForSeconds(0.03f);iconObj.SetActive(false);rect.anchoredPosition=Vector2.zero;rect.anchorMax=newVector2(0.5f,0.5f);rect.anchorMin=newVector2(0.5f,0.5f);Sequenceseq=DOTween.Sequence();seq.Append(rect.DOScale(Vector3.one*4,0.5f).SetEase(Ease.InOutCirc)).Append(rect.DOLocalMove(newVector3(previousRec.anchoredPosition.x+distance,previousRec.anchoredPosition.y,0),0.2f)).Append(rect.DOScale(Vector3.one*2f,0.2f).SetEase(Ease.InOutCirc)).Append(rect.DOScale(Vector3.one,0.2f).SetEase(Ease.InOutCirc).SetLoops(3));img.gameObject.SetActive(true);}3.觸發(fā)關(guān)卡UI 每次收集到的物品會(huì)轉(zhuǎn)變?yōu)閁I放置在屏幕左下角,鼠標(biāo)點(diǎn)擊不同的UI時(shí)圖標(biāo)會(huì)發(fā)生相應(yīng)的變化。再次點(diǎn)擊,鼠標(biāo)會(huì)恢復(fù)成原本圖標(biāo)。 第二道門的開(kāi)門觸發(fā)是游戲關(guān)卡的核心,這里是游戲進(jìn)度的分水嶺。圖4-5放入三枚徽章的前后對(duì)比收集到的三枚徽章點(diǎn)擊相應(yīng)圖標(biāo)后放到對(duì)應(yīng)的位置,三個(gè)位置是按鈕控件,當(dāng)對(duì)應(yīng)的布爾條件滿足時(shí),三個(gè)位置未激活的圖標(biāo)設(shè)置為激活狀態(tài),具體實(shí)現(xiàn)代碼如下:voidClickPointerLeft(){if(ClickIcon1Img.isClickIcon1Img){ClickKeyImage.isClickImg=false;blueImg.gameObject.SetActive(true);Cursor.SetCursor(normalMouseTex,Vector2.zero,CursorMode.Auto);isPlaceIcon1=true;if(isUsedIcon1!=null){isUsedIcon1();}}}voidClickPointerRight(){if(ClickIcon2Img.isClickIcon2Img){ClickKeyImage.isClickImg=false;purpleImg.gameObject.SetActive(true);Cursor.SetCursor(normalMouseTex,Vector2.zero,CursorMode.Auto);isPlaceIcon2=true;if(isUsedIcon2!=null){isUsedIcon2();}}}voidClickPointerUp(){if(ClickIcon3Img.isClickIcon3Img){ClickKeyImage.isClickImg=false;yellowImg.gameObject.SetActive(true);Cursor.SetCursor(normalMouseTex,Vector2.zero,CursorMode.Auto);isPlaceIcon3=true;if(isUsedIcon3!=null){isUsedIcon3();}}}圖4-6第一、二次旋轉(zhuǎn)到正確位置對(duì)比并點(diǎn)擊中間的按鈕發(fā)生相應(yīng)的旋轉(zhuǎn)角度,記錄點(diǎn)擊次數(shù),每次旋轉(zhuǎn)的角度通過(guò)旋轉(zhuǎn)次數(shù)*固定角度得來(lái)。具體代碼實(shí)現(xiàn)如下:voidClickTurnCenter(){if(shouldTurn()){clickTurnCount++;centerBtn.transform.rotation=Quaternion.Euler(newVector3(0,0,-10*clickTurnCount));blueImg.transform.rotation=Quaternion.Euler(newVector3(0,0,5*clickTurnCount));purpleImg.transform.rotation=Quaternion.Euler(newVector3(0,0,5*clickTurnCount));yellowImg.transform.rotation=Quaternion.Euler(newVector3(0,0,5*clickTurnCount));}} 當(dāng)中間按鈕旋轉(zhuǎn)的z軸為-0.5或者0.5時(shí),第一次旋轉(zhuǎn)到正確的位置,三個(gè)不規(guī)則三個(gè)圖形的父物體上添加CanvasGroup組件,可對(duì)其子物體統(tǒng)一做透明度動(dòng)畫。 當(dāng)?shù)谝淮握_旋轉(zhuǎn)發(fā)生并且中間按鈕旋轉(zhuǎn)的z軸為1或者-1時(shí),第二次旋轉(zhuǎn)到正確的位置,中間橙色光圈的大小從0變到1,透明度也從0變到1。通過(guò)協(xié)程停頓2.5秒后旋轉(zhuǎn)的UI透明度變?yōu)?后變?yōu)槲醇せ顮顟B(tài),發(fā)送消息給門的腳本組件,之后門打開(kāi),門口的燈由紅色變?yōu)榫G色。voidTurnSuccessFirst(){if(centerBtn.transform.rotation.z==-0.5f||centerBtn.transform.rotation.z==0.5f){IrregularShapes.gameObject.SetActive(true);IrregularShapes.alpha+=Time.deltaTime;blueImg1.gameObject.SetActive(true);purpleImg1.gameObject.SetActive(true);yellowImg1.gameObject.SetActive(true);blueImg1.transform.rotation=Quaternion.Euler(newVector3(0,0,60));purpleImg1.transform.rotation=Quaternion.Euler(newVector3(0,0,60));yellowImg1.transform.rotation=Quaternion.Euler(newVector3(0,0,60));turnSuccessFirst=true;}TurnSuccessSecond();}IEnumeratorTurnSuccessSecond(){if(turnSuccessFirst){if(centerBtn.transform.rotation.z==1||centerBtn.transform.rotation.z==-1f){blueImg1.transform.rotation=Quaternion.Euler(newVector3(0,0,-60));purpleImg1.transform.rotation=Quaternion.Euler(newVector3(0,0,-60));yellowImg1.transform.rotation=Quaternion.Euler(newVector3(0,0,-60));Sequencesequence=DOTween.Sequence();sequence.Append(lightImg.GetComponent<RectTransform>().DOScale(Vector3.one*0.9f,2)).Insert(0,lightImg.DOFade(1,2));yieldreturnnewWaitForSeconds(2.5f);TurnTable.DOFade(0,0.5f).OnComplete(()=>{TurnTable.gameObject.SetActive(false);if(isSuccessRiddleAction!=null){isSuccessRiddleAction();}});}}}4.5道具模塊的實(shí)現(xiàn) 金幣:玩家控制游戲角色跑、跳躍等動(dòng)作行為收集7枚金幣,每個(gè)金幣游戲物體上都掛有Coin腳本組件和碰撞器,與游戲角色發(fā)生碰撞檢測(cè)時(shí)收集金幣,金幣數(shù)加一。 寶箱:掛有OpenChest腳本組件和碰撞器。當(dāng)游戲角色與寶箱碰撞時(shí),判斷收集到的金幣數(shù)是否為7并且是第一次開(kāi)箱,兩個(gè)條件滿足時(shí),跳轉(zhuǎn)開(kāi)寶箱場(chǎng)景,主游戲頁(yè)的玩家和攝像機(jī)激活狀態(tài)為false,收集到一枚徽章。如果兩個(gè)條件都不滿足則出現(xiàn)提示文本信息。 斧子:只有在開(kāi)寶箱事件觸發(fā)后,斧子游戲物體才會(huì)出現(xiàn)在游戲場(chǎng)景中。斧子游戲物體上掛有GetAxe腳本組件和碰撞器組件,當(dāng)游戲角色與斧子發(fā)生碰撞檢測(cè)時(shí)收集到斧子。并且斧子圖標(biāo)UI出現(xiàn)在屏幕上。 圖紙卷軸的容器:掛有ScrollHolder腳本組件和碰撞器組件,當(dāng)游戲角色與其發(fā)生碰撞時(shí),出現(xiàn)提示線索信息,玩家需要點(diǎn)擊屏幕上的斧子圖標(biāo),隨即鼠標(biāo)圖標(biāo)變成相應(yīng)的游戲物體的UI,然后點(diǎn)擊圖紙卷軸的容器,其觸發(fā)條件必須滿足點(diǎn)擊了斧子UI和鼠標(biāo)點(diǎn)擊時(shí)的射線檢測(cè)到的物體名字是容器的名字。之后容器消失,卷軸落下。 圖紙卷軸:當(dāng)鼠標(biāo)點(diǎn)擊卷軸時(shí)出現(xiàn)提示線索文本,只有按住鼠標(biāo)左鍵把圖紙拖動(dòng)到藍(lán)色光線照耀的區(qū)域才能觸發(fā)線索。此處將光線照耀的區(qū)域加了空物體并掛上碰撞器,卷軸碰撞器與其碰撞進(jìn)入LookPaper場(chǎng)景,收獲到一枚徽章和一個(gè)圖紙卷軸。 六個(gè)瓶子:玩家控制游戲角色按照?qǐng)D紙卷軸上的順序把瓶子打破,觸發(fā)線索機(jī)關(guān),羅馬數(shù)字7的位置上建筑物石柱向下位移,鑰匙出現(xiàn)。 鑰匙:掛有GetKey腳本組件和碰撞器組件,當(dāng)游戲角色與鑰匙游戲物體發(fā)生碰撞時(shí)收集到鑰匙,并且屏幕左下角出現(xiàn)相應(yīng)的鑰匙物品的UI。 第一扇門:開(kāi)門的條件必須滿足兩者:玩家點(diǎn)擊鑰匙UI鼠標(biāo)圖標(biāo)變成鑰匙UI圖標(biāo),鼠標(biāo)左鍵點(diǎn)擊時(shí)發(fā)射射線檢測(cè)到的物體名字是門,此時(shí)門打開(kāi),門口的燈光顏色從藍(lán)色變成綠色。 拖把:進(jìn)門左手邊的墻角有一個(gè)拖把,當(dāng)玩家與其發(fā)生觸發(fā)檢測(cè)時(shí)收集到該物體。 書:進(jìn)門右手邊屋子的桌子上放置這一本書,與其發(fā)生觸發(fā)檢測(cè)會(huì)出現(xiàn)提示線索信息,鼠標(biāo)左鍵點(diǎn)擊并且判斷是否開(kāi)了門才能獲取該物體。 徽章三:進(jìn)門一直往前的屋子里會(huì)發(fā)現(xiàn)一塊壁畫與其他三塊不一樣,上面沾滿了污漬,用收集到的拖把進(jìn)行清潔:點(diǎn)擊拖把UI圖標(biāo),再點(diǎn)擊壁畫,此時(shí)進(jìn)入清潔壁畫的場(chǎng)景,主場(chǎng)景的游戲人物和攝像機(jī)暫時(shí)未激活。每點(diǎn)擊一次壁畫,覆蓋在上面的污漬材質(zhì)圖片的透明度就降低,直到透明度為0時(shí),游戲人物和攝像機(jī)設(shè)置為激活狀態(tài),此時(shí)點(diǎn)擊徽章三收集。此處代碼實(shí)現(xiàn)如下:voidUpdate(){if(Input.GetMouseButtonDown(0)){Debug.Log("pressmouse.");ripple.Emit(Vector2.one);clickMouseNum++;deduceStains(clickMouseNum);}if(material.color.a<=0){isClearedStains=true;transform.gameObject.SetActive(false);Cursor.SetCursor(normalMouseTex,Vector2.zero,CursorMode.Auto);if(isUsedBroom!=null){isUsedBroom();}}}voiddeduceStains(floatcount){floatalph=1-0.3f*count;material.color=newColor(0,0,0,alph);}當(dāng)污漬透明度<=0時(shí),回調(diào)函數(shù)執(zhí)行如下:voidhideBroomImage(){broomImage.gameObject.SetActive(false);stainsObj.SetActive(false);icon3Obj.SetActive(false);cameraFollw.SetActive(true);playman.SetActive(true);bookRectTram.anchoredPosition=newVector3(bookRectTram.anchoredPosition.x–150,bookRectTram.anchoredPosition.y,0);}第二道門:將收集到的三枚徽章放入轉(zhuǎn)盤的相應(yīng)位置,點(diǎn)擊中間旋轉(zhuǎn)觸發(fā)開(kāi)門事件,此時(shí)門外的紅燈變?yōu)榫G燈。 書柜上的書:滿足三個(gè)條件才能觸發(fā)——玩家收集到了前面房間桌子上的書、碰撞到了書柜、第一次碰撞到書柜。如果滿足條件則進(jìn)入TriggerBook場(chǎng)景,此時(shí)書本的UI圖標(biāo)透明度變?yōu)?,書本游戲物體從UI的位置發(fā)生位移、放大、旋轉(zhuǎn)三個(gè)動(dòng)畫同時(shí)作用,書本最后移動(dòng)到缺失的位置,過(guò)了兩秒之后,一排的書整體移動(dòng),開(kāi)門機(jī)關(guān)出現(xiàn)。具體動(dòng)畫實(shí)現(xiàn)代碼如下:IEnumeratorbookIsShow(){bookImgShouldHide=true;yieldreturnnewWaitForSeconds(2);TransformbookTran=book.GetComponent<Transform>();Sequencesequence=DOTween.Sequence();sequence.Append(bookTran.DOScale(Vector3.one,1)).Insert(0,bookTran.DOLocalRotate(newVector3(0,-90,0),0.5f,RotateMode.Fast)).Insert(0,bookTran.DOLocalMove(newVector3(-0.03f,-0.008f,0.258f),2f).SetEase(Ease.OutQuint));yieldreturnnewWaitForSeconds(2);book.transform.parent.GetComponent<Transform>().DOLocalMoveZ(42f,2).SetEase(Ease.InCubic);bookIsMove=true;} 開(kāi)門機(jī)關(guān):鼠標(biāo)左鍵點(diǎn)擊并且書移動(dòng)的條件滿足后,開(kāi)門機(jī)關(guān)發(fā)生旋轉(zhuǎn),開(kāi)門的條件滿足。 第三道門:玩家需要控制游戲角色與門發(fā)生觸發(fā)檢測(cè)并且開(kāi)門機(jī)關(guān)觸發(fā)后才可以開(kāi)門。 墨水瓶:游戲人物與墨水瓶發(fā)生觸發(fā)檢測(cè),收集到4個(gè)墨水瓶。 箱子:游戲人物與其碰撞并且滿足收集到的墨水瓶數(shù)量>=4,可觸發(fā)機(jī)關(guān),箱子的圖標(biāo)變亮,并且獲得火柴道具。 走道上的油燈:玩家需要點(diǎn)擊屏幕左下角的火柴UI圖標(biāo),當(dāng)鼠標(biāo)圖標(biāo)變成火柴時(shí),點(diǎn)擊油燈游戲物體,此時(shí)點(diǎn)燃油燈,開(kāi)第四道門的條件滿足。 第四道門:游戲人物與門發(fā)生觸發(fā)檢測(cè),并且點(diǎn)燃油燈方可開(kāi)門。 書本:點(diǎn)擊放在桌子上的書本,進(jìn)入ClickBook場(chǎng)景,記住上面的數(shù)字。 圖紙:收集到羽毛筆后方可觸發(fā),之后進(jìn)入MapClue場(chǎng)景。 第五道門:根據(jù)兩個(gè)線索找出開(kāi)門密碼,游戲成功。4.6聲音模塊 Unity3D播放音樂(lè)方便快捷,使用其自帶的AudioSource組件,把需要播放的音效放到組件的AudioClip里,根據(jù)需求調(diào)整組件的參數(shù)設(shè)置。圖4-7AudioSource組件及其參數(shù)設(shè)置 本項(xiàng)目的音效分為UI交互音效、道具音效和背景音樂(lè)。UI交互音效的播放時(shí)機(jī)是在點(diǎn)擊按鈕時(shí),進(jìn)入游戲的打字機(jī)動(dòng)畫效果和音效的播放使用了DoTween動(dòng)畫里的text.DoText,當(dāng)文本動(dòng)畫播放完之后使用回調(diào)函數(shù),讓音效停下。具體實(shí)現(xiàn)代碼如下:text.DOText("Icametothemedievalchurchalone."+"\n"+"\n"+"Suddenlyclosedthedoor..."+"\n"+"\n"+"Ihavetofindthedoortogoout...",10f).OnComplete(()=>{TextAud.Stop();});按任意鍵開(kāi)始游戲時(shí),音效停止播放。privatevoidUpdate(){if(Input.anyKey){TextAud.Stop();coverImg.DOFade(0,0.5f);}} 背景音樂(lè)放在游戲角色的AudioSource組件里,隨著角色移動(dòng)播放,這樣做的好處就是不管角色走到哪里,音樂(lè)的聲音大小都是一致的,不會(huì)忽遠(yuǎn)忽近。 獲取道具時(shí)播放的音效隨著不同道具被觸發(fā)而播放不同的聲音,有助于增加游戲的真實(shí)性,讓玩家身臨其境。4.7Shader模塊 Shaderlanguage,稱為著色語(yǔ)言,是一種高級(jí)語(yǔ)言,但必須基于圖形硬件,用來(lái)對(duì)三維圖形進(jìn)行光影,空間位置變換,顏色處理等操作,最終改變物體的形狀、大小、位置以及實(shí)現(xiàn)特效,在實(shí)時(shí)變化的游戲、電影中模擬真實(shí)、非真實(shí)的畫面效果。 本項(xiàng)目共有兩個(gè)地方用到了Shader,一處是開(kāi)始游戲頁(yè)面的Play按鈕,具體的Shader代碼如下:Shader"UI/UpdateBrightness"{Properties{_Color("MainColor",Color)=(1,1,1,1)_MainTex("Base(RGB)",2D)="white"{}_Brightness("Brightness",Range(-1,1))=0}SubShader{Tags{"Queue"="Transparent"}Pass{CullOffLightingOffZWriteOffBlendSrcAlphaOneMinusSrcAlphaCGPROGRAM#pragmavertexvert#pragmafragmentfrag#include"UnityCG.cginc"float4_Color;sampler2D_MainTex;float_Brightness;structv2f{float4pos:SV_POSITION;float2uv:TEXCOORD0;};float4_MainTex_ST;v2fvert(appdata_basev){v2fo;pos=UnityObjectToClipPos(v.vertex);uv=TRANSFORM_TEX(v.texcoord,_MainTex);returno;}floatBrightenChannel(floatc,floatbrightness){if(brightness<0){returnc+c*brightness;}else{returnc+c*(1/(1-brightness)-1);}}half4frag(v2fi):COLOR{half4texcol=tex2D(_MainTex,i.uv);half4finalColor=texcol;finalColor*=_Color;finalColor.r=BrightenChannel(finalColor.r,_Brightness);finalColor.g=BrightenChannel(finalColor.g,_Brightness);finalColor.b=BrightenChannel(finalColor.b,_Brightness);returnfinalColor;}ENDCG}}Fallback"VertexLit"}在Properties塊里定義參數(shù),可以在可視面板上調(diào)整參數(shù)可視化看最終畫面中的效果,比如調(diào)整主要顏色“_Color”,更換圖片“_MainTex”,修改亮度值“_Brightness”。然后在LetMeGoBrightenEffect腳本組件中對(duì)亮度值進(jìn)行DoTween補(bǔ)間動(dòng)畫://對(duì)currentBrightness做DoTween動(dòng)畫voidstartTweenBrightValue(){Sequencese=DOTween.Sequence();se.AppendInterval(preTime);for(inti=0;i<animationCount;i++){se.Append(DOTween.To(()=>currentBrightness,x=>currentBrightness=x,brightnessTo,0.4f)).SetEase(Ease.

溫馨提示

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

評(píng)論

0/150

提交評(píng)論