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

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

Unity ECS實(shí)現(xiàn)RTS游戲中的游戲單位框選、集結(jié)和移動(dòng)控制

2022-09-02 16:17 作者:獨(dú)立游戲人-老雷  | 我要投稿

今天想給大家分享的主題是如何實(shí)現(xiàn)RTS類型游戲中的游戲單位角色控制

本文中會(huì)介紹如何運(yùn)用最新的ECS架構(gòu)來(lái)實(shí)現(xiàn)游戲單位控制

版權(quán)聲明

  • 本文為“優(yōu)夢(mèng)創(chuàng)客”原創(chuàng)文章,您可以自由轉(zhuǎn)載,但必須加入完整的版權(quán)聲明

  • 更多學(xué)習(xí)資源請(qǐng)加QQ:1517069595或WX:alice17173獲取(企業(yè)級(jí)性能優(yōu)化/熱更新/Shader特效/服務(wù)器/商業(yè)項(xiàng)目實(shí)戰(zhàn)/每周直播/一對(duì)一指導(dǎo))

  • 點(diǎn)贊、關(guān)注、分享可免費(fèi)獲得配套學(xué)習(xí)資源

  • 詳細(xì)內(nèi)容可參考文末完整視頻

效果演示


效果實(shí)現(xiàn)

選中多個(gè)游戲單位

  • 上方代碼實(shí)現(xiàn)的功能是獲取被鼠標(biāo)框選的游戲單位,如果需要源代碼可以在文末添加愛(ài)麗絲老師的QQ或者微信號(hào)領(lǐng)取

  • 代碼講解

  • 獲取鼠標(biāo)框選方框的左下角和右上角

  • 鼠標(biāo)在按下和彈起的過(guò)程中畫出的方框一般存在兩種情況

    • 鼠標(biāo)的起始位置對(duì)應(yīng)左下角,終止位置對(duì)應(yīng)右上角

    • 鼠標(biāo)按下時(shí)的起始位置是右上角,終止位置則是左下角

  • 在計(jì)算方框的起始位置為右上角,終止位置為左下角時(shí)不能直接用起始位置當(dāng)方框的左下角,要把終止位置當(dāng)做方框左下角的位置

  • 想要統(tǒng)一的獲得左下角和右上角的位置需要寫一些算法,如上方代碼所示,這個(gè)算法很簡(jiǎn)單,就是比較起始位置和終止位置,取較小值作為左下角點(diǎn),然后用兩者的較大值作為右上角點(diǎn)

  • 查找被選中的游戲?qū)嶓w

  • ForEach方法的作用是遍歷每一個(gè)游戲單位,后面的Lambda表達(dá)式的功能是判斷游戲單位的位置坐標(biāo)是否在鼠標(biāo)框選范圍內(nèi),并打印鼠標(biāo)范圍框選范圍內(nèi)的游戲單位

繪制選區(qū)

  • 在場(chǎng)景中創(chuàng)建一個(gè)空節(jié)點(diǎn),起名為SelectionArea(選擇區(qū)域),再創(chuàng)建一個(gè)空子節(jié)點(diǎn),取名為Sprite(精靈節(jié)點(diǎn))

  • 為精靈節(jié)點(diǎn)添加精靈渲染器,并選擇一張綠色的圖片(把白色圖片設(shè)置成綠色也可以)

  • 這里需要注意一下這張圖片的大小

  • 我們?yōu)檫@張圖片設(shè)置了0.5的偏移值,這是什么意思呢?

  • 也就是說(shuō)SelectionArea(選擇區(qū)域)節(jié)點(diǎn)和Sprite(精靈)節(jié)點(diǎn)的位置關(guān)系變成了上圖的樣子,上圖中紅色坐標(biāo)軸的原點(diǎn)就是SelectionArea(選擇區(qū)域)節(jié)點(diǎn)的位置,藍(lán)色坐標(biāo)軸的原點(diǎn)則代表Sprite(精靈)節(jié)點(diǎn)的位置,這樣偏移以后,將來(lái)拖拽、縮放選框時(shí)就會(huì)以紅顏色的中心點(diǎn)為起點(diǎn),會(huì)比較方便

  • 在代碼中實(shí)現(xiàn)動(dòng)態(tài)繪制選框


  • 注意

    • SelectionArea節(jié)點(diǎn)被添加到總控腳本ECS_RTSControls里了,所以在上方代碼中是通過(guò)訪問(wèn)總控腳本的單例來(lái)獲取SelectionArea節(jié)點(diǎn)

  • 此腳本是在之前的UnitControlSystem腳本上增加了一個(gè)類和一些代碼

    • 這些代碼會(huì)在鼠標(biāo)按下時(shí)激活SelectionArea節(jié)點(diǎn),并將SelectionArea節(jié)點(diǎn)的位置設(shè)置為鼠標(biāo)按下的位置

    • 在鼠標(biāo)拖拽過(guò)程中會(huì)不斷獲取鼠標(biāo)當(dāng)前位置,并用鼠標(biāo)當(dāng)前為減去鼠標(biāo)初始位置,以得到當(dāng)前鼠標(biāo)框選的選區(qū)大小,然后賦值給selectionArea的localScale,這樣就實(shí)現(xiàn)了selectionArea選區(qū)隨著鼠標(biāo)拖拽自動(dòng)改變大小的效果

    • 最后在鼠標(biāo)抬起時(shí)會(huì)將selectionArea的SetActive設(shè)置為false,隱藏鼠標(biāo)選區(qū),并為被選中的游戲?qū)ο筇砑覷nitSelected結(jié)構(gòu)體

  • 效果演示

