1.SNew
该函数在Slate层中经常使用,常用于创建一个Slate控件,相当于UObject层中的NewObject<>();
具体代码如下所示,后面.HAlign(HAlign_Right)这种都是设置这个Slate控件的样式,比如该Box是水平居中还是居右,比如Padding是什么比例等等
SNew(SBox)
.HAlign(HAlign_Right)
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.Padding(FMargin(5.0f, 0.0f))
.AutoWidth()
[
SNew(STextBlock)
.Font(FEditorStyle::GetFontStyle("TinyText"))
.Text(this, &FPaperTileMapDetailsCustomization::GetLayerSettingsHeadingText)
.ToolTipText(LOCTEXT("LayerSettingsTooltip", "Properties specific to the currently selected layer"))
]
]
2. TSharedRef<SWidget> UWidget::TakeWidget();
是将UWidget转成SWidget的一种方式,SWidget在Slate层,UWidget在UObject层,UWidget套了一层SWidget,可以理解为UWidget只是个壳,平时跟一下源码就可以发现,在U开头的控件中,一般在构造函数等中通过SNew()方式创建Slate层中的控件,然后将该引用放在Private中
该函数的作用是:做了一个UMG通向Slate控件的桥梁,我们自定义的UMG控件可以通过该函数转成Slate中的SWidget
官方解释如下:
/**
* Gets the underlying slate widget or constructs it if it doesn't exist. If you're looking to replace
* what slate widget gets constructed look for RebuildWidget. For extremely special cases where you actually
* need to change the the GC Root widget of the constructed User Widget - you need to use TakeDerivedWidget
* you must also take care to not call TakeWidget before calling TakeDerivedWidget, as that would put the wrong
* expected wrapper around the resulting widget being constructed.
*/
TSharedRef<SWidget> TakeWidget();
如何向Swidget转成UUserWidget?
bool UMyBlueprintFunctionLibrary::TestUMGWidget(UUserWidget* InWidget)
{
TSharedRef<SWidget> Widget = InWidget->TakeWidget();
TSharedRef<SObjectWidget> ObjWidget = StaticCastSharedRef<SObjectWidget>(Widget);
return ObjWidget->GetWidgetObject() == InWidget;
}
3.FSlateTexture2DRHIRef* FAssetThumbnailPool::AccessTexture( const FAssetData& AssetData, uint32 Width, uint32 Height )
该函数作用:设置好的AssetData和图片长宽高,用于将渲染好的缩略图数据返回成FSlateTexture2DRHIRef*
/**
* Accesses the texture for an object. If a thumbnail was recently rendered this function simply returns the thumbnail. If it was not, it requests a new one be generated
* No assumptions should be made about whether or not it was rendered
*
* @param Asset The asset to get the thumbnail for
* @param Width The width of the thumbnail
* @param Height The height of the thumbnail
* @return The thumbnail for the asset or NULL if one could not be produced
*/
FSlateTexture2DRHIRef* AccessTexture( const FAssetData& AssetData, uint32 Width, uint32 Height );
4.
const FObjectThumbnail* ThumbnailTools::FindCachedThumbnail( const FString& InFullName )
FObjectThumbnail* ThumbnailTools::GetThumbnailForObject( UObject* InObject )
传入UObject的引用或路径就可以拿到内存中渲染好的FObjectThumbnail
/** Searches for an object's thumbnail in memory and returns it if found */
const FObjectThumbnail* FindCachedThumbnail( const FString& InFullName )
/** Returns the thumbnail for the specified object or NULL if one doesn't exist yet */
FObjectThumbnail* GetThumbnailForObject( UObject* InObject )
5 ObjectType* TSharedPtr::Get()
在Slate层经常用TSharedPtr保存指针,但是如果函数返回一个TSharedPtr是不行的,因为它是只读的,不能赋值,我们可以通过Get()方法返回该对象的引用
/**
* Returns the object referenced by this pointer, or nullptr if no object is reference
*
* @return The object owned by this shared pointer, or nullptr
*/
FORCEINLINE ObjectType* Get() const
{
return Object;
}
6
UTexture2D* FImageUtils::CreateTexture2D
(int32 SrcWidth, int32 SrcHeight, const TArray<FColor> &SrcData, UObject* Outer, const FString& Name, const EObjectFlags &Flags, const FCreateTexture2DParameters& InParams)
在FimageUtils类中封装了一些创建Texture2D,导入导出的函数
/**
* Creates a 2D texture from a array of raw color data.
*
* @param SrcWidth Source image width.
* @param SrcHeight Source image height.
* @param SrcData Source image data.
* @param Outer Outer for the texture object.
* @param Name Name for the texture object.
* @param Flags Object flags for the texture object.
* @param InParams Params about how to set up the texture.
* @return Returns a pointer to the constructed 2D texture object.
*
*/
ENGINE_API static UTexture2D* CreateTexture2D(int32 SrcWidth, int32 SrcHeight, const TArray<FColor> &SrcData, UObject* Outer, const FString& Name, const EObjectFlags &Flags, const FCreateTexture2DParameters& InParams);
7 FString UObjectBaseUtility::GetPathName( ) const
获取UObject中路径,UObjectBaseUtility是UObject的父类
/**
* Returns the fully qualified pathname for this object, in the format:
* 'Outermost.[Outer:]Name'
*
* @param StopOuter if specified, indicates that the output string should be relative to this object. if StopOuter
* does not exist in this object's Outer chain, the result would be the same as passing NULL.
*
* @note safe to call on NULL object pointers!
*/
FString UObjectBaseUtility::GetPathName( const UObject* StopOuter/*=NULL*/ ) const
{
FString Result;
GetPathName(StopOuter, Result);
return Result;
}
8 FString UObjectBaseUtility::GetFullName( ) const
获取UObject的名字
/**
* Returns the fully qualified pathname for this object as well as the name of the class, in the format:
* 'ClassName Outermost.[Outer:]Name'.
*
* @param StopOuter if specified, indicates that the output string should be relative to this object. if StopOuter
* does not exist in this object's Outer chain, the result would be the same as passing NULL.
*
* @note safe to call on NULL object pointers!
*/
FString UObjectBaseUtility::GetFullName( const UObject* StopOuter/*=NULL*/ ) const
{
FString Result;
if( this != nullptr )
{
Result.Empty(128);
GetClass()->AppendName(Result);
Result += TEXT(" ");
GetPathName( StopOuter, Result );
// could possibly put a Result.Shrink() here, but this isn't used much in a shipping game
}
else
{
Result += TEXT("None");
}
return Result;
}
9 FPaths:RootDir()
获取根路径
/**
* Returns the root directory of the engine directory tree
*
* @return Root directory.
*/
static FString FPaths:RootDir();
该类下还封装有一些其他路径,比如相对路径和绝对路径转换
static FString ConvertRelativePathToFull(const FString& InPath);
10 static FString FPaths:GetPath(const FString& InPath)
获取文件名之前的路径
// Returns the path in front of the filename
static FString FPaths:GetPath(const FString& InPath);
11 IModuleInterface& FModuleManager::LoadModuleChecked( const FName InModuleName )
加载一个指定模块,我们说ue4是多个模块一个个加载的
/**
* Loads the specified module, checking to ensure it exists.
*
* @param InModuleName The base name of the module file. Should not include path, extension or platform/configuration info. This is just the "module name" part of the module file name. Names should be globally unique.
* @return The loaded module, or nullptr if the load operation failed.
* @see AbandonModule, IsModuleLoaded, LoadModuleChecked, LoadModulePtr, LoadModuleWithFailureReason, UnloadModule
*/
IModuleInterface& LoadModuleChecked( const FName InModuleName );
用法:这个用法是拿到Image模块,然后创建一个JPEG的IMageWrapper指针
IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
12
bool FFileHelper::SaveArrayToFile(TArrayView<const uint8> Array, const TCHAR* Filename, IFileManager* FileManager /*= &IFileManager::Get()*/, uint32 WriteFlags)
用于将二进制数据存储成一个文件
/**
* Save a binary array to a file.
*/
static bool SaveArrayToFile(TArrayView<const uint8> Array, const TCHAR* Filename, IFileManager* FileManager=&IFileManager::Get(), uint32 WriteFlags = 0);
用法:该函数是将ObjectThumbnail存储成一个图片格式
FObjectThumbnail _objectThumnail;
ThumbnailTools::RenderThumbnail(obj, _imageRes, _imageRes, ThumbnailTools::EThumbnailTextureFlushMode::AlwaysFlush, NULL, &_objectThumnail);
TArray<uint8> _myData = _objectThumnail.GetUncompressedImageData();
TArray<FColor> _imageRawColor;
for (int i = 0; i < _myData.Num(); i += 4)
{
_imageRawColor.Add(FColor(_myData[i + 2], _myData[i + 1], _myData[i], _myData[i + 3]));
}
FString _fileName = OutputPath.ToString() +"/"+ obj->GetName() + FString(".jpg");
IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
ImageWrapper->SetRaw(_imageRawColor.GetData(), _imageRawColor.GetAllocatedSize(), _imageRes, _imageRes, ERGBFormat::BGRA, 8);
const TArray<uint8>& _ImageData = ImageWrapper->GetCompressed(100);
FFileHelper::SaveArrayToFile(_ImageData, *_fileName);
13 new FExtender()
new出一个容器,经常用于slate层,用来添加各种控件
14
TSharedRef< const FExtensionBase > FExtender::AddToolBarExtension( FName ExtensionHook, EExtensionHook::Position HookPosition, const TSharedPtr< FUICommandList >& CommandList, const FToolBarExtensionDelegate& ToolBarExtensionDelegate )
TSharedRef< const FExtensionBase > FExtender::AddMenuExtension( FName ExtensionHook, EExtensionHook::Position HookPosition, const TSharedPtr< FUICommandList >& CommandList, const FMenuExtensionDelegate& MenuExtensionDelegate )
TSharedRef< const FExtensionBase > FExtender::AddMenuBarExtension( FName ExtensionHook, EExtensionHook::Position HookPosition, const TSharedPtr< FUICommandList >& CommandList, const FMenuBarExtensionDelegate& MenuBarExtensionDelegate )
常用的三种添加slate控件风格的方法,具体使用是先new一个容器,然后add这三种,最后在module里添加进来
FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
{
TSharedPtr<FExtender> MenuExtender = MakeShareable(new FExtender());
MenuExtender->AddMenuExtension("WindowLayout", EExtensionHook::After, PluginCommands, FMenuExtensionDelegate::CreateRaw(this, &FThumbnailExporterModule::AddMenuExtension));
LevelEditorModule.GetMenuExtensibilityManager()->AddExtender(MenuExtender);
}
{
TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);
ToolbarExtender->AddToolBarExtension("Settings", EExtensionHook::After, PluginCommands, FToolBarExtensionDelegate::CreateRaw(this, &FThumbnailExporterModule::AddToolbarExtension));
LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender);
}
15
FTabSpawnerEntry& FGlobalTabmanager::RegisterNomadTabSpawner( const FName TabId, const FOnSpawnTab& OnSpawnTab )
添加后还不行,还得注册,这样才能在slate层修改编辑器中的各种控件风格,具体代码如下
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(ThumbnailExporterTabName, FOnSpawnTab::CreateRaw(this, &FThumbnailExporterModule::OnSpawnPluginTab))
.SetDisplayName(LOCTEXT("FThumbnailExporterTabTitle", "ThumbnailExporter"))
.SetMenuType(ETabSpawnerMenuType::Hidden);
16
bool UAssetManager::GetAssetDataForPath(const FSoftObjectPath& ObjectPath, FAssetData& AssetData) const
拿到AssetManager,通过资源路径获取该资源信息
官方解释如下:具体代码使用在第二段
/** Gets the FAssetData at a specific path, handles redirectors and blueprint classes correctly. Returns true if it found a valid data */
virtual bool GetAssetDataForPath(const FSoftObjectPath& ObjectPath, FAssetData& AssetData) const;
UAssetManager& AssetManager = UAssetManager::Get();
FAssetData MeshObjectAssetData;
AssetManager.GetAssetDataForPath(MeshObject->GetPathName(), MeshObjectAssetData);
17
FAssetThumbnailPool::FAssetThumbnailPool( uint32 InNumInPool, const TAttribute<bool>& InAreRealTimeThumbnailsAllowed, double InMaxFrameTimeAllowance, uint32 InMaxRealTimeThumbnailsPerFrame )
个人感觉这个函数是new了一个线程池,该线程池专门用来渲染各种Thumbnail的
官方解释如下:
对FAssetThumbnailPool 的解释
/**
* Utility class for keeping track of, rendering, and recycling thumbnails rendered in Slate
*/
class FAssetThumbnailPool : public FTickableEditorObject
构造函数的各个参数含义:
/**
* Constructor
*
* @param InNumInPool The number of thumbnails allowed in the pool
* @param InAreRealTimeThumbnailsAllowed Attribute that determines if thumbnails should be rendered in real-time
* @param InMaxFrameTimeAllowance The maximum number of seconds per tick to spend rendering thumbnails
* @param InMaxRealTimeThumbnailsPerFrame The maximum number of real-time thumbnails to render per tick
*/
UNREALED_API FAssetThumbnailPool( uint32 InNumInPool, const TAttribute<bool>& InAreRealTimeThumbnailsAllowed = true, double InMaxFrameTimeAllowance = 0.005, uint32 InMaxRealTimeThumbnailsPerFrame = 3 );
使用代码如下:
TSharedPtr<FAssetThumbnailPool> ThumbnailPool1 = MakeShareable(new FAssetThumbnailPool(50, true));
18
TSharedRef< ObjectType, Mode > ToSharedRef() const
将一个TSharedPtr转成TSharedRef
/**
* Converts a shared pointer to a shared reference. The pointer *must* be valid or an assertion will trigger.
*
* @return Reference to the object
*/
// NOTE: The following is an Unreal extension to standard shared_ptr behavior
FORCEINLINE TSharedRef< ObjectType, Mode > ToSharedRef() const
{
// If this assert goes off, it means a shared reference was created from a shared pointer that was nullptr.
// Shared references are never allowed to be null. Consider using TSharedPtr instead.
check( IsValid() );
return TSharedRef< ObjectType, Mode >( *this );
}
用法:
TSharedPtr<SWidget> MySWidget;
TSharedRef<SWidget> MySWidgetRef=MySWidget.ToSharedRef();
19
UTexture2D* UKismetRenderingLibrary::ImportFileAsTexture2D(UObject* WorldContextObject, const FString& Filename)
UTexture2D* UKismetRenderingLibrary::ImportBufferAsTexture2D(UObject* WorldContextObject, const TArray<uint8>& Buffer)
用于传入图片路径或者图片Buffer,生成一张图片
UTexture2D* UKismetRenderingLibrary::ImportFileAsTexture2D(UObject* WorldContextObject, const FString& Filename)
{
return FImageUtils::ImportFileAsTexture2D(Filename);
}
UTexture2D* UKismetRenderingLibrary::ImportBufferAsTexture2D(UObject* WorldContextObject, const TArray<uint8>& Buffer)
20
void UKismetRenderingLibrary::ExportTexture2D(UObject* WorldContextObject, UTexture2D* Texture, const FString& FilePath, const FString& FileName)
将一张Texture2D图片输出到磁盘上
/**
* Exports a Texture2D as a HDR image onto the disk.
*/
UFUNCTION(BlueprintCallable, Category = "Rendering", meta = (Keywords = "ExportTexture2D", WorldContext = "WorldContextObject"))
static ENGINE_API void ExportTexture2D(UObject* WorldContextObject, UTexture2D* Texture, const FString& FilePath, const FString& FileName);
21
UFunction* UClass::FindFunction(FName InName) const
作用:通过函数名直接拿到一个UClass的函数指针
/**
* This signature intentionally hides the method declared in UObject to make it private.
* Call FindFunctionByName instead; This method will search for a function declared in UClass instead of the class it was called on
*/
UFunction* FindFunctionChecked(FName InName) const
{
return UObject::FindFunctionChecked(InName);
}
用法:
SkyDataAsset = FAssetData(SkyData);
UFunction* SetSkyData = SkyController->FindFunction(TEXT("EditorSetSkyData"));
SkyController->ProcessEvent(SetSkyData, &SkyData);
22
virtual void AActor::ProcessEvent(UFunction* Function, void* Parameters)
作用:
传入该函数具有的所有参数Struct和函数指针,直接调用该函数
该函数在cpp的实现如下,可见,调用的其实是父类的该函数
void AActor::ProcessEvent(UFunction* Function, void* Parameters)
{
LLM_SCOPE(ELLMTag::EngineMisc);
#if WITH_EDITOR
static const FName CallInEditorMeta(TEXT("CallInEditor"));
const bool bAllowScriptExecution = GAllowActorScriptExecutionInEditor || Function->GetBoolMetaData(CallInEditorMeta);
#else
const bool bAllowScriptExecution = GAllowActorScriptExecutionInEditor;
#endif
UWorld* MyWorld = GetWorld();
if( ((MyWorld && (MyWorld->AreActorsInitialized() || bAllowScriptExecution)) || HasAnyFlags(RF_ClassDefaultObject)) && !IsGarbageCollecting() )
{
#if !UE_BUILD_SHIPPING
if (!ProcessEventDelegate.IsBound() || !ProcessEventDelegate.Execute(this, Function, Parameters))
{
Super::ProcessEvent(Function, Parameters);
}
#else
Super::ProcessEvent(Function, Parameters);
#endif
}
}
父类是UObject,该函数实现如下,感觉有点晦涩,有空再研究
void UObject::ProcessEvent( UFunction* Function, void* Parms )
{
checkf(!IsUnreachable(),TEXT("%s Function: '%s'"), *GetFullName(), *Function->GetPathName());
checkf(!FUObjectThreadContext::Get().IsRoutingPostLoad, TEXT("Cannot call UnrealScript (%s - %s) while PostLoading objects"), *GetFullName(), *Function->GetFullName());
#if LIGHTWEIGHT_PROCESS_EVENT_COUNTER
CONDITIONAL_SCOPE_CYCLE_COUNTER(STAT_BlueprintTime, IsInGameThread() && ProcessEventCounter == 0);
TGuardValue<int32> PECounter(ProcessEventCounter, ProcessEventCounter+1);
#endif
#if DO_BLUEPRINT_GUARD
FBlueprintExceptionTracker& BlueprintExceptionTracker = FBlueprintExceptionTracker::Get();
TGuardValue<int32> EntryCounter( BlueprintExceptionTracker.ScriptEntryTag, BlueprintExceptionTracker.ScriptEntryTag+1);
CONDITIONAL_SCOPE_CYCLE_COUNTER(STAT_BlueprintTime, IsInGameThread() && BlueprintExceptionTracker.ScriptEntryTag == 1);
#endif
#if TOTAL_OVERHEAD_SCRIPT_STATS
FBlueprintEventTimer::FScopedVMTimer VMTime;
#endif // TOTAL_OVERHEAD_SCRIPT_STATS
// Reject.
if (IsPendingKill())
{
return;
}
#if WITH_EDITORONLY_DATA
// Cannot invoke script events when the game thread is paused for debugging.
if(GIntraFrameDebuggingGameThread)
{
if(GFirstFrameIntraFrameDebugging)
{
UE_LOG(LogScriptCore, Warning, TEXT("Cannot call UnrealScript (%s - %s) while stopped at a breakpoint."), *GetFullName(), *Function->GetFullName());
}
return;
}
#endif // WITH_EDITORONLY_DATA
if ((Function->FunctionFlags & FUNC_Native) != 0)
{
int32 FunctionCallspace = GetFunctionCallspace(Function, Parms, NULL);
if (FunctionCallspace & FunctionCallspace::Remote)
{
CallRemoteFunction(Function, Parms, NULL, NULL);
}
if ((FunctionCallspace & FunctionCallspace::Local) == 0)
{
return;
}
}
else if (Function->Script.Num() == 0)
{
return;
}
checkSlow((Function->ParmsSize == 0) || (Parms != NULL));
#if PER_FUNCTION_SCRIPT_STATS
const bool bShouldTrackFunction = Stats::IsThreadCollectingData();
FScopeCycleCounterUObject FunctionScope(bShouldTrackFunction ? Function : nullptr);
#endif // PER_FUNCTION_SCRIPT_STATS
#if STATS || ENABLE_STATNAMEDEVENTS
const bool bShouldTrackObject = GVerboseScriptStats && Stats::IsThreadCollectingData();
FScopeCycleCounterUObject ContextScope(bShouldTrackObject ? this : nullptr);
#endif
#if UE_BLUEPRINT_EVENTGRAPH_FASTCALLS
// Fast path for ubergraph calls
int32 EventGraphParams;
if (Function->EventGraphFunction != nullptr)
{
// Call directly into the event graph, skipping the stub thunk function
EventGraphParams = Function->EventGraphCallOffset;
Parms = &EventGraphParams;
Function = Function->EventGraphFunction;
// Validate assumptions required for this optimized path (EventGraphFunction should have only been filled out if these held)
checkSlow(Function->ParmsSize == sizeof(EventGraphParams));
checkSlow(Function->FirstPropertyToInit == nullptr);
checkSlow(Function->PostConstructLink == nullptr);
}
#endif
// Scope required for scoped script stats.
{
uint8* Frame = NULL;
#if USE_UBER_GRAPH_PERSISTENT_FRAME
if (Function->HasAnyFunctionFlags(FUNC_UbergraphFunction))
{
Frame = Function->GetOuterUClassUnchecked()->GetPersistentUberGraphFrame(this, Function);
}
#endif
const bool bUsePersistentFrame = (NULL != Frame);
if (!bUsePersistentFrame)
{
Frame = (uint8*)FMemory_Alloca(Function->PropertiesSize);
// zero the local property memory
FMemory::Memzero(Frame + Function->ParmsSize, Function->PropertiesSize - Function->ParmsSize);
}
// initialize the parameter properties
FMemory::Memcpy(Frame, Parms, Function->ParmsSize);
// Create a new local execution stack.
FFrame NewStack(this, Function, Frame, NULL, Function->Children);
checkSlow(NewStack.Locals || Function->ParmsSize == 0);
// if the function has out parameters, fill the stack frame's out parameter info with the info for those params
if ( Function->HasAnyFunctionFlags(FUNC_HasOutParms) )
{
FOutParmRec** LastOut = &NewStack.OutParms;
for ( UProperty* Property = (UProperty*)Function->Children; Property && (Property->PropertyFlags&(CPF_Parm)) == CPF_Parm; Property = (UProperty*)Property->Next )
{
// this is used for optional parameters - the destination address for out parameter values is the address of the calling function
// so we'll need to know which address to use if we need to evaluate the default parm value expression located in the new function's
// bytecode
if ( Property->HasAnyPropertyFlags(CPF_OutParm) )
{
CA_SUPPRESS(6263)
FOutParmRec* Out = (FOutParmRec*)FMemory_Alloca(sizeof(FOutParmRec));
// set the address and property in the out param info
// note that since C++ doesn't support "optional out" we can ignore that here
Out->PropAddr = Property->ContainerPtrToValuePtr<uint8>(Parms);
Out->Property = Property;
// add the new out param info to the stack frame's linked list
if (*LastOut)
{
(*LastOut)->NextOutParm = Out;
LastOut = &(*LastOut)->NextOutParm;
}
else
{
*LastOut = Out;
}
}
}
// set the next pointer of the last item to NULL to mark the end of the list
if (*LastOut)
{
(*LastOut)->NextOutParm = NULL;
}
}
if (!bUsePersistentFrame)
{
for (UProperty* LocalProp = Function->FirstPropertyToInit; LocalProp != NULL; LocalProp = (UProperty*)LocalProp->Next)
{
LocalProp->InitializeValue_InContainer(NewStack.Locals);
}
}
// Call native function or UObject::ProcessInternal.
const bool bHasReturnParam = Function->ReturnValueOffset != MAX_uint16;
uint8* ReturnValueAddress = bHasReturnParam ? ((uint8*)Parms + Function->ReturnValueOffset) : nullptr;
Function->Invoke(this, NewStack, ReturnValueAddress);
if (!bUsePersistentFrame)
{
// Destroy local variables except function parameters.!! see also UObject::CallFunctionByNameWithArguments
// also copy back constructed value parms here so the correct copy is destroyed when the event function returns
for (UProperty* P = Function->DestructorLink; P; P = P->DestructorLinkNext)
{
if (!P->IsInContainer(Function->ParmsSize))
{
P->DestroyValue_InContainer(NewStack.Locals);
}
else if (!(P->PropertyFlags & CPF_OutParm))
{
FMemory::Memcpy(P->ContainerPtrToValuePtr<uint8>(Parms), P->ContainerPtrToValuePtr<uint8>(NewStack.Locals), P->ArrayDim * P->ElementSize);
}
}
}
}
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
#if WITH_EDITORONLY_DATA
FBlueprintCoreDelegates::OnScriptExecutionEnd.Broadcast();
#endif
#endif
}
23
template< class ObjectType >
FORCEINLINE SharedPointerInternals::FRawPtrProxy< ObjectType > MakeShareable( ObjectType* InObject )
作用:将一个object的指针隐式转换成一个shared pointers
用法
TSharedRef<IDetailCustomization> FCWPVPActorDetailPanel::MakeInstance()
{
return MakeShareable(new FCWPVPActorDetailPanel);
}
源码的解释:
/**
* MakeShareable utility function. Wrap object pointers with MakeShareable to allow them to be implicitly
* converted to shared pointers! This is useful in assignment operations, or when returning a shared
* pointer from a function.
*/
// NOTE: The following is an Unreal extension to standard shared_ptr behavior
template< class ObjectType >
FORCEINLINE SharedPointerInternals::FRawPtrProxy< ObjectType > MakeShareable( ObjectType* InObject )
{
return SharedPointerInternals::FRawPtrProxy< ObjectType >( InObject );
}
24
如果是编辑器已经加载过的资源,不通过loadobject方法加载该资源
如何从ue4编辑器内存中直接拿到该资源?
该方法是通过UAssetManager获取内存中已经加载过的所有资源,传入的是该资源的地址,拿到一个AssetData数据,通过FastGetAsset方法(参数为true表示该资源已load)获取UObject
UAssetManager& AssetManaget = UAssetManager::Get();
FSoftObjectPath SoftPath(*Path);
FAssetData ObjectAssetData;
bool bHaveGet = AssetManaget.GetAssetDataForPath(SoftPath, ObjectAssetData);
if (bHaveGet)
{
return ObjectAssetData.FastGetAsset(true);
}
return nullptr;
25
UEditorAssetLibrary::SaveLoadedAsset(const TArray<UObject*>& AssetsToSave, bool bOnlyIfIsDirty = true);
用来保存编辑器中已加载过的资源,序列化数据到硬盘上
/**
* Save the packages the assets live in. All objects that live in the package will be saved. Will try to checkout the files.
* @param AssetToSaves Assets that we want to save.
* @param bOnlyIfIsDirty Only checkout asset that are dirty.
* @return True if the operation succeeds.
*/
UFUNCTION(BlueprintCallable, Category = "Editor Scripting | Asset")
static bool SaveLoadedAssets(const TArray<UObject*>& AssetsToSave, bool bOnlyIfIsDirty = true);
26
UEditorAssetLibrary类中封装了对编辑器中已Load的资源的各种操作,如加载资源,拷贝资源,删除资源,根据路径获取FAssetData,判断资源是否存在,对资源的迁出保存等