61. UE5 RPG 實現敵人近戰攻擊技能和轉向攻擊

在前面,我們實現了敵人的AI系統,敵人可以根據自身的職業進行匹配對應的攻擊方式。比如近戰戰士會靠近目標后進行攻擊然后躲避目標的攻擊接著進行攻擊。我們實現了敵人的AI行為,但是現在還沒有實現需要釋放的技能,接下來,我們將實現敵人的使用的技能,剛好回顧一下之前的實現的功能。

首先基于之前的傷害技能基類,創建一個近戰技能基類
在這里插入圖片描述
命名為近戰技能 RPGMeleeAbility
在這里插入圖片描述
我們要實現技能的激活,需要使用到GameplayTag,所以我們增加一個新的技能標簽用于激活。
在RPGGameplayTags.h增加新的標簽

FGameplayTag Abilities_Attack; //攻擊技能激活標簽

然后將標簽添加到標簽管理器

	/** Abilities*/GameplayTags.Abilities_Attack = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Abilities.Attack"),FString("攻擊技能標簽"));

接下來,我們要實現在角色數據表里面配置它的技能,打開Character Class Info.h增加對應的屬性設置

//對應每個職業的屬性和技能
USTRUCT()
struct FCharacterClassDefaultInfo
{GENERATED_BODY()UPROPERTY(EditDefaultsOnly, Category="Class Defaults")TSubclassOf<UGameplayEffect> PrimaryAttributes;UPROPERTY(EditDefaultsOnly, Category="Class Defaults")TArray<TSubclassOf<UGameplayAbility>> StartupAbilities;
};

后面在UE的藍圖里面設置以后,我們可以在結構體內獲取需要應用的技能。接下來,我們還需要回憶一下如何應用敵人的技能的,我們是在敵人的基類里面,去實現的技能的應用,
在這里插入圖片描述
我們要擴展這個函數,增加傳入角色的類型,通過類型去獲取特定職業的技能。

	//初始化角色的技能UFUNCTION(BlueprintCallable, Category="MyAbilitySystemLibrary|CharacterClassDefaults")static void GiveStartupAbilities(const UObject* WorldContextObject, UAbilitySystemComponent* ASC, ECharacterClass CharacterClass);

擴展函數,從數據結構中獲取到數據并應用到角色的ASC上

void URPGAbilitySystemBlueprintLibrary::GiveStartupAbilities(const UObject* WorldContextObject, UAbilitySystemComponent* ASC, ECharacterClass CharacterClass)
{//從實例獲取到關卡角色的配置UCharacterClassInfo* CharacterClassInfo = GetCharacterClassInfo(WorldContextObject);if(CharacterClassInfo == nullptr) return;//從戰斗接口獲取到角色的等級ICombatInterface* CombatInterface = Cast<ICombatInterface>(ASC->GetAvatarActor());int32 CharacterLevel = 1;if(CombatInterface){CharacterLevel = CombatInterface->GetPlayerLevel();}//應用角色擁有的技能數組for(const TSubclassOf<UGameplayAbility> AbilityClass : CharacterClassInfo->CommonAbilities){FGameplayAbilitySpec AbilitySpec = FGameplayAbilitySpec(AbilityClass, CharacterLevel); //創建技能實例ASC->GiveAbility(AbilitySpec); //只應用不激活}//獲取到默認的基礎角色數據const FCharacterClassDefaultInfo ClassDefaultInfo = CharacterClassInfo->GetClassDefaultInfo(CharacterClass);//應用職業技能數組for(const TSubclassOf<UGameplayAbility> AbilityClass : ClassDefaultInfo.StartupAbilities){FGameplayAbilitySpec AbilitySpec = FGameplayAbilitySpec(AbilityClass, CharacterLevel); //創建技能實例ASC->GiveAbility(AbilitySpec); //只應用不激活}
}

