UE TSubclassOf

本文介绍了如何在代码中使用TSubclassOf<TParentClassName>创建子类实例,包括通过蓝图编辑指定子类和直接在代码中加载蓝图文件地址两种方式。特别适用于复杂Widget的创建,如UCubeViewUIWidget的实例化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义

TSubclassOf<ParentClassName> ChildClass_Ins

TSubclassOf 根据父类对象创建其子类实例。然后就可以再将创建的子类对象地址赋值给父类指针。一般用于在代码中创建蓝图子类实例。

具体使用场景例如:

1.Widget创建;Widget若全部使用代码来创建比较复杂,可先使用代码定义所需的空间变量,再派生蓝图类,完成界面编辑。

UPROPERTY(EditAnywhere, Category = "UserWidget")
TSubclassOf<class UCubeViewUIWidget> CubeViewUIWidget_BP;
/*
中间需指定CubeViewUIWidget_BP的定义类型
*/
UCubeViewUIWidget* CubeViewUIWidget;
CubeViewUIWidget = CreateWidget<UCubeViewUIWidget>(GetWorld(), CubeViewUIWidget_BP);

注意

使用TSubclassOf作为某一个类(Class1)的成员变量时,需要指定子类类型(派生类不唯一)。具体方法有两种:

  1. 在该成员变量暴露给蓝图可编辑,再将该类(Class1)派生出一个蓝图类,再在蓝图类默认值设置中设定CubeViewUIWidget_BP的值,如图:

 

  1. 不派生蓝图类,直接在代码中指定子类定位文件地址(需要创建实例的蓝图文件地址):
TSubclassOf<class UCubeViewUIWidget> CubeViewUIWidget_BP;
UCubeViewUIWidget* CubeViewUIWidget;
//从内容浏览器中加载类的定义
static ConstructorHelpers::FClassFinder<UCubeViewUIWidget> WidgetAsset(TEXT("Game/Widget_BP"));
	if (WidgetAsset.Succeeded())
	{
		/** Assign the class of the loaded asset to the WigetClass variable, which is a "subclass" of UUserWidget : Which our asset class is */
		CubeViewUIWidget_BP = WidgetAsset.Class;
	}
CubeViewUIWidget = CreateWidget<UCubeViewUIWidget>(GetWorld(), CubeViewUIWidget_BP);

其中:TEXT("Game/Widget_BP")为内容浏览器中的蓝图文件的位置,可右击文件<复制引用>获取。

### Unreal Engine 中拾取系统的实现方式 在 Unreal Engine (UE) 中,拾取系统通常用于处理玩家与场景中的物品交互的功能。以下是关于如何在 UE 中实现拾取系统的详细介绍: #### 1. 使用碰撞检测触发拾取逻辑 为了实现拾取功能,可以利用 UE 的物理引擎和碰撞检测机制。通过设置静态网格物体(Static Mesh)或骨骼网格物体(Skeletal Mesh)上的碰撞组件(Collision Component),使其能够响应特定类型的重叠事件。 例如,可以通过以下代码监听角色与可拾取物之间的碰撞并执行相应操作: ```cpp void AMyCharacter::BeginPlay() { Super::BeginPlay(); // 设置手部区域或其他拾取范围的SphereComponent为Overlap模式 PickUpRange->OnComponentBeginOverlap.AddDynamic(this, &AMyCharacter::OnPickupEnter); } void AMyCharacter::OnPickupEnter(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) { IPickupInterface* PickupInterface = Cast<IPickupInterface>(OtherActor); if (PickupInterface != nullptr) { PickupInterface->Execute_PickedUp(OtherActor); // 调用接口函数移除对象或改变其状态 } } ``` 上述代码展示了如何定义一个 `PickupRange` 并绑定到角色上,当该范围与其他支持拾取的对象发生碰撞时会调用回调函数[^5]。 #### 2. 创建拾取物品的基础类 为了让不同种类的道具都可以被统一管理,建议创建一个基础蓝图或者C++类作为所有拾取物品的父类。这个基类应该包含通用属性比如名称、描述以及效果数据等,并提供虚拟方法供子类覆写以定制具体行为。 对于 C++ 开发者来说,可能看起来像这样: ```cpp UCLASS(Abstract) class MYGAME_API APickupBase : public AActor { GENERATED_BODY() public: virtual void BeginPlay() override; virtual void PickedUp_Implementation(); // 可由派生类覆盖的具体动作 protected: UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings") TSubclassOf<UAbilitySystemBlueprintLibrary> AbilityToGrant; // 如果涉及能力授予的话 }; ``` #### 3. 利用接口提高灵活性 如果希望进一步增强设计的模块化程度,则可以引入接口的概念。让每一个潜在可拾起的东西都去继承自某个预设好的接口声明文件内的成员变量及纯虚函數定义即可完成此目的。 如下面的例子所示,我们定义了一个简单的拾取接口 `IPickupInterface.h` ,它只包含了单一的方法签名用来通知外部世界当前实例已经被成功获取到了。 ```cpp // IPickupInterface.h #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "IPickupInterface.generated.h" UINTERFACE(MinimalAPI) class UIPickupInterface : public UInterface { }; class MYGAME_API IPickupInterface { GENERATED_BODY() public: virtual void Execute_PickedUp(AActor *SelfActor)=0; }; ``` 最后再回到之前提到过的那个 OnPickupEnter 函数内部部分时候就可以安全地尝试转换传入参数里面的 Actor 是否实现了我们的新标准啦! --- ### 总结 综上所述,在 Unreal Engine 中构建一套完整的拾取系统需要综合运用多种技术手段,包括但不限于碰撞检测、面向对象编程原则下的抽象层次划分还有就是灵活应用各种插槽概念等等[^6]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值