1,将一段逻辑改成一个函数,选中逻辑右键collapse to function即可写成了函数
3,求得两个向量的夹角,这里求得是一个箭头和角色的两个物体的面向夹角是否是75度以内也可以说箭头的方向是否在人物面向的150度以内
这里的。代表向量的相乘,acos也即反三角函数arccos
文章图片
4,Blend Poses By bool在动画状态机中通过该函数达到一个状态机下面使用多种动画,比如敌人拿着枪的时候不瞄准可以一边移动一边转向你得身边,但是瞄准的时候只能移动不能旋转就这样调用
文章图片
5,将HUD的血条显示和PlayerCharacter中的血量绑定并更新:
在PlayerCharacter中自定义事件PerformUpdateHealth,因为PlayerCharacter要和HUD同时调用一个函数因此采用事件调度器,创建一个UpdateHealth事件调度器,拖动到事件列表中选择调用,每次人物受到伤害就自动调用PerformUpdateHealth事件,再传入到事件调度器中
文章图片
在HUD中的Designer中设置好血条,在Graph中在事件Construct中拿到PlayerCharacter绑定事件调度器,注意的是,要从红色方框事件向外拉出创建一个自定义事件,而不是创建一个自定义事件再连到方框事件中
文章图片
如果将感觉血条掉血速度很快,用一个平滑的差值处理,做法如下:用一个TimeLine做平滑处理,也可以用sin等函数,起点0,0终点0.1,1再调用lerp来做差值
文章图片
6,在角色死亡时候调用死亡动画,设置bool值isDead默认false,死亡瞬间置为true,但是瞬间destroy敌人会导致isDead又恢复默认false,解决方法:死亡时刻延时2秒调用死亡动画。
7,要拿到animBulePrint首先要拿到该角色的mesh调用Get Anim Instance方法
文章图片
8,pawn可以直接转为子类的character,子类的character里可以拿到mesh组件
pawn可以拿到movement组件
9,开门关门动画代码:
文章图片
10,事件调度器:目前知道的是用于逻辑和界面交互的,在逻辑中把数据输入给定义好的事件调度器,在UI中绑定事件调度器,自定义事件将数据显示到控件上
11,当人物掉到地面就刷新怪物,给地面设置tag为land,人物character中碰撞到tag为land就触发
文章图片
犯错点:直接取数组的第0号元素,玩意数组没有元素呢。程序就崩了,所以要加上判定length>0才行。
12,对于渐变如果在HUD中不能在蓝图中用时间轴,要用动画,做法:添加动画,自定义动画名称,在时间轴中添加HUD的哪个组件,设置是哪个属性的渐变
文章图片
13,对于旋转rotation的信息可以右键Split Struct Pin转成3个角度的分量
文章图片
变成这样
文章图片
14,Clamp函数的作用,限制最大值和最小值
15,UE_LOG(LogTemp, Warning, TEXT("hitLocation:%s"),*HitLocation.ToString());
注意HitLocation.ToString()前面一定要加*否则报错
CompilerResultsLog: 信息with
CompilerResultsLog: 信息[
CompilerResultsLog: 信息T1=FString
CompilerResultsLog: 信息]
16,想了解引擎中类的继承结构,点击Windows(窗口)---->开发者工具----->类别查看器---->过滤器将仅actor去掉勾选
文章图片
17,.uasset文件导入不能直接拖,要移动到项目中的content文件夹中才能生成,把调试对象改成当前人物的即可
文章图片
18,游戏运行时要想知道逻辑运行到哪个分支
19,对于这种bug
或者行走动画一闪一闪的,解决办法,勾上就行
文章图片
还有把右侧的loop Animation去掉勾就行
文章图片
20,箭头的mesh为什么旋转了结果没反应呢?
文章图片
因为在代码中attach的Rotation Rule使用的Snap to target,因此它和目标的旋转是一样的,因此改成keep Relative
文章图片
导入坦克部分的总结:
对于人物靠近坦克按r键人物消失切换到坦克视角,做法:拿到gameMode,把Default Pawn切换成坦克,Controller从角色切换成坦克,但是拿到GameMode有set Default Pawn的函数但是没有set Controll的函数,因此可以共用一套controller,判断角色是人物还是坦克。
1,对坦克的FBX导入时不想让导入的是一对散乱的零件而是拼好的整体,将fbx拖动到资源弹出FBX导入选项,在mesh中选择Combine Meshes
2,将多个部分的组件拼接好的做法:创建蓝图类继承actor取名BP_Tank,添加static mesh在mesh选择Tank_Body,然后再加一个static mesh将它放到BP_Tank下面mesh选择左边坦克履带,调整好位置。再加static mesh加入右边履带
3,当然如果不用这种用相对位置拼接的方法还可以通过挂点的方式,步骤
文章图片
在右侧插槽管理器中创建插槽,存储其他组件的位置,
文章图片
最后再BP_Tank中添加static mesh选择LeftTrack在插槽中选择刚才创建的那个,这样不用设置相对位置就自动对应好位置了
文章图片
4,现在要一进游戏就控制坦克怎么控制呢?创建GameModeBase,打开,要想让控制坦克要让属性中的Default Pawn Class选择坦克,但是坦克是actor不是pawn,找到BP_Tank,类设置--->Class Options--->ParentClass把actor改成pawn
5,如果现在进游戏还不是坦克,打开项目设置,搜索Gamemode把Default GameMode改成创建的那个
文章图片
6,现在进入游戏有了坦克,但是视角不能左右移动,在tank蓝图类中添加摄像机,首先添加Spring Arm,在下面再加入相机,
文章图片
Spring Arm的作用是一个手臂举着相机,将Target Arm Length改成1200调整相机视角
文章图片
7,对于坦克相机的左右镜头和上下镜头的移动,设置好鼠标的pitch和yaw移动,
文章图片
如果想让坦克只是镜头转动但是坦克不动这样:对于tank这个pawn都不勾,但是相机都勾
文章图片
文章图片
效果如下:
如果想让坦克和镜头一起左右转,pawn勾选yaw(z轴转)相机全勾选
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
视频中是这样连的(他是只让相机转动,坦克不转,因此只给相机添加相对旋转):
这里Spring Arm是摇臂,由于摇臂的距离Target Arm Length设定比较远1200,因此根据鼠标的移动改变摇臂的旋转
文章图片
如果只连其中的一个,鼠标左右移动和上下移动视角都没问题,但是两个都连起来发现视角混乱,
原因是,假如向右移动一点再向上移动,发现相机已经被移乱了,视角已经倾斜了
文章图片
解决方法:添加一个空的组件Scene,该组件只有位置信息这样设置,把target用Scene连,
文章图片
这样相机永远是直立的不会反过来了
文章图片
对于Clamp函数是限定一个数的最小值和最大值,只能在这两个数之间。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
8两个Rotator相减
用Delta(Rotator),这个函数作用就是rotator相减取模
/** Normalized A-B */
UFUNCTION(BlueprintPure, meta=(DisplayName = "Delta (Rotator)", ScriptMethod = "Delta"), Category="Math|Rotator")
static FRotator NormalizedDeltaRotator(FRotator A, FRotator B);
FRotator UKismetMathLibrary::NormalizedDeltaRotator(FRotator A, FRotator B)
{
FRotator Delta = A - B;
Delta.Normalize();
return Delta;
}
文章图片
而一点一点旋转是用的Rinterp To这个函数
文章图片
如果用的动画蓝图的动画偏移,是这样的
文章图片
对于骨骼动画融合
文章图片
选择红框里的选项,动画图表里会出现一个新的节点
Base Pose — 基础的动画姿势下面我们将原来的状态机连到 Base Pose 节点, 并将
Blend Pose 0 — 我们想要混合进来的姿势0
Blend Weights 0 — 姿势0混合时所占的权重 (取值范围0~1)
添加引脚 — 可以继续添加混合的姿势 — 可以混合多个姿势进来
AnimMix
连到 Blend Pose 0 节点。然后再将混合后的姿势连到最终动画姿势里。
至此,还不能奏效, 因为我们并未设置从哪个骨骼上开始混合,也没有设置混合到什么程度 (权重)
所以接下来我们点击混合节点,可以看到右侧细节面板里出现了一些参数
点击 Branch Filters 后面的加号,会增加一个元素
可以看到 Branch Filters 里面有一个元素, 这个元素包含两个成员
Bone Name 表示想要混合的骨骼名称这里只有一个 Branch Filters, 当我们再多添加混合的姿势的时候 (即点击添加引脚), Branch Filters 也会随着它增多
Blend Depth 表示混合的深度,关于这个参数的设置,后面会详细说明
可以继续添加元素,以对不同的骨骼设置不同的混合深度
每一个 Branch Filters 对应着一个 Blend Poses
关于 Blend Depth Blend Depth 决定当前骨骼 (及其孩子骨骼) 混合到原动画的比重
当 Blend Depth 的取值为 0 到 1 之间的任何数 (包括0和1) 时, 当前的骨骼会完全取代原来的骨骼位置,完全混合进去举个比较实用的例子,
当 Blend Depth 的取值为 -1 时 (不建议取其他的负值), 当前的骨骼完全不会影响原来的骨骼位置,即完全不会混合
当 Blend Depth 的取值为 大于1 的任何数时, 随着这个数值的增加, 当前骨骼混合到原骨骼的程度逐渐减小
如果现在我们只想融合胳膊上部,那么我们可以将整个胳膊的父骨骼的 Blend Depth 设置为 1 (或0)
然后将 胳膊下部的父骨骼的 Blend Depth 设置为 -1
这样整个胳膊的下部就不会融合进去了
原理 Blend Depth 在 ue4 中的源代码位置记录如下, 方便以后详查
//Engine\Engine\Source\Runtime\Engine\Private\Animation\AnimationRuntime.cpp 1280行void FAnimationRuntime::CreateMaskWeights(TArray& BoneBlendWeights, const TArray& BlendFilters, const USkeleton* Skeleton)
{
if ( Skeleton )
{
const FReferenceSkeleton& RefSkeleton = Skeleton->GetReferenceSkeleton();
const int32 NumBones = RefSkeleton.GetNum();
BoneBlendWeights.Reset(NumBones);
BoneBlendWeights.AddZeroed(NumBones);
// base mask bone
for (int32 PoseIndex=0;
PoseIndex(BoneBlendWeight.BlendWeight + BlendIncrease, 0.f, 1.f);
}
}
}
}
}
}
}
【UE4总结四】
推荐阅读
- 使用虚幻引擎中的C++导论
- Scripting the Editor using Python
- 虚幻4DPI自适应缩放规则解析
- 【UE4_C++】<14-3>用户界面 UI和UMG——为UI创建屏幕尺寸自适应缩放
- UE4血条、名字面向相机
- UE4|UE4C++ 设置UMG控件的Slot
- UE4|AirSim里的那些坑