繪制角色腳下的圓圈

  • 注意

    • 用于繪制角色腳下圓圈的材質(zhì)被添加到總控腳本ECS_RTSControls里了,所以在上方代碼中是通過(guò)訪問(wèn)總控腳本的單例來(lái)獲取的圓圈的材質(zhì)的

    • 圓圈的網(wǎng)格模型則是在ECS_RTSControls調(diào)用Unity動(dòng)畫的創(chuàng)建網(wǎng)格方法動(dòng)態(tài)創(chuàng)建的,所以也通過(guò)ECS_RTSControls的單例獲取

  • unitSelectedCircleMaterial(角色選中材質(zhì))

如果需要項(xiàng)目源碼或資源可以在文末通過(guò)添加愛(ài)麗絲老師的QQ獲取

  • 效果演示

  • 問(wèn)題

    • 問(wèn)題1:無(wú)法取消選中

      • 上面的代碼在選中了左邊的角色后,點(diǎn)擊空處或再次選中其他角色時(shí)并不會(huì)取消之前被選中角色的選中狀態(tài),為了要解決這個(gè)問(wèn)題我們添加了幾行代碼,讓UnitControlSystem腳本在鼠標(biāo)彈起時(shí)遍歷所有游戲?qū)ο?,刪除它們身上的UnitSelected組件

  • 問(wèn)題2:無(wú)法通過(guò)點(diǎn)擊選中游戲?qū)ο?br>

    • 上面代碼實(shí)現(xiàn)的選中效果必須要把游戲?qū)ο笳w框入才能選中,但在RTS游戲里,游戲玩家對(duì)于單個(gè)游戲?qū)ο笫强梢酝ㄟ^(guò)點(diǎn)擊選中的,而且框選也很麻煩,那怎樣才能讓它可以點(diǎn)中選中一個(gè)對(duì)象呢?方法很簡(jiǎn)單

    • 就是擴(kuò)大最小選區(qū),選擇區(qū)域在點(diǎn)擊時(shí)自動(dòng)擴(kuò)大一圈,這樣就能確保點(diǎn)擊選中單個(gè)角色

  • 注意:

    • 這些代碼會(huì)在鼠標(biāo)抬起時(shí)執(zhí)行,它會(huì)檢測(cè)當(dāng)前鼠標(biāo)選區(qū)大小是否小于鼠標(biāo)選區(qū)最小值,如果小于則會(huì)根據(jù)鼠標(biāo)選區(qū)最小值減去當(dāng)前鼠標(biāo)選區(qū)大小的值放大鼠標(biāo)選區(qū)

  • 這樣就保證了最小區(qū)域是足夠大的,可以通過(guò)點(diǎn)擊選中游戲單位

讓游戲?qū)ο笙蛑付ǖ姆较蛞苿?dòng)

  • 注意:

    • 這段代碼會(huì)在鼠標(biāo)右鍵抬起時(shí)執(zhí)行,它會(huì)為所有被選中的游戲?qū)ο笤O(shè)置移動(dòng)目標(biāo)點(diǎn),并使游戲?qū)ο笙蚰繕?biāo)點(diǎn)移動(dòng)

    • MoveTo是一個(gè)移動(dòng)腳本,MoveTo的position代表游戲角色移動(dòng)的目標(biāo)點(diǎn),move代表是否開(kāi)始移動(dòng),如果需要完整的ECS源碼資源,可以在添加愛(ài)麗絲老師領(lǐng)取

  • 效果演示

