個人Unity自用面經(未完)

目錄標題

      • 1.在 2D 平臺跳躍游戲項目中,你使用了對象池來生成和回收怪物包含陣亡的動畫預制件。在對象池回收對象時,如何確保動畫狀態被正確重置,避免下次使用時出現異常?
      • 2.在僵尸吃腦子模擬項目中,你創建了繼承于IAspect的aspect,并通過RefRW和RefRO定義訪問的屬性。能詳細說說在實際使用中,RefRW和RefRO有什么區別嗎?在什么場景下分別使用它們?
      • 3.在 2D 平臺跳躍游戲項目中,你使用對象池來生成和回收怪物預制件。在對象池的設計與實現過程中,如何確定對象池的初始容量和最大容量呢?
      • 4.在 3D 回合制策略游戲中,你使用了狀態機實現敵人的 AI,并且 AI 的行為帶權。在不同情況下,不同動作的權值是如何確定的呢?
      • 5.在僵尸吃腦子模擬項目里運用了 ECS 架構,你也清楚 ECS 架構適合并行計算。那在實際開發中,是怎樣去利用 ECS 架構實現并行計算,進而提升游戲性能的呢?
      • 6.在 2D 平臺跳躍游戲項目中,你使用了 TileMap 瓦礫地圖系統構建地圖。在使用過程中,如何實現地圖的動態加載與卸載,以優化游戲內存占用?
      • 7.在 3D 回合制策略游戲中,你使用了狀態機來管理角色的行為狀態。當角色的狀態比較復雜,存在多種狀態之間的相互轉換,并且有一些狀態還存在子狀態時,你是如何設計狀態機以確保邏輯清晰,易于維護和擴展的呢?
      • 8.在僵尸吃腦子模擬項目里,你運用了 ECS 架構。當游戲場景中僵尸數量極多,比如上萬只時,可能會面臨性能瓶頸。你打算采取哪些策略來優化 ECS 架構下大規模僵尸的性能表現呢?
      • 9.在你參與的 “3D 回合制策略游戲” 項目里,你使用了狀態機實現敵人的 AI 且行為帶權。在游戲運行過程中,如果玩家做出了一個游戲設計師未曾預料到的操作,導致敵人 AI 的權值計算出現異常,你會如何排查和解決這個問題?
      • 10.在 “僵尸吃腦子模擬” 項目里,你使用了 ECS 架構并創建了多個繼承于ISystem的系統。當多個系統之間存在數據依賴關系時,你是如何管理和協調這些依賴關系,以確保系統執行順序正確且數據一致性的?

豆包 中等偏上—優秀 評價

1.在 2D 平臺跳躍游戲項目中,你使用了對象池來生成和回收怪物包含陣亡的動畫預制件。在對象池回收對象時,如何確保動畫狀態被正確重置,避免下次使用時出現異常?

答:我在泛型對象池定義之初就設置了一個私有的抽象Reset函數,對于后續繼承它的對象池必須要實現它,然后在對外公開的回收預制體函數ReturnToPool中調用這個Reset函數,這樣來保證他們狀態復原,避免異常。比如我在Reset中重新設定這個預制體的動畫機中所有的轉換條件參數復原,Transform屬性復原,并且在Reset函數里使用了Try和catch來捕獲重置失敗的預制體。

2.在僵尸吃腦子模擬項目中,你創建了繼承于IAspect的aspect,并通過RefRW和RefRO定義訪問的屬性。能詳細說說在實際使用中,RefRW和RefRO有什么區別嗎?在什么場景下分別使用它們?

答:Ref RW對應的就是ref關鍵字, read and write,RO 對應的就是 read only,意思就是前者是一個可讀寫的屬性,后者是一個只可讀的屬性,這要根據需求來用,比如我項目里寫了僵尸的行走速度,我不希望他改變所以我把aspect里面對僵尸速度屬性的引用設置為只讀的意味著我不希望改變他,比如項目中墓碑的Transform屬性,我希望每個墓碑生成的位置角度是不一樣的所以我設置他為可讀寫的。