敵人的角色類型也是設置在敵人基類上的,所以我們可以直接調用時傳入

	//初始化角色的技能if(HasAuthority()){URPGAbilitySystemBlueprintLibrary::GiveStartupAbilities(this, AbilitySystemComponent, CharacterClass);}

在UE中設置

接著我們可以編譯代碼打開UE,在UE里面創建一個對應的藍圖類
在這里插入圖片描述
命名為GA_GoblinSpearAttack
在這里插入圖片描述
首先設置技能標簽,我們就可以通過標簽激活技能。
在這里插入圖片描述
在技能里實現測試代碼,在觸發技能時,繪制一個綠色的球
在這里插入圖片描述
接著打開我們的數據表,現在每個職業多了一個需要設置的技能數組,將我們創建的技能添加給戰士
在這里插入圖片描述
攻擊是由AI觸發的,所以,我們在AI的攻擊任務中,通過標簽激活技能即可。我們從控制的pawn中獲取到ASC,然后通過標簽激活技能
在這里插入圖片描述
創建的變量我們可以將其設置外部可以設置
在這里插入圖片描述
然后再行為樹中設置激活的技能標簽
在這里插入圖片描述
接著運行測試效果,如果允許哥布林在攻擊時繪制綠色的球,證明我們技能激活成功。
在這里插入圖片描述

設置技能攻擊蒙太奇

回憶一下之前我們實現的火球術,需要使用一個蒙太奇動畫,然后在蒙太奇動畫中觸發事件發射火球實現技能的釋放。接下來,我們使用同樣的思路實現近戰攻擊的技能。
找到敵人的攻擊動畫,創建一個蒙太奇
在這里插入圖片描述
創建名稱AM_Attack_GoblinSpear,方便在蒙太奇下拉中選擇
在這里插入圖片描述
在蒙太奇中,我們需要增加MotionWarping來控制朝向,注意,動畫必須要支持根動畫
在這里插入圖片描述
設置角色在蓄力的時候轉向
在這里插入圖片描述
設置觸發名稱,關閉移動,只留下轉向,切換轉向類型為朝向目標
在這里插入圖片描述
我們有了蒙太奇,還需要實現在攻擊時朝向攻擊目標,按照之前的實現方式,我們通過MotionWarpping插件實現轉向。

添加轉向插件

我們需要在敵人基類身上增加MotionWarpping插件
在這里插入圖片描述
實現調用,和主角的一樣即可,其實這里我們可以實現一個角色基類藍圖,在里面設置一些通用的函數,這里先不改。
在這里插入圖片描述
要實現這個功能,我們需要讓敵人知道攻擊目標的位置,然后攻擊時朝向它,我們需要在AI控制器中獲取到目標。
我們在敵人接口里增加兩個函數,用于設置和獲取攻擊目標,這里設置了BlueprintNativeEvent,它默認給我們實現,并且可以在藍圖中實現此函數,如果在藍圖中實現了此函數,在藍圖中調用,將使用藍圖的版本。

	UFUNCTION(BlueprintCallable, BlueprintNativeEvent)void SetCombatTarget(AActor* InCombatTarget); //設置敵人的攻擊目標UFUNCTION(BlueprintCallable, BlueprintNativeEvent)AActor* GetCombatTarget() const; //獲取敵人的攻擊目標

接下來我們在敵人基類里面覆寫這兩個函數,并去實現,這樣寫法是因為我們是通過UE讓藍圖去實現的此函數,所以我們需要加上Vitrual和后面的_Implementation

	/* IEnemyInterface敵人接口 */virtual void HighlightActor() override; //高亮virtual void UnHighlightActor() override; //取消高亮virtual AActor* GetCombatTarget_Implementation() const override;virtual void SetCombatTarget_Implementation(AActor* InCombatTarget) override;/* IEnemyInterface敵人接口 結束 */

在cpp中實現這兩個函數,我們也可以在藍圖中實現,這里看個人喜好

AActor* ARPGEnemy::GetCombatTarget_Implementation() const
{return CombatTarget;
}void ARPGEnemy::SetCombatTarget_Implementation(AActor* InCombatTarget)
{CombatTarget = InCombatTarget;
}

