《UE4游戏开发》之 《使用小技巧》

  1. 如果遇到在这里插入图片描述原来写的创建类蓝图,需要暴露新的参数,但是创建类蓝图节点没有刷新,即暴露出来的参数没有显示,可以重新定位到创建蓝图,然后重新赋值Class,这样暴露出来的属性就可以看见了,我这里是参数IsDraw

  2. 当在调试动作或特效等局内表现的时候,需要放慢动作的播放,可以使用控制台命令slomo +时间(比如0.5),来实现放慢,好观察表现是否正确

  3. 宏函数库或者宏函数,如何设置参数类型为引用在这里插入图片描述

  4. 见上图,通过使用在这里插入图片描述节点,通过鼠标左键从target参数向Input【输入】节点,出现上截图AddPinToNode,松开鼠标,即可添加引用参数,修改合适的名字即可

  5. 在界面上要控制浮点数显示的精度设置,关键节点:在这里插入图片描述,点击这个下拉倒三角形符号在这里插入图片描述ue4中,把浮点数,看成整数部分和分数部分,截图节点可以控制整数部分的最小位数和最大位数,也可以控制分数【小数】部分的最大和最小位数;RoundingMode可以设置浮点数在保留指定位数时,如何取舍值的方式,详情可以参考该结构体的定义;当UseGrouping=true时,将会把整数部分用","隔开在这里插入图片描述,当UseGroupingMode = false时,整数部分不会用“,”隔开,在这里插入图片描述
    在这里插入图片描述AlwaysSign=true时,会把正负号加上,如:800,显示+800;否则,800,显示800【小结:遇到类似节点,可以类推】

  6. 在蓝图中,如何拼写换行的字符串:Shift+Enter键,即可添加换行【下面截图:是通过for循环,拼写带换行的字符串,其换行的关键节点就是Select节点】在这里插入图片描述

  7. 当需要实现,特效与游戏伤害匹配时,需要动态改变粒子特效的生命周期,其本质就是动态修改粒子模块的控制参数:在粒子模块中,参数类型选择 Distribution Vector Particle Parameter,命好变量名称【LifeTime】,在这里插入图片描述
    代码控制截图:在这里插入图片描述
    PS:如果需要一个变量控制不同粒子模块,只需要变量名完全相同,且变量的类型和值的范围相同,即可。如本例中变量【LifeTime】同时控制2个粒子模块

  8. 在c++代码处打打断点,发现堆栈有如下截图时【即蓝图调用c++代码】:在这里插入图片描述可以在vs中的Immediate Widow,输入{,UE4Editor-Core}::PrintScriptCallstack(),查看具体蓝图调用的堆栈在这里插入图片描述

  9. 项目中模块的管理是记录在:XXX.uproject文件里面,当模块出错,可以在这里暂时屏蔽

  10. 调试打包出来的debug/shiping包时,方法【前提都需要pdb调试文件在exe同目录】:
    (1) 通过vs,attach to Process,调试在这里插入图片描述
    (2)通过打开工程,设置ue4为启动项,并设置ue4工程的属性如下【修改Working Directory:exe所在的目录和Command:完整的exe路径】在这里插入图片描述

  11. 调试打包出来的debug/shiping包时,单步调试时,代码乱跳,可以将DebugGame改成Debug【前提:使用源码引擎,否则没有Debug选项
    .在这里插入图片描述

  12. 调试时防止变量被优化:通过PRAGMA_DISABLE_OPTIMIZATION和PRAGMA_ENABLE_OPTIMIZATION包裹自己代码部分,可以防止被包裹部分的代码变量被优化:

// Copyright Epic Games, Inc. All Rights Reserved.

#include "BoneControllers/AnimNode_CCDIK.h"
#include "Animation/AnimTypes.h"
#include "AnimationRuntime.h"
#include "DrawDebugHelpers.h"
#include "Animation/AnimInstanceProxy.h"

PRAGMA_DISABLE_OPTIMIZATION
/
// AnimNode_CCDIK
// Implementation of the CCDIK IK Algorithm

FAnimNode_CCDIK::FAnimNode_CCDIK()
	: EffectorLocation(FVector::ZeroVector)
	, EffectorLocationSpace(BCS_ComponentSpace)
	, Precision(1.f)
	, MaxIterations(10)
	, bStartFromTail(true)
	, bEnableRotationLimit(false)
{
}

FVector FAnimNode_CCDIK::GetCurrentLocation(FCSPose<FCompactPose>& MeshBases, const FCompactPoseBoneIndex& BoneIndex)
{
	return MeshBases.GetComponentSpaceTransform(BoneIndex).GetLocation();
}

