我在 UE5.3 中的第一个代码块中遇到了奇怪的行为,没有在其他引擎版本上进行测试,如果这是一个初学者问题,我深表歉意!
class MyClass
{
private:
float* Value;
public:
MyClass(float& InValue) : Value(&InValue) { }
float GetValue() { return *Value; }
};
USTRUCT(BlueprintType)
struct MYMODULE_API FMyStruct
{
GENERATED_BODY()
private:
TSharedPtr<MyClass> NewClass = nullptr;
UPROPERTY()
float Value;
public:
FMyStruct() { }
FMyStruct(float InValue) : Value(InValue)
{
NewClass = MakeShared<MyClass>(Value);
}
TSharedPtr<MyClass> GetPtr() { return NewClass; }
};
我创建了一个“FMyStruct”类型的属性,然后在我的 UObject 自定义 BeginPlay 中初始化它,如下所示
UCLASS()
class MYMODULE_API UMyObject: UObject
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite)
FMyStruct MyProperty;
void BeingPlay()
{
MyProperty = FMyStruct(100.0f);
float TempFloat = MyProperty->GetPtr()->GetValue() // Returns correct value here
BP_BeginPlay();
}
UFUNCTION(BlueprintImplementableEvent)
void BP_BeginPlay();
};
正如上面代码块中的注释所述,初始化后调用时,
MyProperty->GetPtr()->GetValue()
返回BeginPlay
中的正确值MyProperty
我将
MyProperty->GetPtr()->GetValue()
暴露给蓝图并在 BP_BeginPlay
处调用它,再次,我得到了正确的值,这很好
但是,在一帧或多帧之后
MyProperty->GetPtr()->GetValue()
由于某种原因不再返回正确的值,在BP中使用值为0.0的延迟节点来跳过一帧
经过几个小时的调试,把代码精简到上面的版本,我决定看看内存地址,结果初始化一帧后
MyClass::Value
指向的地址不一样了MyProperty
这就是我得到地址的方式
UE_LOG(LogTemp, Warning, TEXT("Address[%p]"), *ThePointer);
老实说我不知道要在网上搜索什么,记忆力超出了我的范围,但我确实尝试过但失败了
非常感谢任何帮助,谢谢!
FMyStruct
被多次复制和销毁,所以我覆盖了=
运算符并使用新结构更新了属性,尤其是指向结构值的指针
FMyStruct& operator=(const FMyStruct& Other)
{
Value = Other.Value;
NewClass = Other.NewClass;
if (NewClass.IsValid())
{
NewClass->Value = &Value; // I made it public for testing purposes
}
return *this;
}
这是一个绕行代码,可能很糟糕,而且我认为这样做违背了我原始代码的目的,它只有 1 个真正的结构,我想我必须重新考虑我的设计