UE4对象类类型引用和类默认对象(Class Default Object,简称CDO)

官方介绍https://docs.unrealengine.com/en-us/Programming/UnrealArchitecture/Objects

The UCLASS macro gives the UObject a reference to a UCLASS that describes its Unreal-based type. Each UCLASS maintains one Object called the 'Class Default Object', or CDO for short. The CDO is essentially a default 'template' Object, generated by the class constructor and unmodified thereafter. Both the UCLASS and the CDO can be retrieved for a given Object instance, though they should generally be considered read-only. The UCLASS for an Object instance can be accessed at any time using the GetClass() function.

UCLASS宏为UObject提供了一个描述其基于虚幻的类型的UCLASS的引用。每个UCLASS都维护一个名为“类默认对象”的对象,简称CDO。 CDO本质上是一个默认的“模板”对象,由类构造函数生成,之后未修改。可以为给定的Object实例检索UCLASS和CDO,尽管它们通常应该被认为是只读的。可以使用GetClass()函数随时访问Object实例的UCLASS。 

CDO是在引擎初始化时创建的,当引擎为每个类生成UClass对象时。每个UClass的实例都是在引擎初始化期间创建的,并被分配为该UClass的CDO。并且包含在反射系统中,如在编辑器可以操作类蓝图。Obj.cpp可以看到引擎CDO初始化创建。

个人总结使用:

UE4每个对象都有该类类型引用描述该对象,通过GetClass()获取,原型如下

UClass* FObjectInitializer::GetClass() const
{
    return Obj->GetClass();
}
 

GetClass()对应Class.h都有一个ClassDefaultObject,如下


    /** The class default object; used for delta serialization and object initialization */
    UObject* ClassDefaultObject;
    /**
     * Get the default object from the class
     * @param    bCreateIfNeeded if true (default) then the CDO is created if it is null
     * @return        the CDO for this class
     */
    UObject* GetDefaultObject(bool bCreateIfNeeded = true)
    {
        if (ClassDefaultObject == nullptr && bCreateIfNeeded)
        {
            CreateDefaultObject();
        }

        return ClassDefaultObject;
    }

template< class T > 
inline const T* GetDefault(UClass *Class)
{
    check(Class->GetDefaultObject()->IsA(T::StaticClass()));
    return (const T*)Class->GetDefaultObject();
}

也可以通过全局类UObjectGlobals.h获取

// Get default object of a class.
template< class T > 
inline const T* GetDefault()
{
    return (const T*)T::StaticClass()->GetDefaultObject();
}

// Get default object of a class.
template< class T > 
inline const T* GetDefault(UClass *Class);

 

开发过程中,UE4类默认对象主要功能是存储类对象的默认状态和持有默认变量的状态,用法可以参考如下例子:

1.获取默认值

void AShooterCharacter::BeginPlay()

{
    const ACharacter* DefaultC= GetDefault<ACharacter>(GetClass());

     if ( DefaultChar->GetMesh())
    {
       float RL_Z = DefaultChar->GetMesh()->RelativeLocation.Z;
    }
}

int32 AShooterCharacter::GetMaxHealth() const
{
    return  GetClass()->GetDefaultObject<AShooterCharacter>()->Health;//表示获取AShooterCharacter类血量默认值
}

void AShooterPlayerCameraManager::BeginPlay()
{
    Super::BeginPlay();

    DefaultFreeCamDistance = Cast<AShooterPlayerCameraManager>(GetClass()->ClassDefaultObject)->FreeCamDistance;
}

 

2.判断类型

Other->GetClass()->IsChildOf(AShooterCharacter::StaticClass());//判断Other是否属于AShooterCharacter类型

3.判断是否通过某接口继承实现

UINTERFACE(Blueprintable)
class UShooterXXX : public UInterface
{
    GENERATED_BODY()
};

class IShooterXXX
{
    GENERATED_BODY()

public:
    virtual float GetXXX() const;
};

UCLASS(Abstract)
class AShooterCharacter : public ACharacter, public IShooterXXX

{
    GENERATED_UCLASS_BODY()

virtual float GetXXX() const;//重载IShooterXXX接口实现

}

//判断碰撞信息Actor是否继承该接口实现的对象,然后使用其接口

bool bImplemented = Impact.Actor->GetClass()->ImplementsInterface(UShooterWeaponPenetration::StaticClass());

ShooterXXX*    X = bImplemented ? Cast<ShooterXXX>(Impact.Actor) : nullptr;

float  CurData = bImplemented ? X-> GetXXX():0.f;

4.判断两个对象类类型是否一样

if (otherActor->GetClass() == this->GetClass())
  {

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值