3.在 2D 平臺跳躍游戲項目中,你使用對象池來生成和回收怪物預制件。在對象池的設計與實現過程中,如何確定對象池的初始容量和最大容量呢?

答:初步預估對象池容量
統計游戲數據:在設計階段,仔細分析游戲場景和玩法,統計出游戲中不同類型對象(如怪物、子彈、道具等)同時出現的最大數量和常見數量。例如在一個射擊游戲中,統計一場戰斗里最多會同時存在多少顆子彈,一般情況下又會有多少顆子彈。
考慮擴展系數:為了應對游戲中可能出現的特殊情況,如玩家觸發特殊技能、進入特殊關卡等導致對象數量突然增加,需要在最大數量的基礎上乘以一個擴展系數(通常為 1.2 - 1.5),以此確定對象池的最大容量。初始容量可以設置為常見數量的均值。
游戲測試階段的性能監測
選擇合適的監測工具:在 Unity 中,可以使用內置的 Profiler 工具來監測對象池的使用情況,它能提供詳細的內存使用信息、對象創建和銷毀的頻率等數據。
關注關鍵指標:重點關注對象池的擴容次數、閑置對象數量、對象創建和銷毀的時間等指標。如果對象池頻繁擴容,說明初始容量設置過小;如果大部分時間對象池都有大量閑置對象,說明最大容量設置過大。
根據監測數據進行動態調整
增大初始容量:如果發現對象池頻繁擴容,導致游戲性能下降,可以適當增大初始容量。例如,將初始容量增加 20% - 30%,然后再次進行測試,觀察性能是否有所改善。
減小最大容量:如果對象池大部分時間都有大量閑置對象,占用了過多的內存,可以考慮減小最大容量。每次減小的幅度不宜過大,建議在 10% - 20% 之間,然后重新測試,確保不會影響游戲的正常運行。

4.在 3D 回合制策略游戲中,你使用了狀態機實現敵人的 AI,并且 AI 的行為帶權。在不同情況下,不同動作的權值是如何確定的呢?

答:
我的項目中敵人和友軍都是繼承自player這個父類的,所以他們能使用的動作是一樣的,對于敵人他有移動,射擊,手雷。3個動作,我把移動的權值設置成10 - 可攻擊范圍內敵人的數量 * 3,這樣如果范圍內有敵人那么他們就不更容易去移動,對于射擊權值就是 8,手雷權值是8 + (可攻擊范圍內敵人的數量 - 1) * 2,于是在有敵人且只有一個的情況下會使用射擊,有敵人且有多個的情況下會使用手雷,沒有敵人的情況下會使用移動,同時攻擊還跟敵人剩余的血量有關,對于移動還要計算每個可到達的地點的權值不同于之前的權值系統,它會優先選擇更多可接觸敵人的地點到達,這些其實都只和設計者的需求來設定。

5.在僵尸吃腦子模擬項目里運用了 ECS 架構,你也清楚 ECS 架構適合并行計算。那在實際開發中,是怎樣去利用 ECS 架構實現并行計算,進而提升游戲性能的呢?

答:
首先建立一個Job : IEntityJob,把這個job需要用到的所有東西比如EntityCommandBuffer.ParallelWriter如果不是并發的那么不用使用ParallelWriter(ecb用于更改實體組件,生成實體等)可以暫存某些指令等到某個時間點一起執行以免出現并發的線程爭奪和數據錯讀問題,還有一些數據,或者實體。然后實現這個Job的Execute方法,如有需要還要提供sortKey這個參數,在調用這個作業的時候會自動檢索含有Execute帶有的組件的實體,并且在運行的時候給他發配一個sortKey。最后只需要在調用這個任務的system中new這個job,然后給他提供所需要的參數比如使用SystemAPI.Getsingleton,GetComponent等等,用來new這個job并且調用它,需要注意的是在EntityCommandBufferSystem創建EntityCommandBuffer的時候要AsParallelWriter否則會報錯,這里state作用是在非托管世界申請一個命令緩沖區并且視為并發寫者來緩存并執行并發的命令,因為要并發執行,最后在new的尾處.ScheduleParallel()進行并發執行任務。

