c++ - 当我只能从非 UObjects 继承时,如何让 c++ 继承在演员中工作?
问题描述
我目前正在尝试像在任何其他项目中一样实现继承,但我不断收到错误消息,告诉我我只能从非 UObjects 或 UInterface 派生接口继承。我正在尝试创建一个继承 AActor 的 MasterEntity 类,然后我将拥有共享某些变量(如健康)的子类 PlayerCharacter 和 NonPlayerCharacter,但我无法完成这个看似简单的任务。
我目前的文件如下
MasterEntity.h:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MasterEntity.generated.h"
UCLASS()
class THIRDPERSONGAME_API AMasterEntity : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMasterEntity();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int32 maxHealth;
};
玩家角色.h
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Components/BoxComponent.h"
#include "InteractionInterface.h"
#include "MasterEntity.h"
#include "PlayerCharacter.generated.h"
UCLASS(config=Game)
class APlayerCharacter : public ACharacter, public AMasterEntity
{
GENERATED_BODY()
public:
APlayerCharacter();
protected:
/** Called for forwards/backward input */
void MoveForward(float Value);
/** Called for side to side input */
void MoveRight(float Value);
/**
* Called via input to turn at a given rate.
* @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
*/
void TurnAtRate(float Rate);
/**
* Called via input to turn look up/down at a given rate.
* @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
*/
void LookUpAtRate(float Rate);
protected:
// APawn interface
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// End of APawn interface
virtual void BeginPlay() override;
void OnInteract();
public:
virtual void Tick(float DeltaSeconds) override;
private:
UPROPERTY(EditAnywhere)
UBoxComponent* InteractionBox;
IInteractionInterface* Interface = nullptr;
};
我错过了什么可以让我这样做?我相信我可以改用组件,但这对于我正在尝试做的事情来说似乎真的很混乱。我尝试使 MasterEntity 类只是一个常规的 C++ 类并继承它,这没有给我任何编译错误,但我无法在蓝图编辑器中看到任何值(如 maxHealth 变量)。
解决方案
UE4 不允许从UObject
基于 的类(即您想要使用的大多数 UE4 类)进行多重继承,但允许实现多个接口以及从UObject
. 避免“钻石继承”问题是其背后的原因之一。
这是许多编程语言和范例中的常用方法,有助于管理程序的状态。使用多重继承和可能的菱形继承,代码状态的复杂性会迅速膨胀。与常规类不同,接口不会膨胀派生类对象的状态,因为它们没有数据成员。
在您的示例中,您试图同时继承ACharacter
和AMasterEntity
继承,它们都继承自AActor
,这是 a UObject
,因此出现错误。
使用组件将是推荐的解决方案,因为它遵循“组合优于继承”的原则,并提示您编写更少耦合和更可重用的代码(如果做得好)。
我发现向 Unity 引擎学习很有帮助,它进一步推广了这些概念:GameObject
s(有点类似于 UE4 角色)没有自己的代码,纯粹充当MonoBehavior
s(组件)的容器,而 C# 语言本身完全不允许多重继承(除了实现接口)。
此外,UE4 编辑器(以及许多其他 UE4 功能)依赖于UPROPERTY()
、、UFUNCTION()
等宏来跟踪 C++ 类的结构,因此如果没有它们,它将无法在蓝图中显示您的类的成员,并且这些宏将不起作用在 -UObject
派生类之外。
推荐阅读
- javascript - Img 标记(子)的 Span 标记(父)中的引导工具提示无法加载
- python - 使用 pyCharm + Django + Raspberry pi 进行远程部署
- angular - 使用 pipeable 操作员进行测试
- gatt - 向 Movesense pod 添加第二个 GATT 服务
- java - 具有泛型类型的具体实现的 LambdaMetaFactory
- java - Java 使用流按月获取订购产品的数量
- excel - 从 VB.net 以编程方式命名 Excel 工作簿
- javascript - 如何将样式类应用于按钮,但在 Vue 中的任何时候只能激活一个按钮?
- vue.js - 我无法使用 sass-resources-loader 在 vuejs 中加载配置 scss 文件
- alexa - 如何在 Alexa 技能中为自定义意图的话语添加人类声音?