一、添加能力系统组件
1.添加插件:GameplayAbilities
2.添加能力系统组件
3.在Source/Crunch/Crunch.Build.cs中添加依赖模块:
// Copyright Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class Crunch : ModuleRules
{
public Crunch(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput" });
PrivateDependencyModuleNames.AddRange(new string[]
{
"GameplayAbilities",
"GameplayTasks",
"GameplayTags"
});
// Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
}
}
思考:
PublicDependencyModuleNames.AddRange(new string[] { });
PrivateDependencyModuleNames.AddRange(new string[] { });
有什么区别,具体用法或注意点?
在Unreal Engine的模块化系统中,PublicDependencyModuleNames
和PrivateDependencyModuleNames
的主要区别在于依赖的可见性和传递性:
PublicDependencyModuleNames
- 用于声明当前模块的公共接口依赖
- 具有传递性:依赖当前模块的其他模块会自动继承这些依赖
- 适用场景:当需要在模块的.h文件中使用目标模块的类或功能时
PrivateDependencyModuleNames
- 用于声明当前模块的私有实现依赖
- 不具有传递性:依赖当前模块的其他模块不会继承这些依赖
- 适用场景:仅在.cpp文件中使用目标模块功能,且不暴露给其他模块时
使用注意事项
- 公共依赖会增加编译时间,应尽量减少不必要的公共依赖
- 跨模块调用时,被调用模块必须作为公共依赖添加
- 像Json、ImageWrapper等工具类模块通常作为私有依赖添加
- 模块自身的名称不应添加到依赖列表中(这是常见错误)
- 插件模块的依赖配置方式与项目模块相同
4.添加属性集:
5.在角色类添加这两个组件:Source/Crunch/Public/Character/CCharacter.h
(1)通过接口获取组件:
#include "AbilitySystemInterface.h"
class CRUNCH_API ACCharacter : public ACharacter, public IAbilitySystemInterface
重写接口函数:我们可以获得能力系统组件
/** Returns the ability system component to use for this actor. It may live on another actor, such as a Pawn using the PlayerState's component */
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const = 0;
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
UAbilitySystemComponent* ACCharacter::GetAbilitySystemComponent() const
{
return CAbilitySystemComponent;
}
(2)创建变量:
private:
UPROPERTY()
TObjectPtr<UCAbilitySystemComponent> CAbilitySystemComponent;
UPROPERTY()
TObjectPtr<UCAttributeSet> CAttributeSet;
(3)构造函数添加组件:
//添加组件
CAbilitySystemComponent = CreateDefaultSubobject<UCAbilitySystemComponent>(TEXT("CAbilitySystemComponent"));
CAttributeSet = CreateDefaultSubobject<UCAttributeSet>(TEXT("CAttributeSet"));
Source/Crunch/Public/Character/CCharacter.h:
// Copyright@ChenChao
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "AbilitySystemInterface.h"
#include "CCharacter.generated.h"
class UCAbilitySystemComponent;
class UCAttributeSet;
UCLASS(Abstract)
class CRUNCH_API ACCharacter : public ACharacter, public IAbilitySystemInterface
{
GENERATED_BODY()
public:
ACCharacter();
/********************************************************************************/
/* GameplayAbilitySystem */
/********************************************************************************/
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
protected:
virtual void BeginPlay() override;
private:
UPROPERTY()
TObjectPtr<UCAbilitySystemComponent> CAbilitySystemComponent;
UPROPERTY()
TObjectPtr<UCAttributeSet> CAttributeSet;
};
Source/Crunch/Private/Character/CCharacter.cpp:
// Copyright@ChenChao
#include "Character/CCharacter.h"
#include "GAS/CAbilitySystemComponent.h"
#include "GAS/CAttributeSet.h"
// Sets default values
ACCharacter::ACCharacter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
// 网格体无碰撞
GetMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
//添加组件
CAbilitySystemComponent = CreateDefaultSubobject<UCAbilitySystemComponent>(TEXT("CAbilitySystemComponent"));
CAttributeSet = CreateDefaultSubobject<UCAttributeSet>(TEXT("CAttributeSet"));
}
UAbilitySystemComponent* ACCharacter::GetAbilitySystemComponent() const
{
return CAbilitySystemComponent;
}
void ACCharacter::BeginPlay()
{
Super::BeginPlay();
}