有了設置攻擊目標的函數,我們在AI攻擊任務里面就可以設置攻擊對象了。
在任務里增加一個黑板鍵選擇器,用于在AI行為樹中設置綁定的黑板鍵
在這里插入圖片描述
在AI行為樹中設置攻擊目標為跟隨目標黑板鍵
在這里插入圖片描述
這樣我們就可以在任務里面獲取攻擊目標,并設置給控制的Pawn身上
在這里插入圖片描述
接下來,我們在技能里面,從角色身上獲取到攻擊目標,然后轉換為戰斗接口,調用偏轉朝向的函數,將朝向位置設置,然后再調用蒙太奇播放動畫
在這里插入圖片描述
接著允許查看效果,是否真的能捅向目標
在這里插入圖片描述

添加攻擊事件

接下來,我們需要在蒙太奇動畫里,攻擊的那一刻,觸發一個事件,來告訴技能當前可以計算攻擊。就像之前實現火球術時的一樣。
在這里插入圖片描述
由于我們沒有設置對應的通知,我們去標簽管理器增加一個近戰攻擊的通知標簽。由于這個標簽不需要在c++內使用,所以我們可以直接通過UE添加。
在這里插入圖片描述
設置屬于攻擊的近戰攻擊標簽
在這里插入圖片描述
設置完成,打開蒙太奇,設置到通知上面,這樣就可以在技能里面去接收對應的標簽通知了。
在這里插入圖片描述
然后我們在技能中設置等待游戲事件即可,Only Match Exact是標簽必須全部匹配才可以觸發事件
在這里插入圖片描述
現在我們接收到事件了,還需要考慮如何觸發攻擊。在之前實現火球從法杖杖尖處釋放時,我們在戰斗接口設置了一個獲取技能釋放位置的函數,所以我們可以通過獲取到設置的位置,生成一個碰撞球體,判斷是否和目標產生重疊實現攻擊并應用GE。
在這里插入圖片描述
但是當前函數無法在藍圖中調用,所以,我們需要修改它,將其變成可以在藍圖中調用的版本

	//獲取技能釋放位置,通過在藍圖中設置獲取WeaponTipSocketName的位置UFUNCTION(BlueprintNativeEvent, BlueprintCallable)FVector GetCombatSocketLocation() const;

并將cpp的實現刪除。

在角色基類修改它的繼承,修改成GetCombatSocketLocation_Implementation

virtual FVector GetCombatSocketLocation_Implementation() const override;

并將實現代碼函數名稱也修改掉

FVector ARPGCharacter::GetCombatSocketLocation_Implementation() const
{return Weapon->GetSocketLocation(WeaponTipSocketName);
}

完成以后,就可以編譯打開UE,并設置它的WeaponTipSocketName
在這里插入圖片描述
這里名稱,我們可以在武器骨骼上面增加插槽實現
在這里插入圖片描述
接著在技能藍圖里,我們首先實現接收到事件后繪制一個調試球體,來表現攻擊范圍
在這里插入圖片描述
運行查看釋放能夠正確繪制出調試球體
在這里插入圖片描述
我們在點擊實現角色攻擊時,發現一個問題,有個地方報錯了,提示我們不要在接口中直接調用Event函數。而是調用Execute_GetCombatSocketLocation。
在這里插入圖片描述
往前定位發現是在調用,直接調用獲取位置,由于前面我們將其修改成了藍圖編譯生成函數,所以在C++里面不能夠直接調用
在這里插入圖片描述
所以我們修改此行代碼為使用Execute_GetCombatSocketLocation調用

const FVector SocketLocation = ICombatInterface::Execute_GetCombatSocketLocation(GetAvatarActorFromActorInfo());

接著運行測試就行了。

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

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

相關文章

HTML5 音頻 Audio 標簽詳解

