116. UE5 GAS RPG 實現擊殺掉落戰利品功能

這一篇,我們實現敵人被擊敗后,掉落戰利品的功能。首先,我們將創建一個新的結構體,用于定義掉落體的內容,方便我們設置掉落物。然后,我們實現敵人死亡時的掉落函數,并在藍圖里實現對應的邏輯,在場景里生成掉落物。最后,讓掉落物動起來,顯得掉落物需要玩家趕緊去拾取的感覺。

添加新的資產結構體

為了實現對敵人掉落戰利品的配置,我們需要創建一個新的類,作為配置掉落物的新的資產類。
在這里插入圖片描述
命名為戰利品類
在這里插入圖片描述
在類里,我們首先添加一個結構體,用于設置一種物品的掉落內容和幾率。

USTRUCT(BlueprintType)
struct FLootItem
{GENERATED_BODY()//戰利品在場景中的顯示效果UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="LootTiers|Spawning")TSubclassOf<AActor> LootClass;//戰利品生成幾率UPROPERTY(EditAnywhere, Category="LootTiers|Spawning")float ChanceToSpawn = 0.f;//物品生成的最大數量UPROPERTY(EditAnywhere, Category="LootTiers|Spawning")int32 MaxNumberToSpawn = 0.f;//修改物品生成等級,false則使用敵人等級UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="LootTiers|Spawning")bool bLootLevelOverride = true;
};

然后在類里,我們增加一個數組,開發者可以配置多個掉落物,然后添加一個函數,用于獲取當前可以生成的戰利品數組。

UCLASS()
class RPG_API ULootTiers : public UDataAsset
{GENERATED_BODY()public://獲取需要生成的戰利品數據UFUNCTION(BlueprintCallable)TArray<FLootItem> GetLootItems();UPROPERTY(EditDefaultsOnly, Category="LootTiers|Spawning")TArray<FLootItem> LootItems;
};

在函數實現這里,我們創建了一個新的數組,用于根據概率計算每個物品的是否可掉落,物品可以設置多個,所以,我們需要兩層嵌套循環,如果當前可掉落,那么我們將其添加到返回數組里。最后返回。

TArray<FLootItem> ULootTiers::GetLootItems()
{TArray<FLootItem> ReturnItems;for(const FLootItem Item : LootItems){for(int32 i=0; i<Item.MaxNumberToSpawn; ++i){if(FMath::RandRange(1.f, 100.f) < Item.ChanceToSpawn){FLootItem NewItem;NewItem.LootClass = Item.LootClass;NewItem.bLootLevelOverride = Item.bLootLevelOverride;ReturnItems.Add(NewItem);}}}return ReturnItems;
}

實現配置和觸發掉落邏輯

然后,我們需要一個能夠去獲取配置好的數據資產的地方,最方便的就是放到GameMode里,我們在GameMode類里添加一個配置,可以在藍圖配置使用哪一個數據資產

	//戰利品數據配置UPROPERTY(EditDefaultsOnly, Category="Loot Tiers")TObjectPtr<ULootTiers> LootTiers;

為了方便獲取數據資產,我們在藍圖函數庫里增加一個函數,用于獲取數據資產

	/*** 獲取生成的戰利品數據資產,此數據會配置到GameMode上* @param WorldContextObject  一個世界場景的對象,用于獲取當前所在的世界* @return 戰利品數據** @note 敵人死亡后,所需生成的戰利品*/UFUNCTION(BlueprintCallable, Category="RPGAbilitySystemLibrary|CharacterClassDefaults", meta=(DefaultToSelf = "WorldContextObject"))static ULootTiers* GetLootTiers(const UObject* WorldContextObject);

函數實現,我們將獲取到GameMode,并從GameMode身上獲取到數據資產

ULootTiers* URPGAbilitySystemLibrary::GetLootTiers(const UObject* WorldContextObject)
{//獲取到當前關卡的GameMode實例const ARPGGameMode* GameMode = Cast<ARPGGameMode>(UGameplayStatics::GetGameMode(WorldContextObject));if(GameMode == nullptr) return nullptr;//返回敵人戰利品配置,需要設置到GameMode上return  GameMode->LootTiers;
}