#if WITH_EDITOR
void FAnimNode_CCDIK::ResizeRotationLimitPerJoints(int32 NewSize)
{
	if (NewSize == 0)
	{
		RotationLimitPerJoints.Reset();
	}
	else if (RotationLimitPerJoints.Num() != NewSize)
	{
		int32 StartIndex = RotationLimitPerJoints.Num();
		RotationLimitPerJoints.SetNum(NewSize);
		for (int32 Index = StartIndex; Index < RotationLimitPerJoints.Num(); ++Index)
		{
			RotationLimitPerJoints[Index] = 30.f;
		}
	}
}
#endif 

void FAnimNode_CCDIK::InitializeBoneReferences(const FBoneContainer& RequiredBones)
{
	DECLARE_SCOPE_HIERARCHICAL_COUNTER_ANIMNODE(InitializeBoneReferences)
	TipBone.Initialize(RequiredBones);
	RootBone.Initialize(RequiredBones);
	EffectorTarget.InitializeBoneReferences(RequiredBones);
}

void FAnimNode_CCDIK::GatherDebugData(FNodeDebugData& DebugData)
{
	DECLARE_SCOPE_HIERARCHICAL_COUNTER_ANIMNODE(GatherDebugData)
	FString DebugLine = DebugData.GetNodeName(this);

	DebugData.AddDebugItem(DebugLine);
	ComponentPose.GatherDebugData(DebugData);
}

PRAGMA_ENABLE_OPTIMIZATION
  1. 使用Debug【可以避免断点乱跳问题】在这里插入图片描述通过命令启动调试游戏,出现在这里插入图片描述只需将打包引擎对应目录下dll,拷贝至打包游戏后对应的目录,即可解决

  2. LineTraceByChannel节点可以直观debug在这里插入图片描述
    当DrawDebugType的值为:Persistent时,可以看到如下可视化的红线在这里插入图片描述

  3. 将一个范围的值normal至0到1:【0-1可以用来驱动曲线资产】在这里插入图片描述

  4. 限定输入和输出范围用【0-1去驱动】在这里插入图片描述

  5. 粒子系统中的蓝图事件是:在非GPU发射器中,才能生效的,如果标识的是GPU Sprite将不会生效
    在这里插入图片描述并且可以设置事件触发的频率【如果时触发音效,可以防止因粒子的频率高,导致过多的音效生成】在这里插入图片描述

  6. 通过粒子系统事件绑定实现声音时,由于节省性能,不在摄像机视口内的内容将不会渲染,因此在粒子系统中绑定的事件也不会触发,即声音不会播放,处理方法:点击非粒子发射器面板,将会出现设置粒子系统的面板,设置红圈中参数,则玩家在这个范围内就会听到声音
    在这里插入图片描述

  7. 要想在这里插入图片描述这个事件触发,需要设置staticmeshcomponent的SimulationGeneratesHitEvent为true

在这里插入图片描述
20. 在ue4中,查看Verbose级别的日志:需要在自己工程下DefaultEngine.ini添加
[Core.Log]
global=Verbose

PS:该级别日志不会在控制台窗口打印,只能去对应的log文件里面去查看
21. 通过UFUNCTION(exec)这种声明的函数,可以直接输入命令启动,命令就是:函数名字;UFUNCTION(exec)
void ReportMatchResult();
调出命令输入ui,直接输入:ReportMatchResult即可
22. UObjectGlobals.h->FindObject:【Tries to find an object in memory】是在内存中找,而不是磁盘,所以当返回的指针是null时,表示在内存中没找到,并不代表在磁盘中没有相关信息,所以需要再在磁盘中加载

/**
 * Find an optional object.
 * @see StaticFindObject()
 */
template< class T > 
inline T* FindObject( UObject* Outer, const TCHAR* Name, bool ExactClass=false )
{
	return (T*)StaticFindObject( T::StaticClass(), Outer, Name, ExactClass );
}
/**
 * Tries to find an object in memory. This will handle fully qualified paths of the form /path/packagename.object:subobject and resolve references for you.
 *
 * @param	Class			The to be found object's class
 * @param	InOuter			Outer object to look inside. If this is ANY_PACKAGE it will search all in memory packages, if this is null then InName should start with a package name
 * @param	InName			The object path to search for an object, relative to InOuter
 * @param	ExactClass		Whether to require an exact match with the passed in class
 *
 * @return	Returns a pointer to the found object or nullptr if none could be found
 */
COREUOBJECT_API UObject* StaticFindObject( UClass* Class, UObject* InOuter, const TCHAR* Name, bool ExactClass=false );
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值