HTML5 引入了 <audio> 標簽&#xff0c;允許開發者在網頁中直接嵌入音頻文件&#xff0c;而不需要依賴第三方插件。本文將全面介紹 <audio> 標簽的各種屬性&#xff0c;并通過實例代碼詳細說明其用法。 一、基礎用法 1. 基本結構 HTML5 中使用 <audio> 標…

通過定時器和脈沖控制LED

目錄 一、定時器 &#xff08;一&#xff09;定時器簡介 &#xff08;二&#xff09;定時器類型 1、常見定時器 2、定時器的主要功能 3、常規定時器 &#xff08;三&#xff09;定時器配置 1、定時器標準外設庫接口函數 2、定時器標準外設庫配置 二、PWM &#xff08…

匿名函數(lambda)

自學python如何成為大佬(目錄):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 匿名函數是指沒有名字的函數&#xff0c;應用在需要一個函數&#xff0c;但是又不想費神去命名這個函數的場合。通常情況下&#xff0c;這樣的函數只…

【Qt】Qt界面美化指南:深入理解QSS樣式表的應用與實踐

文章目錄 前言&#xff1a;1. 背景介紹2. 基本語法3. QSS 設置方式3.1. 設置全局樣式3.2. 從文件加載樣式表3.3. 使用 Qt Designer 編輯樣式 總結&#xff1a; 前言&#xff1a; 在當今這個視覺至上的時代&#xff0c;用戶界面&#xff08;UI&#xff09;的設計對于任何軟件產…

智能制造案例專題|與MongoDB一起解鎖工業4.0轉型與增長的無限潛力!

MongoDB 智能制造 數字化技術的洪流在各個產業鏈的主干和枝節涌現。在工業制造領域&#xff0c;能否通過數字化技術實現各生產要素、生產環節之間的緊密配合&#xff0c;高效規劃、管理整個生產流程&#xff0c;是企業提升韌性、贏得競爭的關鍵。隨著工業4.0的深入發展和智能…

高級Java開發者的自我修養:深入剖析JVM垃圾回收機制及面試要點

在探索Java虛擬機&#xff08;JVM&#xff09;的奧秘過程中&#xff0c;垃圾回收機制&#xff08;GC&#xff09;是一個不可或缺的話題&#xff0c;尤其在面對大型應用和系統優化時顯得尤為重要。JVM的自動內存管理是Java編程語言中一項革命性的特性&#xff0c;它大大簡化了程…

測試記錄2:Ubuntu工程直接添加使用Eigen3源文件

直接將Eigen3源文件放入到工程目錄下使用&#xff0c;免安裝 1.新建空文件夾Test_eigen 2.創建將eigen下載的文件夾解壓&#xff0c;重命名為eigen3放入到Test_eigen 3.進入Test_eigen&#xff0c;創建main.cpp #include <iostream> #include <Eigen/Eigen>int m…

AI盒子在智慧加油站的應用

方案背景 為規范加油站作業&#xff0c;保障人民生命財產安全&#xff0c;《加油站作業安全規范》&#xff08;AQ 3010-2007&#xff09;中第五條規定&#xff1a;卸油作業基本要求&#xff0c;明確防靜電、防雷電、防火、人員值守、禁止其他車輛及非工作人員進入卸油區。 痛點…

數據結構基礎篇(4)

十六.循環鏈表 概念 循環鏈表是一種頭尾相接的鏈表&#xff08;最后一個結點的指針域指向頭結點&#xff0c;整個鏈表形成一個環&#xff09;優點 從表任一結點出發均可找到表中其他結點判斷終止 由于循環鏈表中沒有NULL指針&#xff0c;所以涉及遍歷操作時&#xff0c;終止條…

RocketMQ學習(2) 深入學習

RokcetMQ的介紹和基礎知識見這篇博客——RocketMQ學習(1) 快速入門 本篇為上一篇的深入學習&#xff0c;很多基礎知識不再贅述。 目錄 消息重復消費問題(去重;冪等)布隆過濾器 重試機制死信消息 SpringBoot集成RocketMQ集成SpringBoot發送不同消息模式(同步消息)異步消息單向消…