最后,我們要在敵人類里實現掉落邏輯,我們增加一個函數,這個函數需要在藍圖里實現邏輯

	//生成戰利品UFUNCTION(BlueprintImplementableEvent)void SpawnLoot();

然后在觸發死亡邏輯時,我們調用此函數來生成戰利品

在這里插入圖片描述

添加藍圖

代碼方便,我們完成了,接著,我們要在編輯器里,添加一個新的數據資產
在這里插入圖片描述
資產類型使用我們創建的戰利品資產
在這里插入圖片描述
我們將其和之前的資產放到一塊
在這里插入圖片描述
然后,在資產里,我們將之前制作的藥瓶和水晶(持續回血)添加到戰利品里,掉落概率設置為100,并且要使用敵人等級掉落。
在這里插入圖片描述
接著將其設置到GameMode藍圖里
在這里插入圖片描述
我們在敵人藍圖基類里實現統一的掉落戰利品機制,首先通過藍圖庫函數獲取到數據資產實例,然后通過GetLootItems獲取到需要生成的掉落物
在這里插入圖片描述
然后創建一個藍圖函數,用于通過藍圖函數庫,來設置掉落物的轉向。
在這里插入圖片描述
然后我們將其設置為純函數,這樣,不需要通過執行箭頭調用。
在這里插入圖片描述
然后將轉向存儲起來方便后續使用
在這里插入圖片描述
然后,我們通過一個定時器,讓物品掉落持續生成,這樣可以防止卡頓,并且物品有一個個生成的效果,我們在設置定時器時,直接調用一次此事件。
在這里插入圖片描述
接著就是生成戰利品的自定義事件,我們通過索引,從返回的數組里獲取到需要生成的對應的數據,并計算出物品掉落位置,最后生成Actor
在這里插入圖片描述
我們創建獲取變換的純函數,通過轉向對敵人位置進行一個朝向在一定范圍內隨機偏移,并使用旋轉的朝向。
在這里插入圖片描述
在創建Actor后,我們需要更新掉落物的等級,如果此物品需要修改等級,那么我們將通過此函數內的邏輯進行修改
在這里插入圖片描述
函數內,我們首先判斷是否需要修改,然后將其轉換為場景物品的基類,然后判斷當前物品是否存在,最后將敵人等級應用到掉落物身上。
在這里插入圖片描述
最后一步,就是修改索引,每調用一次,我們將索引+1,下次再調用此事件時,將會生成下一個坐標的物品,如果索引超過或等于數組長度時,我們將結束定時器,完成掉落物的生成。
在這里插入圖片描述
最后展示一下完成的藍圖連線

在這里插入圖片描述

然后進入關卡打怪測試效果
在這里插入圖片描述

關于掉落物的一些擴展

如果后續擴展的話,我考慮對于每個大關卡創建單獨的一套掉落,然后在數組資產里增加幾個數組,比如效果,使用小怪的一套掉落,而精英怪使用精英怪的一套掉落,最后是boss的掉落,使用boss的一套掉落邏輯。
然后獲取掉落時,可以根據敵人品質,去獲取不同的掉落,我們當然沒必須單獨為敵人去配置掉落。BOSS除外,我們當然可以對一些特殊BOSS去配置單獨的掉落,比如關卡的最終BOSS掉落,以及一些特殊怪物掉落。

實現掉落物自動旋轉和懸浮效果

為了實現這個效果,我們要在掉落物的基類RPGEffectActor里增加一些屬性和函數,用于實現此效果
要實現這個功能,我們增加一批函數,用于實現此功能

	// 計算后的Actor所在的位置UPROPERTY(BlueprintReadWrite)FVector CalculatedLocation;// 計算后的Actor的旋轉UPROPERTY(BlueprintReadWrite)FRotator CalculatedRotation;// Actor是否幀更新旋轉UPROPERTY(BlueprintReadWrite, Category="Pickup Movement")bool bRotates = false;// Actor每秒旋轉的角度UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Pickup Movement")float RotationRate = 45.f;// Actor是否更新位置UPROPERTY(BlueprintReadWrite, Category="Pickup Movement")bool bSinusoidalMovement = false;// 正弦值-1到1,此值為調整更新移動范圍UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Pickup Movement")float SineAmplitude = 1.f;// 此值參與正弦運算,默認值為1秒一個循環(2PI走完一個正弦的循環,乘以時間,就是一秒一個循環,可用于調整位置移動速度)UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Pickup Movement")float SinePeriod = 1.f; //2 * PI//調用此函數,Actor開始自動更新上下位置UFUNCTION(BlueprintCallable)void StartSinusoidalMovement();//調用此函數,Actor開始自動旋轉UFUNCTION(BlueprintCallable)void StartRotation();
