ue4_C++踩过的坑

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_24835213/article/details/80081355

1.蓝图工程创建C++脚本生成C++文件出错:

OutputLog:

ERROR:e:\project_ue4\*********\Intermediate\Source\VR_Zombie_GearVR.Target.cs(6,14) : error CS0101: ?????ռ䡰<ȫ???????ռ?>???Ѿ??????ˡ?VR_Zombie_GearVRTarget???Ķ???

ERROR: UnrealBuildTool Exception: Unable to compile source files.

解决方案:删除Intermediate文件夹再创建一遍即可

2.c++编译报错:"Expected xxxxxxxx.h to be first header included”

将xxxx.h头文件放在第一个引用

3.c++退出游戏API

FGenericPlatformMisc::RequestExit(false);

4.VS rebuild工程(或者是打包时选了FullRebuild)报错

原因:VS的rebuild和ue4的有冲突,会导致误删插件中的文件

解决方法:将缺少的文件从SDK插件中拷贝一份放在对应位置即可打包成功

5.开发小米VR一体机遇到一个坑爹的问题

在上传时报这样的错误

也就是Opengl ES版本需要3.0以上

但是项目中确实用的是ES3.1,androidManifest里面却显示的是2.0

小米插件中提供了修改androidManifest的方法,在MiVRHMD_APL.xml

的<androidManifestUpdates>标签中加入如下字段

即可!

6.项目拷贝到其他电脑识别不到ue4目录:

右键项目重新生成sln项目即可。

7.通过反射来以名字查找更改Ustruct成员值

void UPP_ToolBluePrintFunctoin::GetSetParameter(UObject * ObjectWithPara,const FName & Parameter_name, const float Intensity, UObject* & OutActor)
 {
	//OutActors.Reset();
	APostProcessVolume* PP_Outer;
	 FName PropName = FName("Settings");
	 FName MemberName = Parameter_name;
	 float NewValue = Intensity;
	 struct FPostProcessSettings MyPPSettings;
	 PP_Outer = Cast<APostProcessVolume>(ObjectWithPara);
	 // Get property representing struct
	 UProperty * Prop = PP_Outer->GetClass()->FindPropertyByName(PropName);
	 // Ensure Object actually has a special member
	 if (Prop)
	 {
		
		 // Get struct address
		 void * StructAddress = Prop->ContainerPtrToValuePtr<void>(PP_Outer);
		 // Ensure the parameter is special parameter
		 if (UStructProperty * StructProp = Cast<UStructProperty>(Prop))
		 {
			 
			 // We'll get struct properties through a UScriptStruct, not a UObject
			 // ScriptStructs are just templates and don't hold any of your data
			 UScriptStruct * ScriptStruct = StructProp->Struct;
			 FPostProcessSettings MyPPSettings;
			 
			 // Get  need property
			 UProperty * ChildProp = ScriptStruct->FindPropertyByName(MemberName);
			 // Cast to FloatProperty
			 if (UFloatProperty *  ChildFloatProp = Cast<UFloatProperty >(ChildProp))
			 {
					 PP_Outer->CanEditChange(ChildFloatProp);
					 //not work 
					/*
				ChildFloatProp->SetFloatingPointPropertyValue(StructAddress, NewValue);*/
					 ChildFloatProp->SetPropertyValue_InContainer(StructAddress, NewValue);
			 }
			OutActor = PP_Outer;
		}	 
	 }
 }

其中

 UProperty * Prop = PP_Outer->GetClass()->FindPropertyByName(PropName);

通过名字查找到了Uobject包含的settings Uproperty

void * StructAddress = Prop->ContainerPtrToValuePtr<void>(PP_Outer);

拿到settings Uproperty 地址的指针

UStructProperty * StructProp = Cast<UStructProperty>(Prop)

确保指针指向的是一个UStructProperty

 UScriptStruct * ScriptStruct = StructProp->Struct;

得到UStructProperty的抽象定义

UProperty * ChildProp = ScriptStruct->FindPropertyByName(MemberName);

通过名字找到UStructProperty定义下包含的一个UProperty

UFloatProperty *  ChildFloatProp = Cast<UFloatProperty >(ChildProp)

确保ChildProp 是一个浮点类型的UProperty

 PP_Outer->CanEditChange(ChildFloatProp);

该方法确保了APostProcessVolume里面的settings成员下的名为MemberName的UProperty 值改变起作用

 ChildFloatProp->SetFloatingPointPropertyValue(StructAddress, NewValue);

该方法经测试只能更改UProperty 初始化时的值,在runtime不起作用

 ChildFloatProp->SetPropertyValue_InContainer(StructAddress, NewValue);

该方法经测试可以在runtime实时改变UProperty 的值(StructAddress一定要指向要更改的Ustruct地址)

总结:

反射作为ue4魔改C++的一项功能,在编程过程中给我们提供了很大的便利,但是如果不能透彻理解它的真正含义,很容易在使用过程中给自己造成不必要的麻烦。另外现在获取更改UProperty 的值还限制在UBoolProperty、UEnumProperty、UNumericProperty、UObjectProperty、UArrayProperty、UStructProperty这几种。其中数字属性类, 其子类有 int32, int64, uint32, uint64, float, double等其它具体类型数字的属性类。我想要get/set Vector4类型的UProperty 还依然解决不了。可能对ue4反射还是不够了解。

补充:

get/set Vector4类型的UProperty可用以下代码实现:


				 FVector4 * Vector4Address = ChildProp->ContainerPtrToValuePtr<FVector4>(StructAddress);
				 Vector4Address->X = NewValue;
				 Vector4Address->Y = NewValue;
				 Vector4Address->Z = NewValue;
				 Vector4Address->W = NewValue;

 通过上面的方法基本上可以实现对任意类型的UProperty进行Set/Get.但是在对与UE4自带的bool类型有点问题:

 UProperty * ChildProp_b = ScriptStruct->FindPropertyByName(bOverrideName);
uint32  *ChildBoolProp = ChildProp_b->ContainerPtrToValuePtr<uint32 >(StructAddress);
				 bool(ChildBoolProp) = true;

  bool(ChildBoolProp) = true;

这段代码是有问题的,编译不会通过!

我发现UE4为了节省内存,将float类型以Uint32位域格式进行存储,使我在set的过程中出现了问题,如果以指针来Set

*ChildBoolProp = true;

会造成内存错乱,影响到其他相邻属性的值,这一块我还有一些疑惑,有待解决。。。。

引起错乱的原因:位域不支持指针和引用,最好是强转成bool类型再set值。

参考:https://answers.unrealengine.com/questions/711071/setting-value-of-uproperty.html

https://answers.unrealengine.com/questions/212756/setget-uproperty-inside-of-ustruct-directly.html?sort=oldest

https://answers.unrealengine.com/questions/296180/cant-set-uproperty-reflection-in-c-why.html?sort=oldest

https://www.jianshu.com/p/2c33860da041

猜你喜欢

转载自blog.csdn.net/qq_24835213/article/details/80081355