我对原文的格式进行了调整,并标注了部分重点
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 值。
参考
- answers.unrealengine.com/questions/7…
 - answers.unrealengine.com/questions/2…
 - answers.unrealengine.com/questions/2…
 - www.jianshu.com/p/2c33860da…
 
8. 更改 UE4 版本编译报错 All source files in module XXXXXX must include the same precompiled header first
解决方法
将这行代码加入到 build.cs 中
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
9. Rotate to face BB entry
大家在编写行为树的时候,经常会遇到需求就是要把操作目标转向某人,面对某人,UE4 的行为树中,为我们提供了节点 Rotate to face BB entry ,从字面意思可以理解到就是 “把脸转向xx” ,但是很多朋友在设置的时候发现根本无效,我说的无效是说把节点添加后出现转向是瞬间转动,并没有光滑过度,那么应该怎么办呢?
这一点 UE 本身并没有说明,需要我们做两个设置!
- 
要在控制的 Character 的根节点关掉 Use Controller Rotation Yaw
 - 
开启控制 Character 下的 CharacterMovement 组件的 Use Controller Desired Rotation