避免在一個任務中修改另一個任務需要讀取的數據

6.在 2D 平臺跳躍游戲項目中,你使用了 TileMap 瓦礫地圖系統構建地圖。在使用過程中,如何實現地圖的動態加載與卸載,以優化游戲內存占用?

答:
地圖分塊處理
劃分地圖區域:把整個游戲地圖按照一定規則劃分成多個小的地圖塊,比如以正方形或矩形區域為單位。每個地圖塊都可以獨立加載和卸載。例如,在一個大型的 2D 平臺跳躍游戲世界中,可以將其劃分為多個 10×10 個 Tile 的地圖塊。
確定加載范圍:依據玩家當前所在的位置和視野范圍,確定需要加載的地圖塊。一般來說,除了玩家當前所在的地圖塊,還需要加載其周圍的一些地圖塊,以保證玩家移動時地圖的連貫性。比如,玩家在一個地圖塊中,那么可以同時加載其上下左右以及四個對角方向相鄰的地圖塊。
實現動態加載與卸載機制
加載邏輯:當玩家接近某個未加載的地圖塊時,觸發加載操作。可以使用 Unity 的場景加載 API(如 SceneManager.LoadSceneAsync )來異步加載地圖塊。異步加載不會阻塞主線程,能保證游戲的流暢性。在加載時,還可以顯示一個加載提示,提升用戶體驗。
卸載邏輯:當某個地圖塊遠離玩家的視野范圍,并且在一段時間內不會被玩家訪問到時,觸發卸載操作。使用 SceneManager.UnloadSceneAsync 來異步卸載地圖塊,釋放內存。
緩存機制
臨時緩存:為了避免頻繁的加載和卸載操作,可以設置一個緩存區,將最近使用過的地圖塊暫時保留在內存中。當玩家再次需要訪問這些地圖塊時,可以直接從緩存中獲取,而不需要重新加載。
緩存淘汰策略:由于緩存區的容量是有限的,當緩存區達到最大容量時,就需要移除一些數據來為新的數據騰出空間。常見的淘汰策略有先進先出(FIFO)、最近最少使用(LRU)等。

7.在 3D 回合制策略游戲中,你使用了狀態機來管理角色的行為狀態。當角色的狀態比較復雜,存在多種狀態之間的相互轉換,并且有一些狀態還存在子狀態時,你是如何設計狀態機以確保邏輯清晰,易于維護和擴展的呢?

答:我使用狀態機系統來維護我的狀態,狀態機內部只有 state currentstate,兩個公開的方法public void changeState(State stateName)和public void Initial,然后每個state都繼承自Istate必須實現Istate里的抽象方法,Enter,Exit,Update,然后在FSM類里創建一個枚舉類State用于枚舉每個狀態的名字,和一個字典關聯 State state 和 Istate theState,然后FSM里包含對狀態機的聲明,并且有AddState方法用于往字典里添加狀態,在聲明fsm變量的腳本中的Onupdate調用currenState.Update,這樣就可以確保狀態之間的模塊化和解耦而且擴展方便,維護方便。子狀態也同樣可以這樣使用和添加,確保同一個時間只有一個狀態在執行。

8.在僵尸吃腦子模擬項目里,你運用了 ECS 架構。當游戲場景中僵尸數量極多,比如上萬只時,可能會面臨性能瓶頸。你打算采取哪些策略來優化 ECS 架構下大規模僵尸的性能表現呢?