實(shí)現(xiàn)游戲單位按陣列移動(dòng)

  • 上面實(shí)現(xiàn)的效果還有一個(gè)問(wèn)題存在

  • 可以看到上面的兩個(gè)角色變成一個(gè)了,因?yàn)槿绻麄兊囊苿?dòng)目標(biāo)點(diǎn)是相同的,所以這兩個(gè)角色在移動(dòng)時(shí)就會(huì)重疊起來(lái)

  • 上面代碼中的movePositionList是游戲單位的移動(dòng)位置列表,當(dāng)鼠標(biāo)右鍵按下設(shè)置目標(biāo)點(diǎn)時(shí),這段代碼會(huì)遍歷所有被選中的游戲單位,并使用positionIndex(位置索引)取出移動(dòng)位置列表里計(jì)算好的移動(dòng)位置,讓這些游戲單位的移動(dòng)位置都不一樣

  • 效果演示

  • 可以看到被選中的游戲單位朝著同一個(gè)目標(biāo)點(diǎn)移動(dòng),并且位置都各不相同,這是因?yàn)槟繕?biāo)點(diǎn)在movePositionList經(jīng)過(guò)處理后,產(chǎn)生四個(gè)位置不同的坐標(biāo)點(diǎn),這樣賦值給游戲單位的就是位置不同的坐標(biāo)點(diǎn)了

  • 這段代碼的問(wèn)題也很明顯:當(dāng)玩家選中四個(gè)以上的游戲單位進(jìn)行移動(dòng)時(shí),仍然會(huì)產(chǎn)生重疊現(xiàn)象

    • 這是因?yàn)閙ovePositionList里的元素只有四個(gè),當(dāng)這段代碼遍歷完所有元素時(shí),就會(huì)從movePositionList的起始位置重新遍歷,所以多出來(lái)的游戲單位位置會(huì)與其他游戲單位重疊

  • 解決這個(gè)問(wèn)題最簡(jiǎn)單的方法就是增加movePositionList里的元素個(gè)數(shù),讓元素個(gè)數(shù)始終大于游戲單位個(gè)數(shù),這個(gè)問(wèn)題自然迎刃而解

  • 不過(guò)在一些游戲單位數(shù)量動(dòng)輒就是幾十、幾百上下的RTS游戲中,這種方法就不夠看了,需要用另一種方法

  • 上面的GetPositionListAround會(huì)返回一個(gè)位置列表,位置列表里的所有元素都會(huì)以該方法的position參數(shù)為圓心,distance為半徑呈圓形排列(如下圖),這些元素的數(shù)量就是positionCount

  • ApplyRotationToVector的作用則是通過(guò)傳入的角度(angle)來(lái)構(gòu)造旋轉(zhuǎn)值,并使用這個(gè)旋轉(zhuǎn)值旋轉(zhuǎn)向量(vec),旋轉(zhuǎn)到了angle所代表的角度,這個(gè)方法背后的數(shù)學(xué)原理,本文就不去細(xì)講了,因?yàn)閮?nèi)容很多,如果想要學(xué)習(xí)這方面的知識(shí),可以在文末添加愛(ài)麗絲老師了解

  • 對(duì)之前的代碼進(jìn)行修改,使用GetPositionListAround生產(chǎn)位置列表

  • 效果演示

  • 由于在上面的代碼中GetPositionListAround只指定了5個(gè)元素?cái)?shù)量,所以重疊的現(xiàn)象依然存在,代碼還需要繼續(xù)改進(jìn)

  • 最上方的GetPositionListAround是對(duì)之前寫的GetPositionListAround的改進(jìn),可以讓小兵的位置分布成幾個(gè)圓環(huán)(如下圖所示)

  • 新的GetPositionListAround方法的第一個(gè)參數(shù)startPosition仍然代表圓環(huán)中心點(diǎn)的位置,第二個(gè)參數(shù)ringDistance是半徑數(shù)組,用于存放所有圓環(huán)的半徑,第三個(gè)參數(shù)ringPositionCount代表每一個(gè)圓環(huán)上的位置點(diǎn)數(shù)量

  • 效果演示

思考練習(xí)

  1. 實(shí)現(xiàn)不受位置點(diǎn)數(shù)量限制,為每一個(gè)游戲單位生成不與其他單位重疊的位置點(diǎn)(因?yàn)橹灰”鴶?shù)量超過(guò)上面代碼中設(shè)置的位置點(diǎn)總數(shù),還是會(huì)有游戲單位重疊現(xiàn)象)

  2. 兵種遇到障礙能否實(shí)現(xiàn)游戲單位躲避障礙行走到目標(biāo)點(diǎn)(A*,ECS實(shí)現(xiàn))

寫在最后

  • 更多學(xué)習(xí)資源請(qǐng)加QQ:1517069595或WX:alice17173獲取(企業(yè)級(jí)性能優(yōu)化/熱更新/Shader特效/服務(wù)器/商業(yè)項(xiàng)目實(shí)戰(zhàn)/每周直播/一對(duì)一指導(dǎo))

  • 點(diǎn)贊、關(guān)注、分享可免費(fèi)獲得配套學(xué)習(xí)資源

  • 詳細(xì)內(nèi)容可觀看下方完整視頻


Unity ECS實(shí)現(xiàn)RTS游戲中的游戲單位框選、集結(jié)和移動(dòng)控制的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
枣庄市| 军事| 青河县| 调兵山市| 西丰县| 连山| 克什克腾旗| 思南县| 宁乡县| 通州区| 安图县| 大连市| 团风县| 丰城市| 信宜市| 泸定县| 京山县| 从化市| 龙陵县| 和平区| 冷水江市| 方正县| 澎湖县| 花莲县| 江津市| 明水县| 宝应县| 文登市| 普兰县| 繁峙县| 清镇市| 齐齐哈尔市| 玛曲县| 木兰县| 新余市| 交口县| 黄大仙区| 深水埗区| 涞水县| 慈溪市| 贵南县|