private://當前掉落物的存在時間,可以通過此時間實現動態效果float RunningTime = 0.f;// Actor生成的默認初始位置,在Actor動態浮動時,需要默認位置作為基礎位置FVector InitialLocation;// 每一幀更新Actor的位置和轉向void ItemMovement(float DeltaSeconds);

我們還需要用到幀更新函數

virtual void Tick(float DeltaSeconds) override;

在事件開始時,我們將掉落物的默認位置和旋轉保存,并設置計算后的屬性,我們需要在后續使用它更新Actor

void ARPGEffectActor::BeginPlay()
{Super::BeginPlay();//設置初始位置InitialLocation = GetActorLocation();CalculatedLocation = InitialLocation;CalculatedRotation = GetActorRotation();
}

我們需要在幀更新了去保存當前效果的執行時間,并調用更新函數

void ARPGEffectActor::Tick(float DeltaSeconds)
{Super::Tick(DeltaSeconds);//更新當前Actor的存在時間RunningTime += DeltaSeconds;ItemMovement(DeltaSeconds);
}

在更新函數里,我們根據變量判斷是否需要更新,來對轉向和位置更新,這里需要提到的是,位置更新用到了正弦三角函數進行更新

void ARPGEffectActor::ItemMovement(float DeltaSeconds)
{//更新轉向if(bRotates){const FRotator DeltaRotation(0.f, DeltaSeconds * RotationRate, 0.f);CalculatedRotation = UKismetMathLibrary::ComposeRotators(CalculatedRotation, DeltaRotation);}//更新位置if(bSinusoidalMovement){const float Sine = SineAmplitude * FMath::Sin(RunningTime * SinePeriod * 6.28318f);CalculatedLocation = InitialLocation + FVector(0.f, 0.f, Sine);}
}

你會發現上面的變量無法在藍圖面板直接設置,那么如何將其設置為true呢,我們通用函數將其設置為true

void ARPGEffectActor::StartSinusoidalMovement()
{bSinusoidalMovement = true;InitialLocation = GetActorLocation();CalculatedLocation = InitialLocation;
}void ARPGEffectActor::StartRotation()
{bRotates = true;CalculatedRotation = GetActorRotation();
}

后續效果我們需要在藍圖里實現,所以,我們創建一個拾取的基類,然后將所有可掉落物都繼承此藍圖,沒必要在每個藍圖里實現一遍
在這里插入圖片描述
我們在拾取物基類里,創建一個時間軸,來實現掉落物的從無到有的效果,并通過時間軸的更新實現一些位置更新,和縮放效果。在時間軸播放完成后,我們調用開始旋轉和開始移動的默認效果。
在這里插入圖片描述
時間軸里,我們增加了兩個軌道,用于分別更新位置和縮放使用
在這里插入圖片描述
在幀更新里,我們通過計算后的位置和旋轉更新Actor即可
在這里插入圖片描述

以下是拾取物的表現效果

在這里插入圖片描述

添加音效

最后一個功能,我們在Actor里添加一些音效,來實現一些點綴效果。
首先在Actor增加一個變量,設置音效基礎類型
在這里插入圖片描述
然后找到對應的音效
在這里插入圖片描述
設置給變量

在這里插入圖片描述
在更新位置和縮放后(我折疊成了一個函數),我們通過修改位置的值,判斷如果大于0.3時,執行一次模擬觸碰到地面的音效
在這里插入圖片描述
然后在事件開始時增加一個生成的音效

在這里插入圖片描述
在銷毀時,播放一個拾取的音效。
在這里插入圖片描述

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

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

相關文章

Excel技巧:如何批量調整excel表格中的圖片?