答:
空間分區與裁剪:
將游戲場景劃分為多個空間區域,比如使用**四叉樹(2D 場景)或八叉樹(3D 場景)**結構。為每個僵尸分配所屬的區域,當進行渲染、碰撞檢測或 AI 計算時,只處理玩家所在區域及相鄰區域內的僵尸。例如,玩家在一個特定房間內,只計算該房間及其相鄰房間內的僵尸,避免對整個場景中所有僵尸進行不必要的操作。
對于視野范圍外的僵尸,不進行渲染和復雜的 AI 計算,只保留基本的位置追蹤等輕量級信息,當僵尸進入玩家視野范圍時再進行完整的處理。
批處理與合并:
在渲染方面,將多個僵尸的渲染數據合并成一個批次進行繪制。利用 GPU 的批處理功能,減少 Draw Call 的數量。比如,可以將相同類型、相同材質的僵尸的頂點數據、索引數據等合并,一次性提交給 GPU 進行渲染,提高渲染效率。
對于僵尸的物理碰撞檢測,可以將多個僵尸分組,對組內的僵尸進行統一的碰撞檢測處理,而不是逐個僵尸進行檢測,減少碰撞檢測的計算量。
優化組件與數據結構:
確保僵尸的組件設計簡潔,只包含必要的數據和功能。避免在組件中存儲過多冗余或不常用的數據。例如,如果僵尸的某個屬性只在特定情況下使用,可以考慮在需要時動態獲取,而不是一直存儲在組件中。
選擇合適的數據結構來存儲僵尸相關的數據。例如,使用數組而不是鏈表來存儲僵尸列表,因為數組在隨機訪問和遍歷方面通常具有更好的性能。同時,可以對數據進行預排序,以便在進行某些計算(如距離排序)時提高效率。
并行計算與多線程優化:
充分利用 ECS 架構的并行計算優勢,將僵尸的 AI 計算、物理模擬等任務拆分成多個并行任務,利用多核 CPU 進行加速。例如,為每個僵尸的 AI 行為計算創建一個 Job,通過 ScheduleParallel() 方法并行執行這些 Job。
注意避免多線程之間的資源競爭和數據沖突。合理使用鎖機制或無鎖數據結構來保護共享資源。例如,對于僵尸的生命值等共享數據的修改,使用線程安全的方式進行操作。
LOD(Level of Detail)技術:
為僵尸設置不同的細節層次模型。當僵尸距離玩家較遠時,使用低細節模型,減少模型的頂點數量和紋理復雜度,降低渲染成本。當僵尸靠近玩家時,切換到高細節模型,提供更好的視覺效果。
同樣,對于僵尸的 AI 行為也可以設置不同的細節層次。例如,遠處的僵尸可以采用簡單的巡邏行為,而近處的僵尸則執行更復雜的追逐和攻擊行為。

9.在你參與的 “3D 回合制策略游戲” 項目里,你使用了狀態機實現敵人的 AI 且行為帶權。在游戲運行過程中,如果玩家做出了一個游戲設計師未曾預料到的操作,導致敵人 AI 的權值計算出現異常,你會如何排查和解決這個問題?

答:
我應該會在敵人AI采取行動的使用使用Try和Catch去捕捉錯誤,如果沒有捕捉到說明沒有語法上或者訪問越界等的問題而是邏輯上的問題,那么如果是后者只能去跟隨敵人狀態機進行一步一步的調試,如果它引起了空間或者性能問題那么可以使用性能檢測工具profile來檢測哪個函數或者哪個部分出現了內存性能異常。

10.在 “僵尸吃腦子模擬” 項目里,你使用了 ECS 架構并創建了多個繼承于ISystem的系統。當多個系統之間存在數據依賴關系時,你是如何管理和協調這些依賴關系,以確保系統執行順序正確且數據一致性的?

