1.如何让客户端自动连接服务器
MyGame.exe 127.0.0.1
通过命令行参数指定服务器IP,就会自动进入游戏
参考:https://docs.unrealengine.com/latest/CHN/Programming/Basics/CommandLineArguments/index.html
2.如何以spectator模式启动客户端
在ULocalPlayer的派生类中重写GetGameLoginOptions函数,具体如下
FString UShooterLocalPlayer::GetGameLoginOptions() const
{
return TEXT("SpectatorOnly=1");
}
3.如何解决ue4 vs 调试不能看到FString等变量值的问题
Visual Studio支持通过‘可视化查看器’来扩展调试器,从而轻松地查看常见的虚幻数据类型, 比如对象FNames 和动态数组。根据您所使用的Visual Studio 2010或Visual Studio 2012的不同, 这个功能的设置也有所区别。
您会发现您的安装文件中包含了具备该可视化查看器逻辑的文件:
[ROCKETINSTALL]/Engine/Extras/VisualStudioDebugging/UE4.natvis
复制该文件到以下位置:
[VSINSTALLDIR]/Common7/Packages/Debugger/Visualizers/UE4.natvis
[USERPROFILE]/My Documents/Visual Studio 2012/Visualizers/UE4.natvis
参考:https://docs.unrealengine.com/latest/CHN/Programming/Development/VisualStudioSetup/index.html
4.ShooterGame 中LOS是什么意思
应该是 Line-of-sight 的意思
5.C++如何在屏幕上打印输出
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, NewControlRotation.ToString());
6.shootergame中projectile是如何检测碰撞的
在ProjectileMovementComponent.cpp中MoveUpdatedComponent函数调用
7.ue4中打包出来地图可以运行,从源码编译选择Development确不能运行,提示加载地图失败,怎么解决
在编辑器中烘培一下该地图,再进就可以(File->Cook Content For Windows)
8.在游戏中,给pawn加了一个发射子弹时的动作,但发现有时播放,有时不播放,后来发现是因为子弹个数问题,之前的逻辑子弹为0时播放会重新装弹,所以没有播放发射子弹的动作
9.函数前加 UFUNCTION(exec) 是什么意思
加了这个指明该函数可以在控制台执行
10.如何决定一个Actor是否需要同步
代码在ActorReplication.cpp中,IsNetRelevantFor函数
具体代码如下:
bool AActor::IsNetRelevantFor(const AActor* RealViewer, const AActor* ViewTarget, const FVector& SrcLocation) const
{
if (bAlwaysRelevant || IsOwnedBy(ViewTarget) || IsOwnedBy(RealViewer) || this == ViewTarget || ViewTarget == Instigator)
{
return true;
}
else if ( bNetUseOwnerRelevancy && Owner)
{
return Owner->IsNetRelevantFor(RealViewer, ViewTarget, SrcLocation);
}
else if ( bOnlyRelevantToOwner )
{
return false;
}
else if ( RootComponent && RootComponent->AttachParent && RootComponent->AttachParent->GetOwner() && (Cast(RootComponent->AttachParent) || (RootComponent->AttachParent->GetOwner() == Owner)) )
{
return RootComponent->AttachParent->GetOwner()->IsNetRelevantFor(RealViewer, ViewTarget, SrcLocation);
}
else if( bHidden && (!RootComponent || !RootComponent->IsCollisionEnabled()) )
{
return false;
}
if (!RootComponent)
{
UE_LOG(LogNet, Warning, TEXT("Actor %s / %s has no root component in AActor::IsNetRelevantFor. (Make bAlwaysRelevant=true?)"), *GetClass()->GetName(), *GetName() );
return false;
}
if (GetDefault()->bUseDistanceBasedRelevancy)
{
return ((SrcLocation - GetActorLocation()).SizeSquared() < NetCullDistanceSquared);
}
return true;
}
参考文档:https://wiki.beyondunreal.com/Everything_you_ever_wanted_to_know_about_replication_(but_were_afraid_to_ask)
11.FString转int32
Color = FCString::Atoi(*ColorStr)
ColorStr类型为FString,Color类型为int32
12.int32转FString
FString::FromInt(Color)
13.UnrealTournament编译报错
编译UnrealTournament Master,报错,后来查是因为本身代码有问题,然后下载了release版,链接报错 error LNK1181 Box2D.lib
解决方法,找到UnrealTournamentEditor.Target.cs文件,UEBuildConfiguration.bCompileBox2D 由false改为true,再编译,就正常了
14.如何重新生成generated.h文件
ue4中,很多头文件都会预编译一遍,生成对应的generated.h,比如,ShooterBot会生成ShooterBot.generated.h。有时候我们希望generated.h重新生成,怎么办呢,只需要修改对应的头文件,generated.h就会重新生成
15.Actor中使用了胶囊体(UCapsuleComponent),当actor被放入场景的时候,胶囊体的中心在地面上,但把Pawn拖到场景时,胶囊体的底贴在地面上,这是什么原因呢
Actor中有个成员变量bCollideWhenPlacing,在Pawn的构造函数中被初始化为了true,所以胶囊体底部会贴着地面,如果想让你的物体(派生自Actor)也有同样的效果,只要在物体的构造函数中加入bCollideWhenPlacing=true就可以了
16.ue4接htc vive看到的画面不正确,像是反了一样
htc vive有问题,但oclus没有问题,后来发现时PostProcessVolume里面的一个参数设置问题
具体参数是 ScreenPercentage 的问题,默认值是100,我们游戏里改为了125,改回100就好了
17.ue4崩溃,具体说是一个verify没过,卡在了LevelTick.cpp 777行
解决办法:把这个verify去掉就好了
verify(ComponentsThatNeedEndOfFrameUpdate.Remove(WeakComponent) == 1);
改为
ComponentsThatNeedEndOfFrameUpdate.Remove(WeakComponent);
18.ue4 C++项目如何重命名
https://answers.unrealengine.com/questions/242407/renaming-a-c-project.html
19.如何开关某个分类的log
如:打开logGarbage
log loggarbage all
log logtexture off 关闭logtexture类log输出
20.SpawnActor后没有调用BeginPlay
调试发现是因为SpawnActor调用过早导致的,只有在UWorld的bBegunPlay被设置为true以后,spawnactor时,beginplay才会被调用
注意,尤其是在多人游戏客户端spawnactor时,clientgamestarted时,bBegunPlay不一定会被设置为true,跟网络和加载速度都有关
21.如何在log里输出指针的值
源码里有现成的
UE_LOG(LogGarbage, Fatal, TEXT("Invalid object in GC: 0x%016llx, ReferencingObject: %s, ReferencingProperty: %s"),
(int64)(PTRINT)Object,
InReferencingObject ? *InReferencingObject->GetFullName() : TEXT("NULL"),
InReferencingProperty ? *InReferencingProperty->GetFullName() : TEXT("NULL"));
22.如何查看一个对象在对象列表里的值
int32 Index = Object->InternalIndex;
GUObjectArray.ObjObjects.Objects[Index]
23.获取level began play到现在的时间
MyWorld->TimeSeconds;
24.BlendSpace播放动画出现动画不连贯问题如何解决
以BlendSpace处理移动为例,当Speed突然变为0时,当前动作会由移动突然变为idle,此时由于动画又移动突变为idle,当移动动作和idle动作差别比较大时,就会明显感觉
动画跳跃了一下,会显得很不连贯,BlendSpace中有个参数TargetWeightInterpolationSpeedPerSec可以解决这个问题,可以让这两帧动画平滑过渡。
25.如何避免滑步
移动动作一旦做好了,速度就确定了,这个速度是一个固定值,美术需要保证在这个速度下移动,不出现滑步(地面脚的移动速度要等于角色的移动速度),然后程序用这个速度设置角色的移动速度就能避免滑步了。
26.ue4 3D widget半透明问题
用widget component处理3D UI,发现半透明的图在场景里要么全透明,要不全不透明,没有中间状态,后来发现widget component有个属性BlendMode,默认是Masked,改成Transparent就好了
27.ue4实现转身
动作资源只有四个转身动作(左转90度,左转180度,右转90度,右转180度),如何实现较为平滑的转身呢?
目前采用的转身方案如下:
分情况讨论
1.当前Yaw和目标Yaw相差绝对值<45度,直接用插值方式旋转整个Actor(RInterp To)
2.当前Yaw和目标Yaw相差绝对值>=45度并且<=135度,播放旋转90度动作(具体向左向右根据差值的符号),然后再使用步骤1的方法
3.当前Yaw和目标Yaw相差绝对值>135度,播放旋转180度的动作(同上),然后再使用步骤1的方法
28.ue4实现跳跃
动作资源有三个(JumpUpAnim,JumpDownAnim,JumpLandAnim)
JumpUp为起跳时播放的动作,JumpDown为跳到最高点后下降播放的动作,JumpLand为落地播放的动作
ue4中Character内置了跳跃功能,所以只需在动画蓝图里实现跳跃相关的状态就可以了
具体需要JumpUp、JumpLoop、JumpEnd三个状态,假设AI只有在Walk状态会切换至JumpStart状态,那么Walk切换至JumpStart的条件为SpeedZ>0,JumpStart切换至JumpLoop的条件为SpeedZ<0,JumpLoop切换至JumpEnd条件为SpeedZ==0。JumpEnd切回Walk条件为Land动作播放完成,在动画蓝图中可用TimeRemaining结点来判断。
29.ue4实现自然的死亡
比较自然的死亡是使用物理模拟,但如果纯使用物理模拟,打击感就会比较弱,比较好的做法是做八个方向的死亡动作,每个死亡动作做到一半的时候开启物理模拟(死亡动作本身就只有一半),这种做法在大部分情况是没有问题的,但当死亡动作会穿透障碍物时,开启物理模拟,角色有可能会被弹得很远,这取决于角色跟障碍物的重叠程度。所以想到的解决方案是,检测角色跟障碍物碰撞的瞬间,开启物理模拟。怎么检测呢,一个方法是SkeletalMesh的BeginOverlap,但这种做法并没有检测到事件(就算可以检测,效率也比较低),还一个就是想到OnComonentHit事件,这个事件只有开启物理模拟后才会触发,所以也不能用。最后想到的方法是,在Mesh上加碰撞体,让碰撞体挂到Spine和Head关节上(具体挂哪个关节跟模型相关),然后检测碰撞体跟障碍物的碰撞事件,在事件处理中开启物理模拟,测试后效果很完美。
30.NavLinkProxy不起作用
自己实现了一个BTTask_MoveToActor行为树节点,在节点内部调用AIMoveTo方法实现移动到目标点,发现NavLinkProxy不起作用,但是在调用AIMoveTo之后Delay1到2秒,发现就起作用了,后来发现是由于每帧都在调用AIMoveTo引起的,改成只有在移动目标切换或当前移动速度为0时,才调用AIMoveTo就好了。
31.ReplicatedUsing如何获取被覆盖前的值
拿ShooterGame中的ShooterCharacter中的CurrentWeapon属性举例,
UPROPERTY(Transient, ReplicatedUsing=OnRep_CurrentWeapon)
class AShooterWeapon* CurrentWeapon;
UFUNCTION()
void OnRep_CurrentWeapon(class AShooterWeapon* LastWeapon);
OnRep函数可以带一个参数,也可以不带参数,如果带一个参数,此参数类型只能和被标记的属性一致,代表之前被覆盖的值
32.ue4中有提供角度标准化的方法吗(即把角度标准化到(-180,180]范围内)
有的,在Rotator.h中
/**
* Clamps an angle to the range of (-180, 180].
*
* @param Angle The Angle to clamp.
* @return The clamped angle.
*/
static float NormalizeAxis( float Angle );
33.Actor位置不同步问题
正常情况下,Actor在勾选了Replicates和ReplicateMovement后,在服务器修改Actor的位置,会自动同步到客户端,
但需要注意,当Actor被隐藏后,Actor的位置是不会同步到客户端的
34.ue4蓝图中如何调用基类Event(比如BeginPlay)
如上图所示,4.21版本,搜索方法找不到基类方法,在该事件上右键,点击Add call to parent function即可
35.多人联网游戏时,客户端如何获取当前服务器时间(4.21版)
GameStateBase中,GetServerWorldTimeSeconds方法,如下图: