




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
摘要隨著互聯網時代的進步,游戲行業的推動,影響著人們的生活方式。在學習工作之余,輕松愉快的游戲娛樂成為了人們休閑娛樂的生活方式之一。而游戲與虛擬仿真的結合也開始受到越來越多的人們關注。通過虛擬仿真類游戲,讓游戲玩家體驗到更加豐富多彩的生活,了解到更多不一樣的知識,因此虛擬仿真類游戲越來越受歡迎。Unity3D是目前最流行的游戲開發引擎之一,以其低成本與高效率被多數游戲開發者所使用。本論文探究基于Unity3D的海關仿真游戲開發與實現的過程,首先確定游戲設計方向,其次列舉了游戲的實現內容。其中包括了道具的使用、入境人員的信息、以及人工智能對話,開發過程中所應用到的框架方法,如使用管理UI的PureMVC框架、管理狀態的有限狀態機,以及仿真游戲所需的渲染方法,比如使用了LightWightRenderPipeline工具。讓想要了解海關檢查員工作的游戲玩家,能夠更加真實地體驗海關檢查員的具體工作流程。最后,對游戲的功能進行打包運行。關鍵詞:Unity3D;虛擬仿真類游戲;海關模擬AbstractWiththeprogressoftheInterneteraandthepromotionofthegameindustry,people'slifestyleisaffected.Afterstudyingandworking,relaxedandhappygameentertainmenthasbecomeoneofthelifestyleofpeople'sleisureandentertainment.Andthecombinationofgameandvirtualsimulationhasattractedmoreandmoreattention.Throughvirtualsimulationgames,thegameplayerscanexperiencemorecolorfullifeandlearnmoredifferentknowledge,sovirtualsimulationgamesaremoreandmorepopular.Unity3disoneofthemostpopulargamedevelopmentengines,whichisusedbymostgamedeveloperswithitslowcostandhighefficiency.ThispaperexploresthedevelopmentandimplementationprocessofCustomssimulationgamebasedonunity3d.Firstly,thedesigndirectionofthegameisdetermined,andthentheimplementationcontentofthegameislisted.Itincludestheuseofprops,informationofentrypersonnel,andartificialintelligencedialogue.Theframeworkmethodsappliedinthedevelopmentprocess,suchasthepureMVCframeworkusingthemanagementUI,thefinitestatemachinemanagingthestate,andtherenderingmethodsneededforthesimulationgame,suchastheuseofthelightwiderenderpipelinetool.Letthegameplayerswhowanttoknowabouttheworkofcustomsinspectorsexperiencethespecificworkprocessofcustomsinspectorsmoretruly.Finally,packandrunthefunctionsofthegame.Keywords:Unity3D;Virtualsimulationgames;Customssimulation廣東東軟學院本科生畢業設計(論文)目錄第一章 緒論 11.1 選題的背景和意義 11.2 國內外研究現狀 11.3 論文組織結構 2第二章 開發工具介紹 32.1 Unity3D引擎 32.1.1 Unity3D軟件介紹 32.1.2 物理引擎 32.1.3 輕量級渲染管道 32.2 C#開發語言 32.3 VisualStudio2019 4第三章 游戲總體設計 53.1 游戲背景介紹 53.2 游戲玩法 53.2.1 操作機制 53.3 游戲主要過程 53.4 游戲得分機制 53.4.1 績效得分 53.4.2 服務得分 53.4.3 安全得分 63.5 系統整體設計 63.6 游戲界面設計 7第四章 游戲實現 84.1 游戲場景 84.1.1 場景設計 84.1.2 場景制作 84.1.3 燈光 94.2 特殊道具 104.2.1 電腦 104.2.2 筆記本電腦 134.2.3 紅色蓋章和綠色蓋章 154.2.4 金屬探測儀 174.2.5 危險警報器 184.2.6 通行證和護照 194.3 入境人員 234.3.1 創建入境人員信息 234.3.2 入境人員攜帶物品 244.3.3 入境人員動作 254.3.4 入境人員交互 274.3.5 入境人員路徑 304.3.6 入境人員狀態 314.3.7 創建入境人員 334.4 玩家控制對象 354.4.1 創建對象 354.4.2 控制鏡頭 354.4.3 控制道具 374.4.4 控制對象狀態 41第五章 游戲打包與測試 485.1 游戲打包 485.2 游戲運行 48第六章 總結 51參考文獻 52致謝 53緒論選題的背景和意義隨著社會進步的發展,地球村更加進一步的形成。現如今,人們之間的生活聯系更加密集,國與國之間的聯系也更加密集,通過人才運輸,理想的各自不同,跨地區,跨國家之間的交流更加頻繁密集。現階段我國綜合國力的上升,加入WTO帶來了外匯資本的涌入,改革開放進程推進,“一帶一路”戰略吸引了大量的外來流動人口訪華交流合作,為了有效阻斷國家與國家之間人員頻繁來往成為犯罪以及逃亡,加劇流行性傳染疾病,2020年年初,一場“新型冠狀病毒”席卷全球,在我國基本控制疫情的同時,國外疫情卻不減反增的趨勢,國內入境病例隨著提高,從而導致了國家與人民群眾陷入恐慌,因此需要監管進出境的人員是否符合相應安全條件,并因此建立了海關站。全國海關目前共有46個直屬單位(廣東分署,天津、上海特派辦、41個直屬海關,2所海關院校),600個隸屬海關和辦事處,通關監管點近4000個。中國海關現有關員(含海關緝私警察)約5萬人。隨著現在科技進步,互聯網的普及,電子游戲形式總類越來越豐富,其中虛擬仿真類游戲也開始逐漸受到游戲玩家青睞,3D類型游戲已經在生活中各類電子多平臺得到了普及,對比與傳統2D類型游戲,3D類型游戲能夠帶給游戲玩家更加完善的體驗,而結合3D虛擬仿真制作出的游戲能使游戲體驗回饋更加真實。因此,將使用Unity3D制作一款海關虛擬仿真類游戲。現實生活中普通群眾很難接觸到海關檢查工作人員每日工作流程,以及面臨到的危險、應具備相應的專業知識。通過虛擬仿真效果制作一款海關模擬游戲基于游戲玩家體驗,使普通群眾了解可靠的仿真理論系統,從而達到科普宣傳海關站的相應知識,更加完善地了解基礎知識,可能面臨到的危險。國內外研究現狀隨著互聯網技術和終端硬件的發展與完善、人們生活水平的提高,游戲市場越來越受到重視,游戲產業高速發展。2019年全球數字游戲總營收高達1201億美元,而國內游戲產業實際銷售收入達2308.8億元,同比增長7.7%(2018年同比增長5.3%);其中移動游戲實際銷售收入達到1581.1億元,同比增長率18.0%。因此可看出國內游戲行業增長趨勢猛增,單機領域市場占比卻僅為0.3%,虛擬仿真類單機游戲寥寥無幾。因此,開發一款虛擬仿真類海關游戲即可搶占虛擬仿真游戲市場份額又可豐富游戲種類。論文組織結構論文從總體設計到最終的完成,結合應用了游戲開發相關的知識和技術,成功實現了一個基于Unity3D的海關仿真游戲開發與實現,其中具體介紹了游戲框架設計以及游戲制作的關鍵步驟,也包括游戲的系統功能設計和一系列代碼的編寫。論文分為六章,各章節安排如下:第一部分:緒論,主要介紹了選題的背景以及意義、相關課題國內外研究現狀;第二部分:介紹了本文制作游戲使用的各類開發工具和Unity3D的大致介紹;第三部分:詳細介紹游戲的各個模塊的總體設計,游戲背景,清晰明確游戲內部關系,界面設計;第四部分:具體實現過程框架使用和方法;第五部分:對游戲進行打包并測試;第六部分:結論以及游戲的缺陷和今后的改進方法。開發工具介紹Unity3D引擎Unity3D軟件介紹Unity3D是一款由UnityTechnologies公司所開發的跨平臺游戲開發軟件,作為一款專業的游戲開發引擎,它有資深技術團隊的支持、友善的圖形化界面、豐富的拓展插件和多平臺的導出配置,是一款整合多功能于一身的游戲開發引擎。Unity3D適合新手學習,上手難度較小,因此降低了游戲開發門檻,給熱愛游戲開發的開發者提供了一個平臺。使用Unity開發游戲的無需底層復雜技術,就可以使用它開發設計出高質量的游戲,并且Unity3D開發的游戲可支持Windows、Mac、iPhone和Android等多種平臺發布[12]。因此,是大多數游戲公司和游戲開發者最佳選擇。物理引擎Unity內置了NVIDIA的PhysX物理引擎,PhysX是目前使用最為廣泛的物理引擎,被很多游戲大作所采用,開發者可以通過物理引擎高效、逼真地模擬剛體碰撞、車輛駕駛、布料、重力等物理效果,使游戲畫面更加真實而生動。并且還可以在Windows、Mac、Linux和Android等多種平臺上運行輕量級渲染管道LightweightRenderPipeline(LWRP),輕量級渲染管線,是一個Unity預制的ScriptableRenderPipeline(SRP)。LWRP可以為移動平臺提供圖形渲染功能,但也可以在高端主機和PC上使用LWRP。LWRP使用簡化的、基于物理的光照和材質。使用LWRP,可以在幾個平臺上得到優化了的實時渲染性能。C#開發語言C#是微軟公司發布的一種運行于.NETFramework和.NetCore上的高級程序設計語言,不僅面向對象,類型安全。C#是一種面向對象的語言。不僅如此,C#還進一步支持面向組件的編程。當代軟件設計越來越依賴采用自描述的獨立功能形式的軟件組件。此類組件的關鍵是它們提供包含屬性、方法和事件的編程模型。它們包含提供組件相關聲明性信息的屬性。它們合并了自己的文檔。C#提供了語言構造來直接支持這些概念,讓C#成為一種非常自然的語言,可用于創建和使用軟件組件,因此成為了Unity3D開發的主流語言。VisualStudio2019VisualStudio是美國微軟公司的開發工具包系列產品。它是一個基本完整的開發工具集,包括了整個軟件生命周期中所需要的大部分工具,提供強大的調試和性能分析工具,快捷地查找和修復錯誤的方式,強大的庫調用和云集成,為Unity3D游戲開發提高了效率。游戲總體設計游戲背景介紹《海關檢查員》是一款由玩家扮演海關檢查員,主要的工作在于檢查每一位海關入境者的證件、是否存在走私或者違禁物品,以及判斷入境者的身份是否符合入境的條件。體驗一個檢查員日常工作一些相關的操作,體驗這份工作背后的艱辛以及壓力,以及是如何成為一名稱職的檢查員,以及背后遇到的世間辛酸、恐嚇、要挾。當這些降臨在玩家面前,玩家該如何選擇。是一款玩家內心的問卷答題通關游戲。游戲玩法操作機制《海關檢查員》是第一視角控制游戲,以鍵盤WSAD控制人物視角上下左右移動,鼠標左鍵點擊為拾取、與NPC進行交互以及觸發事件,鼠標右鍵點擊為放下,ESC鍵調出/關閉菜單。游戲主要過程進入游戲,點擊電腦熟記當前的日期,開始檢察入境人員,詢問入境人員具體情況,審閱證件是否準確,金屬探測儀檢驗是否攜帶危險器具,判斷是否給予入境,點擊下一位,選擇檢驗下一位入境人員,系統對游戲玩家進行評分。游戲得分機制績效得分以游戲玩家判斷的準確性為依據,若判斷通行、拒絕準確率越高,績效得分越高。服務得分初始入境者隨機設定情緒,隨著玩家與入境者互動,改變情緒,服務得分隨情緒變化得分。安全得分錯誤通行危險入境者,城市安全指數降低。系統整體設計游戲的主要玩法是玩家與NPC的交互,NPC的AI十分重要,直接影響游戲體驗。所以使用有限狀態機來控制NPC的行為狀態。使用有限狀態機的方式,把NPC的AI行為劃分為多個不同的狀態,通過不同邏輯塊的執行形成NPC的完整行為,NPC的AI邏輯更加的清晰,便于修改與完善,也可以為后期拓展提供途徑。圖3-1NPC的AI邏輯圖游戲界面設計游戲界面是開始進入游戲主場景之后,主攝像機看到的內容,其中包括了海關站界面、檢查入境人員界面、證件界面、金屬探測儀界面,以及電腦操作界面。表3-1游戲界面海關站界面辦工操作臺左側排隊等候區右側電腦信息檢查入境人員界面入境人員通行蓋章、拒絕蓋章金屬探測儀證件界面通行證(蓋章區域、證件照、姓名、性別、日期、國籍、通行編號)護照(姓名、通行編號、入境理由、日期)金屬探測儀界面手持金屬探測儀顯示入境人員攜帶金屬物品電腦操作界面入境人員信息表(證件照、姓名、性別、年齡、國籍、職業、人家原因、)信箱(每日信息)游戲實現游戲場景場景設計系統場景包括(Scene1、StartScene),StartScene為開始游戲場景,Scene1為主場景。表4-1系統場景如下圖StartScene開始游戲按鈕可持續播放的背景動畫Scene1接待以及檢測入境人員的海關站辦公桌,以及可操作電腦提供檢查入境人員工具場景制作使用Unity自帶的地形系統搭建自己想要的海關站,在Hierarchy面板中創建一個片面Plane,在Inspector面板中Transform修改平Plane的大小以及位置,原有的網格渲染器MeshRenderer將靜態光照貼圖LightmapStatic勾選,并加入碰撞體BoxCollider。搭建好一塊平面地形。參數如圖:圖4-1平面地形參數接著在Hierarchy面板中創建三個平面Cube,將海關站搭建在平面地形上,在Inspector面板中Transform修改平Cube的大小以及位置,并在MeshFilter添加好相應的素材,搭建成一個海關站模型,并在網格渲染MeshRenderer中Element拖進相應的材料。圖4-2游戲場景場景里添加一些物體豐富游戲場景,例如,桌椅、電腦、筆記本、電腦桌、書架、辦公桌、盆栽、世界地圖背景,以及地板,這便是大致的海關站內部場景。圖4-3游戲內部場景燈光在Hierarchy面板中新創建的GameObject重命名為Lights,在Lights選項中創建一個DirectionalLight,在Inspector面板中調整位置以及角度,并在Light中Color將Hexadeciml改變為FFF4D6,Mode改為Mixed,Intensity改為2,選擇ShadowType下拉列表SoftShadows,并改變相應想要的數值。在Hierarchy面板中Lights選項中創建一個Cube,重命名為CubeLight,在Inspector面板中更改位置以及大小,并網格編輯器MeshRenderer中元素Element拉進素材LightHardCookie,接著在CubeLight選項中創建PointLight,在Inspector面板中Light的范圍Range設置為7,模式Mode選項選為Baked。將CubeLight拉進預制體_Prfabs中,并再重復使用拉進Lights選項中,并改變其相應位置,形成燈光環境。圖4-4燈光顯示圖特殊道具想要保證游戲的可玩性,需要提供更多的游戲道具,豐富游戲玩法。因此在Hierarchy面板中創建一個Empty,將新創建的GameObject重命名為Interaction,并以此來存放特殊道具。特殊道具包括了:電腦、筆記本電腦、紅色蓋章和綠色蓋章、危險警報器以及通行證和護照。因此,以下內容將是這些特殊道具的實現和說明。電腦辦公桌右手邊的電腦將顯示入境人員的基本信息,以及游戲玩家進行匹對,以及提供點擊下一位按鈕。在Hierarchy面板中的Interaction右鍵,創建一個Empty,將新創建的GameObject重命名為Computer,并在Inspector面板中Transform修改位置,在Tag選項中點擊AddTag添加Computer并選擇,在Computer選項中創建一個Cube,將新建好的Cube重命名為computer,在在MeshFilter添加computer素材,接著在computer選項中創建一個Canvas,并在Inspector面板Canvas中渲染模式RenderMode選項中選擇WorldSpace,隨后在Canvas選項中創建兩個Image,隨著重命名為BasePanel、NPCInfoPanel,在BasePanel的Inspector面板中將已經在Photoshop做好的“桌面1”拖進ScourceImage,在NPCInfoPanel選項下創建一個Image,將其命名為dImage_Ce_C作為入境人員的信息照片,接著創建7個文本Text,并在Inspector面板Text相應的填上(入境人員詳細信息、姓名、性別、年齡、國籍、職業、入境原因),又創建對應的6個空白文本Text,并重新命名,命名格式末尾帶“_C”。以及創建一個Button并且點擊下一位。圖4-5電腦Hierarchy圖圖4-6電腦顯示圖設計好電腦后,在代碼中使用一個單例類UIManager,類型為Dictionary<string,Dictionary<string,Transform>>的字典方法將父節點的名稱以及帶“_C”重命名子物體,存放進一個鍵值,并且對其字典的添加、移除和獲取。其中包括了:AddUI(添加UI組件)、RmoveUI(移除UI組件)、GetUI(獲取UI組件)。電腦上的UI將使用PureMVC框架實現功能,由經典的Model、View、Controller三層分離的方式。Model層由Data和Proxy組成,Data保存了View層的數據,而Proxy將Data封裝起來,負責數據的獲取和操作。View層由Mediator組成以及相應的UI組件,Mediator負責操作UI組件的命令。Controller層由Command組成,而Model和View通過了Command進行交互。表4-2PureMVC具體操作表View層編寫了ComNPCInfoMediator繼承了Mediator觸發UI界面時、實例化其對應的Mediator、Proxy、Command,通過UIIManager獲取UI組件。重寫ListNotificationInterests和HandleNotification方法用于Notification的注冊和接收。以及UpdateNPCInfo方法,將信息顯示在UI文本。Model層編寫ComNPCDataProxy繼承Proxy初始化data數據,并監聽觸發UI監聽。在UpdateNPCData方法中判斷當前入境人員的信息是否為空,調用Mediator注冊好的的Notification傳送data數據作為參數進行View層的更新。獲取新數據后,把數據更新到data中。Command層編寫ComUpdateNPCInfoCommand繼承SimpleCommand當實例化時便執行Execute方法。調用UpdateNPCData,更新Model層數據。Fa?ade層腳本ComFacade繼承Fa?ade使用switch和case的方法判斷不同的UI再分別的使用RegisterMediator、RegisterProxy、RegisterCommand的方法進行注冊。編寫OnDestroy方法,為委托添加對應的三層注銷方法并存儲到字典內,當該界面移除時,觸發該委托執行,從而進行對應三層的注銷。最后在主代碼ComputerView中,每個UI的初始化時,遍歷自身的所有節點,將所需要的子物體保存到字典內。使用這種方式后,我們只需要知道父物體的名稱,該物體的名稱,以及該物體的類型,就可以根據獲得的transform得到對應的組件。UIManager.Instance.Init();
Transform[]
allChild
=
gameObject.transform.GetComponentsInChildren<Transform>();
foreach
(var
item
in
allChild)
{
if
(.EndsWith("_C"))
{
UIManager.Instance.AddUI(,,item);
foreach
(var
i
in
parents)
{
if
(item.parent.gameObject
==
i)
break;
}
parents.Add(item.parent.gameObject);
}
}
筆記本電腦筆記本電腦放置在主場景攝像機的左手方向,提供給游戲玩家當前的績效、服務滿意度、以及城市安全。當作玩家的得分狀況。在Hierarchy面板中的Interaction右鍵,創建一個Empty,將新創建的GameObject重命名為portable,并在Inspector面板中Transform修改位置,在Tag選項中選擇Computer,在網狀過濾器MeshFilter以及網狀渲器MeshRenderer中拖入相應的素材;添加組件碰撞MeshCollider,把portable添加進Mesh中;在portable中創建一個Panle,在Panle中拉入預先設計好的素材;接著在Plane中創建三個Text文本。圖4-7筆記本電腦顯示圖在portable創建腳本SmallCom,創建一個UpdateText的方法,將相應的信息填寫進三個text文本中。
void
Start()
{
text1
=
transform.Find("Canvas/Panel/Text1").GetComponent<Text>();
text2
=
transform.Find("Canvas/Panel/Text2").GetComponent<Text>();
text3
=
transform.Find("Canvas/Panel/Text3").GetComponent<Text>();
ScoreManager.Instance.UpdateTo();
}
public
void
UpdateText(string
str1,string
str2,string
str3)
{
text1.text
=
str1;
text2.text
=
str2;
text3.text
=
str3;
}
}
并在引用ScoreManager類里,初始分數設置為,工作績點:15;服務滿意:50;城市安全:100;并且通過if-else語句更新分數。表4-3得分機制表入境人員是否入境工作績效服務滿意城市安全安全是↑↑↑否↓↓↑危險是↓↑↓否↑↓↑當績效低于5分,績效不合格,游戲結束。if
(score
<=
5)
{
GameOver(OverType.score);
}
public
void
GameOver(OverType
type)
{
if
(type
==
OverType.score)
{
MenuManager.Instance.DisplayMenu(MenuType.gameover,
"績效不達標!");
}
}
并且將使用ToString方法將intl類型轉化為string類型,輸入與筆記本電腦上的text文本。public
void
UpdateTo()
{
string
tmp
=
(score
/
10).ToString()
+
"."
+
(score
%
10).ToString();
evaluate
=
evaluate
<=
0
?
0
:
evaluate;
evaluate
=
evaluate
/
100f
>
1
?
1
:
evaluate;
string
tmp2
=
(evaluate
/
100f
).ToString();
smallCom.UpdateText(tmp,
tmp2,
secure.ToString());
}
紅色蓋章和綠色蓋章通過游戲玩家判斷入境人員是否符合入境資格,使用紅色蓋章拒絕通行,綠色蓋章允許通行。在Hierarchy面板中Interaction的創建一個Empty,創建兩個新的GameObject重命名為PassSeal、RejectSeal,并將Tag選為Interaction,在Inspector面板中改變兩個物體的相應位置,添加碰撞BoxCollilder以及剛體Rigidboby,接著在PassSeal下使用Unity自帶的ProBuilder工具搭建蓋章模型,并創建Empty,重命名為HandTarget附著在蓋章模型把手上當作抓取位置,添加OnTarch腳本;RejectSeal同理。圖4-8蓋章顯示圖在腳本里將蓋章物體加入PlayCrt腳本中的<OnTarch>列表,創建一個的數組存放蓋章上的MeshRenderer的組件,并遍歷使用“標準著色器”在材質上設置值“_Value”,在PlayCrt腳本中使用實現交互效果。public
class
OnTarch
:
MonoBehaviour
{
MeshRenderer[]
renderers;
PlayerCtr
player;
private
void
Start()
{
renderers
=
new
MeshRenderer[transform.childCount];
renderers
=
transform.GetComponentsInChildren<MeshRenderer>();
player
=
GameObject.FindWithTag(Tag.Player).GetComponent<PlayerCtr>();
player.RegistInteraction(this);
}
public
void
Disable()
{
foreach
(var
renderer
in
renderers)
{
renderer.material.SetFloat("_Value",
0);
}
}
}
以及在PlayCrt腳本中使用射線RaycastHit實例UI形印章圖片SetParent附著在想要的物體想以及保持之前的位置、旋轉量、縮放值,而印章圖片通過Resources加載預先放置的Pass(通過印章圖片)、Reject(拒絕印章圖片)。public
class
PlayerCtr
:
MonoBehaviour
{
public
List<OnTarch>
InteractionList;
public
void
InstanceSeal(RaycastHit
hit,
string
SealName)
{
GameObject
img
=
PoolManger.Instance.GetInstance(SealName);
img.transform.position
=
hit.point;
img.transform.forward
=
hit.normal;
if
(img.transform.rotation.y
!=
0)
img.transform.Rotate(0,
0,
90);
img.transform.SetParent(hit.transform,
true);
}
public
void
RegistInteraction(OnTarch
onTarch)
{
InteractionList.Add(onTarch);
}
}
金屬探測儀金屬探測儀是檢測入境人員隨身是否攜帶有危害金屬物品,可以檢測到如:手機、刀、槍械等等。在Hierarchy面板中Interaction的創建ProBuilderCube,重命名為Checker,并將Tag選為Interaction,創建出探測儀的模型,拉入MeshFilter素材;接著創建Empty,重命名為HandTarget附著在探測儀模型把手上當作抓取位置;接著創建Empty,重命名為CheckBox,加入碰撞體BoxCollider并點擊EditCollider改變大小并勾上IsTrigger。圖4-9金屬探測儀顯示圖添加OnTarch腳本在Checker中,當游戲運行時,將探測儀添加進<OnTarch>列表中,在CheckBox添加CheckerBoxCollider腳本,使用Collider檢測CheckBox與Tag標簽里的CheckOB碰撞顯示出物體,若使用LayerMask也檢測CheckBox與layer層CheckOB發出警報聲并且入境人員進行懷疑狀態。public
class
CheckerBoxCollider
:
MonoBehaviour
{
private
void
OnTriggerEnter(Collider
collider)
{
if
(collider.tag.Equals(Tag.CheckOB))
{
foreach
(var
item
in
collider.gameObject.GetComponentsInChildren<MeshRenderer>())
{
item.enabled
=
true;
}
if
(LayerMask.LayerToName(
collider.gameObject.layer).Equals(Tag.CheckOB))
//被發現攜帶危險品
{
AudioManager.Instance.Play("check",
transform.position);
collider.transform.parent.parent.parent.GetComponent<NPC>().EvilBeFind();
}
}
}
}
危險警報器當檢測到入境人員屬于危險人員時,可按壓安置在辦公桌下方的紅色按鈕,保護自我的人生安全。在Hierarchy面板創建創建Cube,重命名為ArrestBtn,將素材拖進MeshFilter中,并添加膠囊碰撞體CapsuleCollider,點擊EditCllider改變大小形狀。圖4-10危險警報器顯示圖創建ArrestBtn腳本放進ArrestBtn中,使用Tweener方法將危險警報器x軸方向前進0.008f,并保持該動畫不變,不關閉改動畫。public
class
ArrestBtn
:
MonoBehaviour
{
Tweener
tweener;
void
Start()
{
Vector3
target
=
transform.position;
target.x
+=
0.008f;
tweener
=
transform.DOMove(target,
1);
tweener.SetLoops(2,
LoopType.Yoyo);
tweener.Pause();
tweener.SetAutoKill(false);
}
}
接著在OnMouseDown方法里重新檢驗動畫是否播放成功,并判斷入境人員若是在懷疑狀態則,發出警報聲加載預制體的警察出現。或在檢查狀態則發出疑問。private
void
OnMouseDown()
{
if
(!tweener.IsPlaying())
{
tweener.Restart();
tweener.Play();
if(NPCManager.Instance.CurrentNPC!=null)
NPCManager.Instance.CurrentNPC.GetComponent<NPC>().BtnDown();
if(NPCManager.Instance.CurrentNPC.GetComponent<NPC>().fsmsys.CurrentIndex==((int)State.Doubt))
Instantiate(Resources.Load("NPC/swat"));
}
}
通行證和護照通行證以及護照是入境人員檢查時提供的有效證件,檢查證件也是游戲玩家查驗入境人員身份的重要步驟。在Hierarchy面板中創建兩個創建Cube,重命名為PassForm、SimplePassport,將通行證PassForm素材拖進Element里,添加BoxCollider,接著創建Panel,調整RectTransform中的位置以及大小,護照SimplePassport同理。在PassForm選項里的Panel中創建4個Text文本,并重命名為后綴帶有“_C”調整到相應的位置RectTransform,將OnTarch腳本拖進PassForm將通行證也加入<OnTarch>鏈表中,以及創建腳本PassFormInfo并拖進PassForm,將入境人員的的信息賦值到通行證的Text文本中,如果入境人員狀態為“evil”的并使用Random隨機生成0-6個數字,隨機改變通行證上的Text文本框信息。形成通行證信息與入境人員自身信息不同的情況。圖4-11通行證和護照public
class
PassFormInfo
:
MonoBehaviour
{
...
public
void
UpdateInfo(BaseNPC
info)
{
nameText.text
=
info.Name;
passNOText.text
=
info.PassNO;
causeText.text
=
info.Cause;
dateText.text
=
info.Date;
if
(info.Evil)
{
switch(
Random.Range(0,
6))
{
case
0:nameText.text
=
NPCManager.Instance.Databuilder.GetRandonName();
break;
case
1:passNOText.text
=
NPCManager.Instance.Databuilder.GetRandomPassNO();
break;
case
2:causeText.text
=
NPCManager.Instance.Databuilder.GetRandomCause();
break;
case
3:dateText.text
=
NPCManager.Instance.Databuilder.GetRandomDate();
break;
}
}
}
}
在SimplePassport選項里的Panel中創建5個Text文本,1個Image并重命名為后綴帶有“_C”調整到相應的位置RectTransform,將OnTarch腳本拖進SimplePassport將通行證也加入<OnTarch>鏈表中,創建腳本PassPortInfo并拖進SimplePassport,腳本邏輯與PassFormInfo同理。在預先寫好的PlayerCtr腳本中,使用射線RaycastHit功能檢測碰撞體是否為護照,并調整好位置并使用Material對應的蓋章渲染出來。public
void
UpdatePassFormSealTextPos(RaycastHit
hit)
{
Vector3
offset
=
hit.collider.gameObject.transform.position
-
hit.point;
offset
*=
10f;
offset.x
=
offset.x
<
0
?
offset.x
*
-2f
:
offset.x
*
-1f;
offset
+=
new
Vector3(1,
0,
0.7f);
offset.x
/=
3;
offset.z
/=
1.5f;
offset
*=
-3f;
offset
+=
new
Vector3(0.5f,
0,
0.5f);
Material
tmpMater
=
hit.collider.gameObject.GetComponent<MeshRenderer>().material;
tmpMater.SetTexture("_SealText",
sealText);
tmpMater.SetVector("_Offset",
new
Vector4(offset.z,
offset.x,
0,
0));
tmpMater.SetFloat("_IsSeal",
1);
}
接著實現查看通行證和護照以及取消查看,在Hierarchy面板中創建Empty,重命名為PassportViewPos,并在下列創建四個Empty,分別重命名為From0、From1、To0、To1,調整好Transform,分別兩兩對應,并在PlayerCtr腳本中創建兩個Transform數組存放,當作查看通行證和護照時顯示位置;再創建Tweener數組存放兩組From0到To0、以及From1到To1的動畫顯示。public
class
PlayerCtr
:
MonoBehaviour
{
tweener[0]
=
fromPos[0].transform.DOMove(toPos[0].position,
1);
tweener[0].Pause();
tweener[0].SetAutoKill(false);
tweener[1]
=
fromPos[1].transform.DOMove(toPos[1].position,
1);
tweener[1].Pause();
tweener[1].SetAutoKill(false);
...}
創建一個Transform數組resetPassportPos存放護照和通行證放置在辦公桌的位置,當要查看證件時先判斷fromPos[0]是否已存在物體,若無物體則將所查看的證件存放在fromPos[0],并且播放tweener[0]動畫;若已有物體存在則將證件存放在fromPos[1],并播放tweener[1]動畫。public
void
UpdateSeeAnim(int
index)
{
if
(index
==
0||index==2)
{tweener[0]
=
fromPos[0].transform.DOMove(toPos[0].position,
1);
tweener[0].Pause();
tweener[0].SetAutoKill(false);
}
if
(index
==
1||index==2)
{tweener[1]
=
fromPos[1].transform.DOMove(toPos[1].position,
1);
tweener[1].Pause();
tweener[1].SetAutoKill(false);
}
}
public
void
SeePassport(GameObject
ob)
{
int
index
=
fromPos[0].childCount
==
0
?
0
:
1;
UpdateSeeAnim(index);
tweener[index].OnStepComplete(()
=>
{
});
ob.transform.SetParent(fromPos[index]);
ob.transform.position
=
fromPos[index].position;
ob.transform.rotation
=
fromPos[index].rotation;
tweener[index].PlayForward();
}
當取消查看證件時,判斷取消查看物體是否存在fromPos[0],若存在證件則使用PlayForward反向播放tweener[0]動畫并且將物體存放在Transform數組resetPassportPos位置上;若不存在則反向播放tweener[1]動畫并且將物體存放在Transform數組resetPassportPos位置上。public
void
QuitSee(GameObject
ob)
{
int
index
=
==
"From0"
?
0:1;
tweener[index].OnStepComplete(()=>
{
ob.transform.SetParent(null);
ob.transform.position
=
resetPassportPos[index].position;
ob.transform.rotation
=
resetPassportPos[index].rotation;}
);
tweener[index].PlayBackwards();
}
入境人員檢查入境人員是這款游戲的主要玩法,因此豐富入境人員便豐富了游戲玩法,增加了游戲的可玩性。我將從入境人員的基本信息多種類、攜帶的物體、創建入境人員信息入境人員的信息是使用序列化Serializable,分別創建編號、姓名、性別、年齡、入境原因、國籍、以及通行證編號,將序列化好的信息實例好在BaseNPC中;并且將大量不重復的姓名、性別、年齡、入境原因、國籍分別填入txt文件中,作為入境人員的信息資料。因此,創建一個NPCDataBuilder類,使用UnityWebRequest方法讀取txt文件,將txt文件上的信息賦值給入境人員,并且使用string系統里的Split方法將txt文件中的信息切割成一組一組數組成為入境人員的信息。例如:string
text
=
textNameMan._WWW.downloadHandler.text;
string[]
texts
=
text.Split(System.Environment.NewLine.ToCharArray(),System.StringSplitOptions.RemoveEmptyEntries);
nameMan
=
new
string[texts.Length];
for
(int
i
=
0;
i
<
texts.Length;
i++)
{
nameMan[i]
=
texts[i];
}
接著在GetNPCData中使用Random.Range方法隨機生成字符串數組賦值給對應的入境人員數據中。public
BaseNPCDataTmp
GetNPCData()
{
BaseNPCDataTmp
npc
=
new
BaseNPCDataTmp();
npc.Sex
=
Random.Range(0,
5)
<
4
?
"男"
:
"女";
npc.Name
=
npc.Sex
==
"男"
?
nameMan[Random.Range(0,
nameMan.Length)]
:
nameWoman[Random.Range(0,
nameWoman.Length)];
npc.Age
=
(byte)Random.Range(18,
58);
npc.Nation
=
nation[Random.Range(0,
nation.Length)];
npc.Occu
=
occu[Random.Range(0,
occu.Length)];
npc.Cause
=
cause[Random.Range(0,
cause.Length)];
return
npc;
}
入境人員攜帶物品入境人員攜帶的物品,包括通行證和護照,以及可能包括危險金屬物品(槍械,刀)和普通金屬物品手機等等。因此在入境人員選項中創建六個空物體創建Empty,分別重命名為Passport、Passform、0、1、2、3,其中調整Passport和Passform的Transform位置為入境人員的手心,作為通行證和護照,接著0、1、2、3,分別調整Transform位置為入境人員的衣兜、以及口袋,并歸于CheckOBPos選項下,當作金屬物品存放位置。在NPCManager腳本中實例攜帶的物品,若入境人員為危險人員,則必須攜帶一件或者多個以上的危險物品,并隨機放置在(0、1、2、3)上。
private
void
InstanCheckOB(bool
isEvil,
GameObject
npcModel)
{
int
count
=
Random.Range(0,
3);
if
(count
==
0
&&
isEvil)
{
count
=
1;
}
for
(int
i
=
0;
i
<
count;
i++)
{
GameObject
tmp;
if
(i
==
0
&&
isEvil)
{
tmp
=
Instantiate(Models.GetCheckOBRandom());
npcModel.GetComponent<NPC>().weapon
=
tmp;
}
else
{
tmp
=
Instantiate(Models.GetSaveOBRandom());
}
tmp.transform.SetParent(npcModel.transform.Find("CheckOBPos").transform.Find(Random.Range(0,
4).ToString()));
tmp.transform.localPosition
=
Vector3.zero;
tmp.transform.right
=
Camera.main.transform.forward;
MeshRenderer[]
meshs=
tmp.GetComponentsInChildren<MeshRenderer>();
foreach
(var
item
in
meshs)
{
item.enabled
=
false;
}
}
}
入境人員動作當入境人員運行其中一種觸發的時候,會導致其他動作無法觸發,造成動作之間不相協調失去仿真性,以下是我實現入境人員動作的方法。我入境人員的動作如下表,創建對應的Animator。表4-4Animator表動作名稱Animator名稱步行Walk談話Talk坐下Sit拿起特殊道具(槍械、證件)Take舉手投降HandUp圖4-12動畫狀態圖在游戲創建入境人員時就會添加AI腳本,使用Animator.StringToHash將對應的動作生成ID,并使用Animator系統中的AnimatorOverrideControllerr生成狀態機動畫存放在animationClips數組里,對基礎的AnimatortControll進行覆蓋,等待被激活使用。圖4-13動畫狀態圖為了使入境人員的動作更加仿真,給人物添加了程序化動畫綁定(AnimationRigging),如<TwoBoneIKConstraint>、<MultiParentConstraint>、<MultiAimConstraint>,將這些組件添加在人物關鍵的骨骼上。在腳本里添加入境人員神態眼睛看的地方,以及改變Rig的權重。private
void
Update()
{
//如果使用左手,權重設置在1到隨速度2線性插值
if
(lfHandEnable)
{
lfHandWeight
=
Mathf.Lerp(lfHandWeight,
1,
Time.deltaTime
*
weightSpeed);
}
else
{//若小于0.1f設置為0
if
(lfHandWeight
!=
0)
{
if
(lfHandWeight
<
0.1f)
{
lfHandWeight
=
0;
}
else//若大于0.1f,則設置在0到隨速度2線性插值
lfHandWeight
=
Mathf.Lerp(lfHandWeight,
0,
Time.deltaTime
*
weightSpeed);
}
}
if
(rtHandEnable)
//如果使用右手,權重設置在1到隨速度2線性插值
{
rtHandWeight
=
Mathf.Lerp(rtHandWeight,
1,
Time.deltaTime
*
weightSpeed);
}
else
{//若小于0.1f設置為0
if
(rtHandWeight
!=
0)
{
if
(rtHandWeight
<
0.1f)
{
rtHandWeight
=
0;
}
else//若大于0.1f,則設置在0到隨速度2線性插值
rtHandWeight
=
Mathf.Lerp(rtHandWeight,
0,
Time.deltaTime
*
weightSpeed);
}
}
}
入境人員交互與入境人員進行簡單對話推動了游戲的劇情進程。在入境人員選項下創建兩個文本框,并且制作一份入境人員對話的Excel表格,并且創建一個NPCTalkMag基類,獲取了讀取對話Excel表格轉化為Json文件數據、以及使用JsonMapper.ToObject儲存在一個BaseTalkTmp數組中。并遍歷使用字典Dictionary添加,如:string
str
=
txt._WWW.downloadHandler.text;
BaseTalkTmp[]
tmp
=
JsonMapper.ToObject<BaseTalkTmp[]>(str);
foreach
(var
item
in
tmp)
{
BaseTalkTmpForRead
tmptalk
=
new
BaseTalkTmpForRead(item);
dict.Add(tmptalk.Mood,
tmptalk);
}
枚舉了入境人員談話過程中可能出現的狀態greet、jumpQueue、beJumpQueue、accept、reject、pass、nopass、doubt、evil、panic、thank、disappoint。編寫BaseTalk方法,使用while將第一輪對話進行到底,跳出循環進行第二輪對話。
while
(tmpbase
!=
null)
{
tmpbase.index
+=
index;
tmpbase.question
=
_talk.strs[tmpbase.index];
tmpindex
=
tmpbase.index;
tmpbase
=
tmpbase.answer1;
}
answer2
=
ans2;
tmpbase
=
answer2;
tmpindex
=
index;
while
(tmpbase
!=
null)
{
tmpbase.index
+=
index;
tmpbase.question
=
_talk.strs[tmpbase.index];
tmpindex
=
tmpbase.index;
tmpbase
=
tmpbase.answer2;
}
question
=
_talk.strs[index];
}
接著在入境人員選項下創建兩個Button,與入境人員進行交互,基礎腳本TalkBoxCtr繼承于NPCTalkMag,添加了按鈕觸發事件。private
void
BtnEvent(int
index)
{
HideSelect();
bool
isPositive
=
answer1Index
==
index
?
true
:
false;
BaseTalk
tmp
=
isPositive
?
baseTalk.answer1.answer1
:
baseTalk.answer2.answer1;
TalkOrMood(tmp.question);
SendEvent(isPositive);
baseTalk
=
null;
}
不同狀態觸發不同事件,通過判斷NPCTalkMag類里入境人員枚舉的狀態,例如偏激狀態下不同入境人員(危險人員、插隊人員、被插隊人員)的回應。示例如:偏激狀態下危險人員回答的問題。
if
(talkState
==
TalkState.greet)
{
if
(IsPositive)
{
if
(npc.baseNPC.Evil)
TalkOrMood(NPCManager.Instance.Databuilder.GetRandomCause());
else
TalkOrMood(npc.baseNPC.Cause);
}
}
使用SetPositionAndRotation和Vector3系統中Lerp方法實現對話框分段上升動畫效果。private
void
UpdatePanel(int
Listindex,bool
isMoverToUp=false)
{
if
(Listindex>=panels.Count)
return;
RectTransform
tmp
=
panels[Listindex];
int
index;
if
(tmp.Equals(panel[0]))
index
=
0;
else
index
=
1;
time[index]
-=
Time.deltaTime;
if
(time[index]
<=
0)
{
time[index]
=
0;
HideTalk(index);
return;
}
if
(isMoverToUp)
{
Vector3
target
=
new
Vector3(panel[index].position.x,
secondPosY,
panel[index].position.z);
Vector3
lerp
=
Vector3.Lerp(panel[index].position,
target,
Time.deltaTime
*
moveSpeed);
panel[index].SetPositionAndRotation(lerp,
panel[index].rotation);
}
}
主要對話交流進程。當點擊左右兩個按鈕提出簡單問題詢問入境人員相關情況,入境人員并隨著回答。。public
void
TalkByBaseTalk(BaseTalk
_baseTalk,TalkState
state)
{
talkState
=
state;
baseTalk
=
_baseTalk;
TalkOrMood(baseTalk.question);
button[0].GetComponentInChildren<Text>().text
=
null;
button[1].GetComponentInChildren<Text>().text
=
null;
if
(baseTalk.answer1
==
null)
return;
int
index
=
Random.Range(0,
1);
answer1Index
=
index;
button[index].GetComponentInChildren<Text>().text
=
baseTalk.answer1.question;
if
(baseTalk.answer2
==
null)
return;
button[++index
%
2].GetComponentInChildren<Text>().text
=
baseTalk.answer2.question;
}
當游戲過程中,添加了入境人員出現插隊的狀況,因此添加了NPCThinkMag類。等待過程中,入境人員通過判斷檢查人員以及被插隊人員都不為空并且自身的情緒數值小于3便進行插隊;public
void
ThinkForChangeState(NPC
npc)
{
if
(npcMag.npcQueue.Count
!=
0
&&
npcMag.JumpQueueNPC
==
null&&
!npcMag.SomeoneReadToJump
&&
npcMag.BeJumpNPC==null
&&npc.baseNPC.mood<3)
npc.fsmsys.ChangeState((int)State.JumpQueue);
else
if
(npcMag.CurrentNPC
!=
null
||
npcMag.JumpQueueNPC
!=
null
||
npcMag.BeJumpNPC
!=null)
npc.fsmsys.ChangeState((int)State.Sit);
else
npc.fsmsys.ChangeState((int)State.Check);
}
當游戲玩家面對插隊情況下,選擇被插隊人員或者插隊人員時,被插隊人員和插隊人員通過自身的情緒數值表現出的不同狀態回應。public
bool
ThinkForBeRejectJumpQueue(NPC
npc)
{
npc.baseNPC.mood--;
if
(npc.baseNPC.mood.Equals(0))
return
true;
else
return
false;
}
public
bool
ThinkForBeJumped(NPC
npc)
{
if
(npc.baseNPC.mood-1<1)
return
true;
else
return
false;
}
入境人員路徑當游戲運行時,入境人員由游戲場景外進入攝像頭場景,游戲進程的不同則入境人員相應的位置也不相同。因此,需要規范好相應的路徑點,規范好游戲進程的順序。在Hierarchy面板中創建8個空物體(出生起點、進門點、檢查點、入境消失點、拒絕入境消失點、排隊一、排隊二、排隊三),以及兩個空物體,重命名為JumpQueuePos、BeJumpQueuePos,分別為插隊
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2030年中國扁平壓線鉗行業發展研究報告
- 2025至2030年中國座便墊市場分析及競爭策略研究報告001
- 高一11月聯考試卷及答案
- 仿真儀表企業制定與實施新質生產力戰略研究報告
- 自閉癥社交故事書行業跨境出海戰略研究報告
- 自由搏擊錦標賽行業跨境出海戰略研究報告
- 個人維修勞務合同樣本
- 義務運輸合同樣本
- 買賣瓷磚合同標準文本
- 買賣地基合同標準文本
- 湖南省常德市2025屆高三下學期模擬考試(二模)物理試卷(含答案)
- 人教版初一下學期生物實驗報告冊
- 《月是故鄉明》定稿 優秀獎 教學課件
- 高鐵站裝飾裝修施工方案
- 防臺防汛管理制度
- 消防器材(滅火器)檢查及記錄表
- 2012小小科學家高年級試題生物
- 廣電運通研究報告:數字人民幣促產業升級-AI+城市助業務轉型
- 移動式腳手架安全操作規程
- 永輝超市企業文化ppt課件
- 多肉生石花圖譜_版
評論
0/150
提交評論