答:
在ECS架構中不像Unity自帶一個腳本執行順序的調整功能。在ECS架構中你運行項目的時候如果先后順序有問題那么大概率會報錯并且無法運行,屆時你可以到Windows->Entities->System中查看每個系統的執行時間,但是這里不像unity原生開發框架可以直接拖動,你必須到每個系統中使用UpdateInGroup(typeof(InitializationSystemGroup))此處可以替換為很多ECS內定好的系統組或者UpdateAfter,Before某個System來調整它們的執行順序。通過這個動作來保證依賴的關系不會出現問題,比如我項目中僵尸生成系統就定義了[UpdateAftertypedef(TombStoneSpawnSystem)]因為我僵尸生成的位置依賴于墓碑生成的位置。
避免循環引用導致相互依賴,可以設置中間層來接收相互依賴之間的數據避免直接依賴來解耦,或者調整循環依賴之間的關系,讓其中一個不再引用環中的數據。
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/79676.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/79676.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/79676.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【計網】ICMP、IP、Ethernet PDU之間的封裝關系

TCP/IP體系結構 應用層RIP、OSPF、FTP運輸層TCP、UDP網際層IP、ARP、ICMP網絡接口層底層協議(Ethernet) 數據鏈路層 Ethernet報文格式 6Byte6Byte2Byte46~1500Byte4Byte目的MAC地址源MAC地址類型/長度數據FCS 其中,類型 / 長度值小于 1536…

前端取經路——入門取經:初出師門的九個CSS修行

大家好,我是老十三,一名前端開發工程師。CSS就像前端修行路上的第一道關卡,看似簡單,實則暗藏玄機。在今天的文章中,我將帶你一起應對九大CSS難題,從Flexbox布局到響應式設計,從選擇器優先級到B…

n8n工作流自動化平臺的實操:Cannot find module ‘iconv-lite‘

解決問題: 1.在可視化界面,執行const iconv require(iconv-lite);,報Cannot find module iconv-lite [line 2]錯誤; 查看module的路徑 進入docker容器 #docker exec -it n8n /bin/sh 構建一個test.js,并寫入如何代碼 vi tes…

如何在 PowerEdge 服務器上設置 NIC 分組

以下文章提供了有關 Windows、VMware 和 Linux 中的 NIC 分組的信息。 什么是網絡適配器分組?設置 NIC 分組 Windows設置 NIC 分組 VMware設置 NIC 分組 Linux 什么是網絡適配器分組(綁定)? 網絡適配器分組是一個術語&#xff0…

【Java ee初階】多線程(5)

一、wait 和 notify wait notify 是兩個用來協調線程執行順序的關鍵字,用來避免“線程餓死”的情況。 wait 和 notify 其實都是 Object 這個類的方法,而 Object這個類是所有類的“祖宗類”,也就是說明,任何一個類,都…

基于k8s的Jenkins CI/CD平臺部署實踐(二):流水線構建與自動部署全流程

基于k8s的Jenkins CI/CD平臺部署實踐(二):流水線構建與自動部署全流程 文章目錄 基于k8s的Jenkins CI/CD平臺部署實踐(二):流水線構建與自動部署全流程一、Jenkins簡介二、系統架構與環境說明1. 系統架構2.…

《Windows 環境下 Qt C++ 項目升級 GCC 版本的完整指南》