python下載指定URL的文件

import requests # 圖片的URL地址 url https://book.pep.com.cn/1212001402143/files/mobile/1.jpg?240301113921 # 發送HTTP GET請求 response requests.get(url) # 檢查請求是否成功 if response.status_code 200: # 打開一個文件用于寫入 with open(download…

實習碰到的問題w1

1.vueelementUI在輸入框中按回車鍵會刷新頁面 當一個 form 元素中只有一個輸入框時&#xff0c;在該輸入框中按下回車應提交該表單。如果希望阻止這一默認 行為&#xff0c;可以在 <el-form> 標簽上添加 submit.native.prevent 。 參考&#xff1a;element-ui 表單 form …

使用el-tab,el-tab-pane循環使用循環后不顯示下劃線問題

在vue項目中使用element-UI el-tab里的el-tab-pane是循環出來的&#xff0c;但是循環出來后選中tab不顯示下劃線了 文章目錄 問題問題展示效果問題代碼問題原因 解決方案解決后效果解決方案1代碼 解決方案2代碼 問題 問題展示效果 問題代碼 <el-tabs v-model"activeNa…

音量的對數表示與浮點數表示

音量用浮點數&#xff08;float&#xff09;和對數&#xff08;logarithmic scale&#xff09;表示各有特點和應用場景 浮點數&#xff1a;直接使用線性刻度表示音量&#xff0c;例如在0.0&#xff08;最小音量&#xff09;到1.0&#xff08;最大音量&#xff09;的范圍內。對…

『 Linux 』緩沖區(萬字)

文章目錄 &#x1f9a6; 什么是緩沖區&#x1f9a6; 格式化輸入/輸出&#x1f9a6; 刷新策略&#x1fab6; 塊緩沖(fully buffered)&#x1fab6; 無緩沖(unbuffered)&#x1fab6; 行緩沖(line buffered) &#x1f9a6; 現象解釋&#x1f9a6; exit()與_exit()&#x1f9a6; 進…

list 的實現

目錄 list 結點類 結點類的構造函數 list的尾插尾刪 list的頭插頭刪 迭代器 運算符重載 --運算符重載 和! 運算符重載 * 和 -> 運算符重載 list 的insert list的erase list list實際上是一個帶頭雙向循環鏈表,要實現list,則首先需要實現一個結點類,而一個結點需要…

【代碼隨想錄——回溯算法——四周目】

1.重新安排行程 1.1 我的代碼&#xff0c;超時通不過 var (used []boolpath []stringres []stringisFind bool )func findItinerary(tickets [][]string) []string {sortTickets(tickets)res make([]string, len(tickets)1)path make([]string, 0)used make([]bool,…

JSON Web Token

JWT 什么是JWT JWT&#xff08;JSON Web Token&#xff09;是一種用于在各方之間作為JSON對象安全地傳輸信息的開放標準&#xff08;RFC 7519&#xff09;。該信息經過數字簽名&#xff0c;因此是可驗證和可信的。JWT 可以使用HMAC算法或使用RSA的公鑰/私鑰對進行簽名 JWT的…

微信小程序 vant Picker組件default-index不生效的解決辦法

1、原始的寫法以及問題 <van-popup show"{{ showPopup && cellClick Freq }}" position"bottom" bind:close"onPopupClose"><van-picker value-key"Spec" show-toolbar title"{{cellClick Freq ? showPcCha…

win10鍵盤按亂了,如何恢復?

今天鍵盤被寶寶給按亂了&#xff0c;好不容易給重新調整回來&#xff0c;記錄備忘&#xff1a; 1、win10的asdf和方向鍵互換了&#xff1a; 使用Fnw鍵來回切換&#xff0c;OK&#xff01; 2、鍵盤的win鍵失效&#xff0c;例如&#xff1a;按winD無法顯示桌面。此時&#xf…