最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

從零開始獨立游戲開發(fā)學(xué)習筆記31--Unity學(xué)習筆記14--M_Studio 3DRPG教程 2 - 結(jié)束

2022-04-25 19:22 作者:oyishyi  | 我要投稿

哎,說真的,我真的很不想連續(xù)兩篇都戛然而止,搞得好像我很容易放棄一樣。但是不得不說這教程真的不適合我。(我其實想說的更狠點,但還是算了)。學(xué)的時候真的一鍋子火,太強行了。一個功能有他自己適合的用處,而不是用在毫不相關(guān)的地方告訴你還可以這么用,這樣是能做,可是有什么意義。

舉一反三,舉一反三,一都沒舉就直接給你反三,還把這三當成一來用,太難受了。我中間查閱了一大堆手冊。每次手冊上的官方例子都在打視頻的臉,我真的看不下去了。真想把當初找教程的我打一嘴巴子。

算了算了,也不是說教程多不好。只是不適合我,既有優(yōu)點也有缺點,我下面也分析了一下。大家看著辦吧。

-------以下是正文---------
學(xué)著學(xué)著逐漸開始意識到 M_Studio 的教程并不算很好。優(yōu)點在于有一套完整的流程,并給你介紹每一個功能,盡量面面俱到。缺點在于功能介紹的很淺顯,并且經(jīng)常為了介紹而強行做某個功能,代碼寫的也不行。

相比之下,國外教程的優(yōu)點在于功能介紹會附帶理論比較深入一些,代碼質(zhì)量也不錯。但是缺點在于要么就是完全分散的知識點,要么就是非常短的一個流程。

或者再極端點,官方手冊,真的完全分散,但是絕對正確。

1. 鼠標控制人物移動

1.1 mouseManager

鼠標作為之后將要經(jīng)常用到的操作(鼠標控制移動,控制攻擊等等),作者選擇在這里使用 mouseManager 來控制。

mouseManager 并不是 unity 自帶的某個東西和定義,而是完全由我們自己創(chuàng)建的一個控制器:創(chuàng)建腳本,再創(chuàng)建一個物體,將腳本掛載到物體上。所謂的 mouseManager 只是作者自己的一個命名而已,完全可命名為 mouseController 或者 cameraController 等,只要看得懂,隨你喜歡。

這里作者沒有講,因此我試圖自己理解:沒有選擇直接掛在 player 上,而是選擇掛載在一個單獨的空物體上,是因為鼠標并不只是控制對人物的移動,還包括其他和人物不相關(guān)的操作。

1.1.1 事件


假設(shè)我們要做鼠標移動,那么可以想象成這么一個過程。鼠標點擊觸發(fā)事件 -> 人物移動。還記得之前做 UI 的時候使用的 UI button 里面自帶的 on click 事件嗎,那里需要你綁定一個 object,然后選一個這個 object 里的方法,到時候觸發(fā)就會調(diào)用這個方法。事件就是這么個東西。

那么現(xiàn)在我們沒有 UI button 配置好的事件屬性,而是一個空物體,我們要如何使用事件呢?
可以想象,應(yīng)該會有一個類似的一個有參數(shù)的屬性或者方法,暴露出來后,在 unity 編輯器里看就會像是 UI button 顯示的那個樣子。

  1. 首先我們要引入事件類的 namespace,叫做 UnityEngine.Events。

  2. 新建一個繼承 UnityEvent 的類,因為我們要使用參數(shù)。


3. 代碼解釋:UnityEvent 后面跟著的是之后這個監(jiān)聽函數(shù)要使用的參數(shù),參數(shù)最多可以有 4 個,比如說?UnityEvent<int, Vecctor2, string, Vecctor3>?這樣。然后創(chuàng)建的類繼承這個類,像是例子中的 EventVector 是一個很好的名字,這樣更容易區(qū)分類型。(注意,不要起類似 EventClick 這種代表動作的名字,因為這只是個類,以后所有只接收一個 Vector3 參數(shù)的事件都可以用這個類,并不一定是 click 相關(guān)。只有之后新建變量的時候才會起和動作相關(guān)的名字,而且命名方式也不是什么 eventClick,也應(yīng)該是 onMouseClick 這種命名習慣。)(至于 eventMove 這種命名就更偏了,正確命名和用法應(yīng)該是:繼承了 EventVector3 的 onMouseClick 事件變量綁定一個叫做 move 的方法)。
4. 既然創(chuàng)建了這么一個類,接下來就是在 MouseManager 類里新建這個類型的變量,這樣我們就可以在 inspector 里看到了。

5. 上面說的和真的一樣,但是其實并沒有看到。
6. 原因是數(shù)據(jù)格式問題,像是一些 int,string,gameObject 類型等確實可以被 unity 編輯器序列化并顯示在 inspector 中。但是很可惜,unity 無法序列化泛型。而我們通過繼承創(chuàng)建的類型又是高度自定義的(幾乎有無限種參數(shù)組合的可能性)。因此需要我們手動序列化使其起作用。
7. 解決方法是在前面加上?[System.Serializable]。

1.1.2 綁定鼠標點擊動作


雖然我們起了個名字叫做 onMouseClick,但這只是個名字,我們要真正的把它和鼠標點擊的動作聯(lián)系起來。

1.1.2.1 Camera.ScreenPointToRay

顧名思義,這個方法的作用就是把屏幕點轉(zhuǎn)化成射線。