Windows 環境下 Qt C++ 項目升級 GCC 版本的完整指南 在 Windows 系統中升級 Qt C++ 項目的 GCC 版本需要同時考慮 Qt 工具鏈、MinGW 環境以及項目配置的調整。以下是詳細的升級步驟和注意事項: 一、升級前的準備工作 1. 確認當前環境 檢查 Qt 版本(建議使用 Qt 5.15+ 以獲…

【coze】故事卡片(圖片、音頻、文字)

【coze】故事卡片(圖片、音頻、文字) 1、創建智能體2、添加人設與回復邏輯3、添加工作流(1)創建工作流(2)添加大模型節點(3)添加提示詞優化節點(4)添加豆包圖…

Maven 依賴發布與倉庫治理

🧑 博主簡介:CSDN博客專家,歷代文學網(PC端可以訪問:https://literature.sinhy.com/#/?__c1000,移動端可微信小程序搜索“歷代文學”)總架構師,15年工作經驗,精通Java編…

虛擬現實視頻播放器 2.6.1 | 支持多種VR格式,提供沉浸式觀看體驗的媒體播放器

虛擬現實媒體播放器是一款專為在智能手機上播放VR(虛擬現實)照片和視頻而設計的應用程序。它支持多種格式的影像內容,包括360和180等距矩形柱面、標準鏡頭和魚眼鏡頭拍攝的照片和視頻,并且兼容3D立體并排、上/下以及收縮媒體格式。…

ts axios中報 Property ‘code‘ does not exist on type ‘AxiosResponse<any, any>‘

ts語法有嚴格的格式,如果我們在處理響應數據時,出現了axios響應中非默認字段,就會出現標題那樣的警告,我們可以通過創建axios.dt.ts解決這個問題 下面是我在開發中遇到的警告,code并不是axios默認返回的字段&#xff0…

tinyrenderer筆記(Shadow Mapping)

tinyrenderer個人代碼倉庫:tinyrenderer個人練習代碼 前言 陰影是光線被阻擋的結果;當光源的光線由于其他物體的阻擋而無法到達物體表面時,該物體就會產生陰影。陰影能使場景看起來更真實,并讓觀察者獲得物體之間的空間位置關系。…

debian中筆記本的省電選擇auto-cpufreq

在reddit中,看評論區出現這個軟件,于是打算嘗試一下,應該能對不使用電源時筆記本的省電起到一定的作用。 https://github.com/AdnanHodzic/auto-cpufreq?tabreadme-ov-file#why-do-i-need-auto-cpufreq 作用 One of the problems with Linux…

Windows 查看電腦是否插拔過U盤

1、按 “WinR” 組合鍵打開 “運行” 對話框,輸入 “regedit” 并回車,打開注冊表編輯器。 2、依次展開HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR注冊表項,這里記錄了所有已連接過的 USB 設備信息,包括 U 盤&am…

426、N叉樹的層序遍歷

輸入檢查: if not root:return [] 如果根節點為空,直接返回空列表 初始化: result [] queue collections.deque([root]) result用于存儲最終結果queue初始化包含根節點,使用雙端隊列實現 主循環: while queue:leve…

【ES】Elasticsearch字段映射沖突問題分析與解決

在使用Elasticsearch作為搜索引擎時,經常會遇到一些映射(Mapping)相關的問題。本文將深入分析字段映射沖突問題,并通過原生的Elasticsearch API請求來復現和解決這個問題。 問題描述 在實際項目中,我們遇到以下錯誤: Transport…

小紅書怎么看自己ip地址?小紅書更改ip地址教學

在社交媒體高度透明的今天,小紅書等平臺公開用戶IP屬地的功能引發了廣泛討論。無論是出于隱私保護的擔憂,還是因需要切換屬地,許多用戶都迫切想知道:能否通過手動修改“偽裝”所在地? 事實上,IP屬地可能影…

深入理解 Java 觀察者模式:原理、實現與應用

在軟件開發領域,設計模式堪稱開發者智慧的凝練結晶,它們為解決各類常見編程難題提供了行之有效的方案。觀察者模式(Observer Pattern)作為行為型設計模式的重要一員,在處理對象間依賴關系與事件通知方面表現卓越。本文…

網絡原理 TCP/IP

1.應用層 1.1自定義協議 客戶端和服務器之間往往進行交互的是“結構化”數據,網絡傳輸的數據是“字符串”“二進制bit流”,約定協議的過程就是把結構化”數據轉成“字符串”或“二進制bit流”的過程. 序列化:把結構化”數據轉成“字符串”…

2025年5月HCIP題庫(帶解析)

某個ACL規則如下:則下列哪些IP地址可以被permit規則匹配: rule 5 permit ip source 10.0.2.0 0.0.254.255 A、10.0.4.5 B、10.0.5.6 C、10.0.6.7 D、10.0.2.1 試題答案:A;C;D 試題解析: 10.0.2.000001010.00000000.00000010.0000000…