插入到excel表格中的圖片大小不一&#xff0c;如何做到每張圖片都完美的與單元格大小相同&#xff1f;并且能夠根據單元格來改變大小&#xff1f;今天分享&#xff0c;excel表格里的圖片如何批量調整大小。 方法如下&#xff1a; 點擊表格中的一個圖片&#xff0c;然后按住Ct…

智能合約

06-智能合約 0 啥是智能合約&#xff1f; 定義 智能合約&#xff0c;又稱加密合約&#xff0c;在一定條件下可直接控制數字貨幣或資產在各方之間轉移的一種計算機程序。 角色 區塊鏈網絡可視為一個分布式存儲服務&#xff0c;因為它存儲了所有交易和智能合約的狀態 智能合約還…

智慧油客:從初識、再識OceanBase,到全棧上線

今天&#xff0c;我們邀請了智慧油客的研發總監黃普友&#xff0c;為我們講述智慧油客與 OceanBase 初識、熟悉和結緣的故事。 智慧油客自2016年誕生以來&#xff0c;秉持新零售的思維&#xff0c;成功從過去二十年間以“以銷售產品為中心”的傳統思維模式&#xff0c;轉向“以…

【深度學習】手機SIM卡托缺陷檢測【附鏈接】

一、手機SIM卡托用途 SIM卡托是用于固定和保護SIM卡的部件&#xff0c;通過連接SIM卡與手機主板的方式&#xff0c;允許設備訪問移動網絡&#xff0c;用戶可以通過SIM卡進行通話、發送短信和使用數據服務。 二、手機SIM卡托不良影響 SIM卡接觸不良&#xff0c;造成信號中斷&…

高新技術企業復審需要哪些材料?

高新技術企業復審需要準備以下材料&#xff1a; 《高新技術企業認定復審申請書》&#xff1b;高新技術企業證書&#xff1b;企業營業執照副本、稅務登記證書&#xff08;復印件&#xff09;&#xff1b;企業職工人數、學歷結構以及研發人員占企業職工的比例證明&#xff1b;五…

消防物證管理系統|DW-S404實現消防物證智能化管理

一、系統概述 智慧消防物證管理系統DW-S404系統旨在借助現代信息技術&#xff0c;達成消防物證管理的高效化、安全化及智能化管理目標。該系統運用物聯網、大數據、云計算等先進技術&#xff0c;實現對消防物證從產生到銷毀的全生命周期跟蹤與監控&#xff0c;從而增強物證管理…

Odoo :一款免費且開源的食品生鮮領域ERP管理系統

文 / 貝思納斯 Odoo金牌合作伙伴 引言 提供業財人資稅的精益化管理&#xff0c;實現研產供銷的融通、食品安全的追蹤與溯源&#xff0c;達成渠道的扁平化以及直面消費者的 D2C 等數字化解決方案&#xff0c;以此提升運營效率與核心競爭力&#xff0c;支撐高質量的變速擴張。…

如何部署vue項目到Github Pages

1.創建vue項目 npm create vitelatest my-vue-app -- --template vue 2.創建github倉庫 3.連接倉庫 在項目根目錄右鍵選擇open git base here&#xff0c;如果沒有安裝git請先安裝git。 初始化倉庫 $ git init $ git add . $ git commit -m "init"將項目與倉庫連…

Dubbo應用篇

文章目錄 一、Dubbo簡介二、SSM項目整合Dubbo1.生產者方配置2.消費者方配置 三、Spring Boot 項目整合Dubbo1.生產者方配置2.消費者方配置 四、應用案例五、Dubbo配置的優先級別1. 方法級配置&#xff08;Highest Priority&#xff09;2. 接口級配置3. 消費者/提供者級配置4. 全…

ubuntu的matlab使用心得

1.讀取視頻 v VideoReader(2222.mp4);出問題&#xff0c;報錯&#xff1a; matlab 錯誤使用 VideoReader/initReader (第 734 行) 由于出現意外錯誤而無法讀取文件。原因: Unable to initialize the video properties 出錯 audiovideo.internal.IVideoReader (第 136 行) init…

消息中間件-Kafka1-實現原理

消息中間件-Kafka 一、kafka簡介 1、概念 Kafka是最初由Linkedin公司開發&#xff0c;是一個分布式、支持分區&#xff08;partition&#xff09;、多副本的&#xff08;replica&#xff09;&#xff0c;基于zookeeper協調的分布式消息系統&#xff0c;它的最大的特性就是可以…