具體含義就是,把屏幕上的某個點的位置(也就是一個 2 維的坐標),轉(zhuǎn)化成從攝像機射到這個點的位置的射線。具體到游戲中就是,你點了某個地方,然后 unity 會自動計算你在屏幕上點的這個地方,對應(yīng)在游戲中的三維坐標系的位置,然后從攝像機發(fā)射一條射線到這個位置,把射線返回給你。

可以在 unity 手冊里找到這個方法,不過基本上是不說人話的。但理解了大概意思后可以在手冊里找到一些細節(jié),比如說它是怎么判斷你點的是哪個物體的

1.1.2.1.1 global rotation vs local rotation4

題外話,去 scene 里看一下,選取 camera,調(diào)整左上角的 global 為 local。意思是工具調(diào)整的坐標系的角度是什么樣的,下面兩張圖可以直觀看到區(qū)別:

上圖人都埋進土里了,平移工具還是一如既往保持和世界坐標一致。下圖則是會根據(jù)人物的旋轉(zhuǎn)改變角度。

1.1.2.1.2 繼續(xù)之前的話題

這個方法雖然好,不過依然要你去提供屏幕點,并不能讀取鼠標點擊的位置。所以我們要通過 Input 給參數(shù)。

看文檔可以知道這個方法返回一個 Ray 類型,因此我們創(chuàng)建一個變量來儲存。

  1. 私有變量命名使用 _ 前綴更容易區(qū)分。

  2. Camera.main 獲取當前場景中被 tag 為 MainCamera 的攝像機。

  3. 雖然老師說直接在 update 里使用 MainCamera 的性能在 2020 版本后被優(yōu)化過,但在 tarodev(ytb 上的一個頻道) 的測試下緩存的速度依然要比不緩存快很多。

  4. 使用 Input.mousePosition 獲取鼠標位置。

1.1.2.2 Phsics.Raycast

不過射線只是射線,這條射線只是單純從攝像機到你點的地方之間的一條線。但是實際上我們還需要知道這條線上有沒有什么障礙物。想要獲取碰撞物體的信息,就要使用物理方法。

那么這里使用 Phsics.Raycast 方法(看文檔記得往下翻,有重載): 找到一種一個重載接受 ray 參數(shù),并且有一個 out 修飾的 RaycastHit 類型的參數(shù)(RaycastHit 查看文檔可以看到包含很多碰撞相關(guān)的信息),我們就使用這個:

  1. out 修飾符作用可以查文檔,總之就是讓其變成引用傳遞,可以被修改。感覺是一個類似指針的概念。

  2. 需要提前創(chuàng)建一個 Raycast 變量,作為參數(shù)來儲存信息。

  3. 方法調(diào)用的時候也要使用 out 修飾。

1.1.2.3 鼠標點擊

剛剛雖然在 if 里沒有放代碼,但是 Phsics.Raycast 執(zhí)行了,就會更改 _hitInfo 的信息。

此外,剛剛做的事情,是在每幀的時候,讀取鼠標位置信息并拿到碰撞體的信息。不過我們其實沒必要每一幀的信息都要。我們只是想在鼠標點擊的時候需要。那么為什么剛剛要這么做呢,其實這是為了后面改變鼠標樣式的時候需要(也就是在鼠標移到不同物體上,會變成不同的樣子來告訴你這個物體是可以互動的)。

這就是為什么我們把 _hitinfo 放在外面,因為這樣我們鼠標點擊的時候就可以直接讀取 _hitinfo 了。 新建一個 函數(shù),用于處理之后的鼠標操作。

  1. GetMouseButtonDown 的參數(shù),0 指的是鼠標左鍵。

  2. 如果射線沒有碰撞,則 this._hitInfo.collider 返回 null。

  3. 這里檢測如果碰撞到的是地面,就會 invoke OnMouseClick 事件。

  4. ?. 這個語法表明,只有前面不為空的時候才會進行后面的調(diào)用或者取值,這樣避免了事先判斷一次空值。可以參考文檔。

  5. 這里代碼的含義是,每當點擊并且碰撞體為地面的時候,執(zhí)行一次 OnMouseClick,參數(shù)為碰撞點。

然后我們回到 Unity Editor,添加一個事件,屬性設(shè)置為 NavMeshAgent.destination,NavMeshAgent 是下載素材自帶的一個組件,也可以手動添加??吹?Nav 就大概明白這個和上一篇文章中的 Navigation 自動導(dǎo)航相關(guān)。而 destination 也顧名思義就是目的點。這里我們設(shè)置后,每次鼠標點擊的時候,就會執(zhí)行 NavMeshAgent.destination,不過由于 destination 是一個屬性不是方法,所以此時 unity 執(zhí)行的操作為將 destination 設(shè)置成 this._hitInfo.point 的值,然后自動導(dǎo)航系統(tǒng)就會把人物移動到對應(yīng)位置。

2. 換教程

見前言。我是真的不理解為什么要用事件來做點擊。


從零開始獨立游戲開發(fā)學(xué)習筆記31--Unity學(xué)習筆記14--M_Studio 3DRPG教程 2 - 結(jié)束的評論 (共 條)

分享到微博請遵守國家法律
胶南市| 麦盖提县| 东山县| 木里| 阳原县| 板桥市| 铜陵市| 三原县| 广饶县| 库伦旗| 新乐市| 镇康县| 成武县| 莱阳市| 高台县| 如皋市| 大庆市| 遂宁市| 信宜市| 岗巴县| 长宁县| 浪卡子县| 青海省| 聂荣县| 增城市| 石阡县| 宁明县| 石楼县| 邓州市| 赤城县| 阿拉善右旗| 成安县| 湖口县| 浑源县| 舞阳县| 普宁市| 襄城县| 金川县| 沽源县| 昭苏县| 武乡县|