如何利用“一鍵生成ppt”減輕工作壓力

隨著數字化的快速發展&#xff0c;PPT設計這一傳統任務也迎來了新的變化。過去&#xff0c;制作一個簡潔、專業的PPT需要花費大量時間與精力。但現在借助科技的力量&#xff0c;一鍵生成PPT的夢想成真了。從智能生成ppt到ai生成ppt的技術不斷進步&#xff0c;令我們能夠體驗到更…

創造未來:The Sandbox 創作者訓練營如何賦能全球創造者

創作者訓練營讓創造者有能力打造下一代數字體驗。通過促進合作和提供尖端工具&#xff0c;The Sandbox 計劃確保今天的元宇宙是由一個個創造者共同打造。 2024 年 5 月&#xff0c;The Sandbox 推出了「創作者訓練營」系列&#xff0c;旨在重新定義數字創作。「創作者訓練營」系…

Docker多架構鏡像構建踩坑記

背景 公司為了做信創項目的亮點&#xff0c;需要將現有的一套在X86上運行的應用系統遷移到ARM服務器上運行&#xff0c;整個項目通過后端Java&#xff0c;前端VUEJS開發通過CICD做成Docker鏡像在K8S里面運行。但是當前的CICD產品不支持ARM的鏡像構建&#xff0c;于是只能手工構…

python學opencv|讀取圖像(三)放大和縮小圖像

【1】引言 前序已經學習了常規的圖像讀取操作和圖像保存技巧&#xff0c;相關文章鏈接為&#xff1a; python學opencv|讀取圖像-CSDN博客 python學opencv|讀取圖像&#xff08;二&#xff09;保存彩色圖像-CSDN博客 今天我們更近一步&#xff0c;學習放大和縮小圖像的技巧&…

D86【python 接口自動化學習】- pytest基礎用法

day86 pytest配置testpaths 學習日期&#xff1a;20241202 學習目標&#xff1a;pytest基礎用法 -- pytest配置testpaths 學習筆記&#xff1a; pytest配置項 主目錄創建pytest.ini文件 [pytest] testpaths./testRule 然后Terminal里直接命令&#xff1a;pytest&#xff…

基于 Apache Dolphinscheduler3.1.9中的Task 處理流程解析

實現一個調度任務&#xff0c;可能很簡單。但是如何讓工作流下的任務跑得更好、更快、更穩定、更具有擴展性&#xff0c;同時可視化&#xff0c;是值得我們去思考得問題。 Apache DolphinScheduler是一個分布式和可擴展的開源工作流協調平臺&#xff0c;具有強大的DAG可視化界…

藍橋杯2117砍竹子(簡單易懂 包看包會版)

問題描述 這天, 小明在砍竹子, 他面前有 n 棵竹子排成一排, 一開始第 i 棵竹子的 高度為 hi?. 他覺得一棵一棵砍太慢了, 決定使用魔法來砍竹子。魔法可以對連續的一 段相同高度的竹子使用, 假設這一段竹子的高度為 H, 那么 用一次魔法可以 把這一段竹子的高度都變為 ?H2?…

如何進行 JavaScript 性能優化?

要進行 JavaScript 性能優化&#xff0c;我們可以從多個角度進行思考&#xff0c;主要包括減少頁面渲染時間、減少內存占用、優化代碼執行效率等。以下是優化的一些方法&#xff0c;并結合實際項目代碼示例講解。 目錄結構 減少 DOM 操作 緩存 DOM 元素批量更新 DOM 優化 Jav…

CTF-PWN: 全保護下格式化字符串利用 [第一屆“吾杯”網絡安全技能大賽 如果能重來] 賽后學習(不會)

通過網盤分享的文件&#xff1a;如果能重來.zip 鏈接: https://pan.baidu.com/s/1XKIJx32nWVcSpKiWFQGpYA?pwd1111 提取碼: 1111 --來自百度網盤超級會員v2的分享漏洞分析 格式化字符串漏洞,在printf(format); __int64 sub_13D7() {char format[56]; // [rsp10h] [rbp-40h]…