我的第一个游戏开发日志
2022/04/04
制作第一个关卡:一个房间,包括一个落地窗,床,桌子,卫生间,门,如果可以的话加上一个窗帘
首先复习一下LightingShadow这个快速指南。然后用BSP Brash绘制房间的边界,再加入家具(需要参考油管bsp to mesh的视频)
2022/04/06
重新建了一个level1,这次直接用mesh来搭房子,门框和窗户框是通过BSP brush来做的,因为需要剔除门的空间。然后把brush生成mesh,再添加材质。
测试遇到的问题
从brush生成的mesh不受光照影响,也就是说材质没有被反射,玩家视角看到的是黑色的。
需要做的改动如图,光照贴图分辨率参考其他的墙mesh设置为128,光照贴图坐标索引设为1。
当前的mesh默认是没有碰撞的,也就是说玩家会穿墙,对于窗户框来说,添加盒体简化碰撞(当前不希望玩家能穿过窗户),而对于门框来说,可以通过添加凸包碰撞来自动设置,但是精度有限。
通过添加盒体碰撞然后自定义范围来规划碰撞体积。效果如图
2022/04/07
今天想做游戏的开头,玩家躺在床上的视角,遇到了问题。
先把玩家放在床上
然后简化了床的碰撞盒
但是游戏运行的时候,玩家无法躺在床上
但是如果勾选胶囊物理效果就可以躺下
或者把胶囊碰撞体缩小
还有一种我觉得比较好的解决方法是把默认的胶囊缩小,然后再新建一个和人等大的胶囊
之所以要重新添加一个胶囊是因为我怀疑原来的胶囊碰撞体根本无法旋转
还有一个原因我觉得是本身这个场景就不应该用character而是应该用pawn
今天还看了官方的第三人称教程 到12P,还有几个设置没太搞懂,先截图记录下来。均取自character蓝图类。
类默认设置–Pawn–使用控制器旋转Yaw
移动组件–角色移动(旋转设置)–使用控制器所需的旋转/将旋转朝向运动
2022/04/08
明天计划先把第三方教程过一遍,然后找mixamo导入unreal和动画相关的教程,第一场景新建一个pawn类来做。
第三人称游戏的教程没有过完,mixamo导入unreal实现了,但还有缺陷。今天没有做实际的游戏开发。
2022/04/09
计划看官方骨骼的视频,然后学习蒙皮权重相关的知识。
2022/04/10
2022/04/11
游戏内摄像机的切换方法
案例参考官方文档 ,思路类似actor之间的通信,把Character蓝图的PlayerController组件里的的相机做替换。
2022/04/12
限制摄像机转动角度的方法,关键词 camera rotation limit
油管教程就不贴了,后来看到了一个比较简单的方法
虽然不清楚对后续开发是否有影响,反正目前想要达成的目的算是实现了。没想到还有这么简单的方法。
dialog
开发过程中的一些技术总结
关于玩家摄像机镜头的调整
- UE4的第一人称模板中,player是由手臂和枪组成的,与相机绑定。
在相机的细节中勾选使用Pawn控制旋转
这种相机设置的效果就是相机始终和枪口在一个方向。
但是像吃鸡这样的第一人称游戏中,低头会看到玩家自己的躯干。
为了实现这样的效果,可以修改第三人称模板来实现。
方法参考油管视频
- 在第三人称的模板中把相机挂在弹簧臂下面,弹簧臂像自拍杆一样与actor保持固定距离。
同样在相机的细节中勾选了使用Pawn控制旋转 。
相机的修改如下:删除弹簧臂,然后把相机挂载在mesh下面。在插槽中选择head,然后调整相机的transform。可以修改FOV,把相机下移到胸口附近,这样可以在低头时看到手。
然后在相机的设置中勾选使用Pawn控制旋转,勾选后表示可以通过鼠标来旋转相机,但是会出现旋转过头的现象,玩家的头是无法旋转360度的。
造成这种问题的原因可以理解为相机在旋转的时候,玩家并没有旋转,如果玩家可以跟着旋转的话,相机的角度就不会过大了。
在最上一层的actor设置中勾选使用控制器旋转Yaw
最后游戏中低头的效果,目前稍微有点穿模。
坐标系相关的总结
直接说结论,坐标系的方向遵循笛卡尔左手坐标系。
首先这是UE4空白项目的世界坐标系
在维基百科中,笛卡尔坐标系分为左手和右手两种
由图可知UE4是遵循左手坐标系,而XYZ的顺序也是按照自然法则的顺序来命名的。
最后是关于旋转的定义,三个轴的旋转对应飞机的航偏轴,直接上图
唯一需要记忆的是XYZ对应的旋转顺序是Roll Pitch Yaw
X | Y | Z |
---|---|---|
R | G | B |
大拇指 | 食指 | 中指 |
Roll | Pitch | Yaw |
关于蓝图的迁移
记录蓝图迁移的方法是因为考虑到以后会经常性的把其他项目的蓝图整合到自己的游戏里面。如果能够顺利迁移的话可以提高开发的效率。
这次迁移的案例是把第三人称模板里的角色蓝图迁移到一个新的空白项目中。
这个蓝图的父类是character,蓝图中使用了UE自带的mesh人物,绑定了默认的动画,定义了基本的移动。
从迁移的内容中可以看到相互绑定的关系。(所以在资源迁移的时候并不是单单的把这一个蓝图文件拷贝过去)
可以看到实际迁移的资产包括动画,材质,纹理,男女两个mesh,和最开始介绍的蓝图 (如果迁移的是同名游戏模式,则蓝图的最下面还包括了游戏模式蓝图)
把这些内容迁移到一个新建的空白项目中,需要迁移到content/ 的目录下
把蓝图拖到游戏场景中发现并不能像第三人称模板一样运行,接下来设置其他的地方
将拖入场景的ThirdPersonCharacter的pawn改成玩家0,这样游戏开始时默认的视角就不是player start了
新建一个game mode,把默认pawn改成ThirdPersonCharacter
在项目设置–地图和模式–默认游戏模式 改为刚才新建的名字
在项目设置–引擎–输入 中导入第三人称模板的配置文件
回到游戏中可以发现角色被完整的移植了过来
Actor通信的方法
**通过蓝图实现Actor通信的方法,参考自 官方文档 **
Actor之间的通信可以理解为玩家按下按键让灯亮或者是玩家靠近一个门,门自动打开。
直接通信
在玩家蓝图中新建一个公开变量,变量类型是灯的蓝图类,通过直接访问灯的组件来控制的亮灭
这种方法最后需要在游戏场景中的玩家设置中指定lamp reference是谁,这里指定的是一个实例。
类型转换
用cast to来判断是否是目标actor,这个案例中玩家靠近灯后灯会灭,远离后灯会亮。
给玩家添加一个球形碰撞检测,分别在重叠和离开的时候设置灯的亮灭。
图中的两个事件是右键Sphere选择的,这种方法相比第一种不需要特殊指定,也就是说在地图里放很多Blueprint Ceiling Light都可以与之互动。
接口
这个案例中,玩家靠近灯时灯灭,远离时灯亮。通过接口实现的好处就是接口可以重用,其他的类也可以使用接口,只不过实现的具体方法不同。
首先新建一个蓝图接口,在接口中定义Turn On和Turn Off两个函数。
玩家与actor重叠时调用接口。
在灯的蓝图中先勾选实现接口
然后实现接口中的函数
事件分发器
在这个案例中,玩家每当靠近或远离灯时,不仅会让灯亮灭,还会让触发一个爆炸特效。
事件分发可以理解为视频网站更新视频,即
- 创建一个视频频道
- 有观众订阅这个频道
- 这个频道发布新视频
- 订阅了这个频道的观众会受到新视频的通知
为了方便把玩家当作是视频频道,而玩家每次与灯触发的事件视作发布一个新的视频,即第一步和第三步
灯和爆炸特效为了订阅这个频道需要创建一个玩家类的公开变量,这里就叫做Subscribe。对应第二步和第四步。
通过C++实现Actor通信
- 直接通信
玩家按F键 灯亮
创建Actor类来定义灯,头文件中添加场景组件,点光源组件,静态网格组件,实现灯开关的自定义函数和一些数据成员,然后再构造函数中对这些成员进行定义。—-自此完成了对CeilingLight类的定义
1
2//CeilingLight.cpp
void ACeilingLight::TurnOffLight() {...} //开关函数基于这个C++类创建蓝图类,给蓝图类添加mesh素材。然后把蓝图类拖到场景中实例化,完成了从类到对象的过程。
进入玩家类的头文件
1
2
3
4
5
6//Character.h
//有什么办法可以按键后让场景中的所有灯都亮灭??
protected:
UPROPERTY(EditInstanceOnly, BlueprintReadWrite)
class ACeilingLight* CeilingLightToToggle; //继承类
void ToggleCeilingLight(); //开关函数定义成员函数
1
2
3
4
5
6
7
8//Character.cpp
void ACharacter::ToggleCeilingLight()
{
if (CeilingLightToToggle)
{
CeilingLightToToggle->TurnOffLight(); //通过指向对象的指针来调用函数
}
}定义交互方式
1
2
3
4
5
6//Character.cpp
ACharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
...
PlayerInputComponent->BindAction("Use", IE_Pressed, this, &ACharacter::ToggleCeilingLight); //当按键时调用开关函数
}目前已经在玩家的类中继承了一个灯的类,如果想通过按键实现让灯亮灭还要指定这个灯(对象)是谁
- 类型转换
玩家靠近时灯亮,远离时灯灭
灯的设置不变
玩家类中添加用于碰撞检测的球和碰撞事件
1
2
3
4
5//Character.h 这次不需要继承ceilinglighting类了
protected:
virtual void NotifyActorBeginOverlap(AActor* OtherActor);
virtual void NotifyActorEndOverlap(AActor* OtherActor);
class USphereComponent* SphereComp; //球体组件实现成员函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16//Character.cpp
//如果类型转换成功,则直接调用成员函数
void ACharacter::NotifyActorBeginOverlap(AActor* OtherActor)
{
if (ACeilingLight* ActorCheck = Cast<ACeilingLight>(OtherActor))
{
ActorCheck->TurnOffLight();
}
}
void ACharacter::NotifyActorEndOverlap(AActor* OtherActor)
{
if (ACeilingLight* ActorCheck = Cast<ACeilingLight>(OtherActor))
{
ActorCheck->TurnOffLight();
}
}可以看到这个案例中,类型转换比直接通信相比,首先玩家类不需要去继承灯的类了,因此也不需要去指定游戏场景中的灯对象。其次是可以在游戏场景中放置多个灯,都可以触发亮灭的逻辑。
- 接口
初始化接口
1
2
3
4//InteractInterface.h
public:
UFUNCTION()
virtual void OnInteract() = 0; //纯虚函数在灯的头文件中声明接口
1
2
3
4
5
6
7//CeilingLight.h
UCLASS()
class ProjectName_API ACeilingLight : public AActor, public IInteractInterface //多重继承
{
public:
virtual void OnInteract();
}实现接口
1
2
3
4
5//CeilingLight.cpp
void ACeilingLight::OnInteract()
{
TurnOffLight(); //这个函数跟之前介绍的一样
}在玩家类中调用接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16//Character.cpp
//如果碰撞体实现了接口,那么调用它的接口的函数
void ACharacter::NotifyActorBeginOverlap(AActor* OtherActor)
{
if (IInteractInterface* ActorCheck = Cast<IInteractInterface>(OtherActor))
{
ActorCheck->OnInteract();
}
}
void ACharacter::NotifyActorEndOverlap(AActor* OtherActor)
{
if (IInteractInterface* ActorCheck = Cast<IInteractInterface>(OtherActor))
{
ActorCheck->OnInteract();
}
}- 事件分发器 (运行游戏时会崩溃,编译没有问题)
假如玩家触发了A事件,那么绑定过A事件的actor会调用自己的函数。可以把A事件独立出来作为一个actor类,因此玩家不需要主动进行碰撞检测。
玩家类还原为默认,不需要做修改。
创建一个盒体类用于声明委托
1
2
3
4
5
6
7
8
9//EventActor.h
DECLARE_DELEGATE(FOnBossDiedDelegate);
...
UPROPERTY(EditInstanceOnly, BlueprintReadWrite)
class UBoxComponent* BoxComp; //盒体组件
virtual void NotifyActorBeginOverlap(AActor* OtherActor); //用于碰撞检测
FOnBossDiedDelegate OnBossDied; //这种写法好像类和对象
UFUNCTION()
void HandleBossDiedEvent(); //1
2
3
4
5
6
7
8
9
10//EventActor.cpp
void AEventActor::NotifyActorBeginOverlap(AActor* OtherActor)
{
HandleBossDiedEvent(); //当有actor碰到盒体时,调用事件
}
void AEventActor::HandleBossDiedEvent()
{
OnBossDied.ExecuteIfBound(); //这个事件激活了委托,那么绑定了OnBossDied的类都会有所反应!
}灯的类中添加对委托的引用
1
2
3//CeilingLight.h
UPROPERTY(EditInstanceOnly, BlueprintReadWrite)
class AEventActor* EventActorReference;1
2//CeilingLight.cpp 这句话会造成程序崩溃
EventActorReference->OnBossDied.BindUObject(this, &ACeilingLight::TurnOffLight); //灯的开关函数绑定OnBossDied在关卡蓝图种实现actor通信
- 案例:玩家靠近碰撞盒后灯亮
制作UE插件的方法
使用BSP Brush的心得
首先关于Brush是干什么的?
上图是从BSP生成的mesh,从左到右依次是默认的cube,将笔刷的长度缩小一倍,将Transform缩小一倍而生成的,但是在引用相同的材质时可以看到,通过Transform缩小一倍的mesh材质也被压缩了。
而把mesh做替换后,生成的大小是一样的。也就是说mesh是不受影响的。
由此可以联想到在做建筑物的建模时,
如果首先通过放大笔刷来构图(全部基于1立方的cube),那么接下来在同位置替换mesh的时候与构图定义的尺寸没有直接关系
如果想直接使用BSP的话,例如地板,只给一面上材质:
所以理想的工作流程应该是先用BSP做基础建模,但是定好了模型的尺寸,然后在根据限定的尺寸去做具体的模型
动画系统学习笔记
2022/04/08 直接学习过动画混合和序列相关的知识,后来发现好像动画系统是一个很大的分支。所以准备先过一下,如果有可以上手的案例顺便做一做。
主要看的是 骨架网格体动画系统
角色设置 的流程是
- 找到合适的骨架网格体和对应的动画
- 导入FBX模型,如果不匹配现有的骨骼,则生成一个新的骨骼。
- 创建玩家控制器脚本或蓝图来处理来自玩家的输入
- 为角色或Pawn创建一个蓝图或脚本或蓝图来解析输入并控制角色的实际移动(不是骨架动画)
- 为角色构造动画蓝图
- 创建一个使用自定义玩家控制器和任何其他自定义脚本资产的游戏模式脚本或蓝图
Mixamo上的资源如何用到UE4里面
Mixamo上主要有两种资源,character和animation
目标是让Mixamo上的character能替换到第三人称模板的小白人上去,然后给他添加动画(这个动画最好是能兼容Mixamo上的动画和EPIC商城的动画)
直接把character (FBX)导入UE项目中,如果在导入选项中指定UE默认的骨骼,后面可能会有问题,如果不指定的话会自己生成一个新的骨骼。FBX会被拆分,主要是图中的四大项
这样虽然可以成功导入,但是如果想继续给添加动画的话,感觉无法和UE默认的资源兼容,因此还需要继续从Mixamo上下载相匹配的动画。我觉得这样有可能会无法和虚幻商城的动画包相匹配。
直接把animation导入UE项目中,这样做的初衷是想给UE添加新的动画,我在网上发现了一个转换工具 Mixamo Converter ,这个软件的原理是预先准备了一个能和Mixamo上的character相匹配的UE模型,然后传上去,再下载想要的animation,然后把animation在软件中转化一下就可以顺利导入到UE中,导入后的动画用的是还是原来小白人的骨骼和mesh。
这种方法适合给小白人添加新的动画
利用 骨骼重定向 的方法,可以实现1:把新的角色和动画导入 2:把新的动画匹配到UE的小人上。
重定向的具体设置:
导入后角色的头发不能正常显示,修改材质
总结一下目前用到的几个角色资源包
AnimStarterPack 官方的动画包
导入后包括动画和mesh和骨骼,mesh和骨骼跟默认的小白人一样,但是如果想把动画添加到第三人称模板上,不能直接引用,可以通过先导出FBX再导入,导入的时候绑定到第三人称模板的骨骼上就可以使用了。
Scanned3DPeoplePack 商店免费资源
实际能操控的mesh有6个,骨骼跟小白人一样,但是想把现成的mesh替换掉模板的小白人实现小白人的移动动画是不行的,因为绑定的骨骼路径不同。因此需要更改绑定。
以这个mesh为例,右键,骨骼–指定骨骼,然后选择模板的骨骼
可以看到正因为mesh的骨骼是一样的,所以可以直接替换绑定
来到ThirdPersonCharacter蓝图,替换mesh
可以看到替换完的mesh还可以使用模板的动画,算是完美兼容。而没有绑定新骨骼的男性mesh只能显示出T型模型,并不会使用动画。
BattleWizardPolyart 商城免费资源
骨骼与默认的小白人相比有拓展。
如果想把套在小白人上,方法同2,但是需要注意
然后如果还想把小魔法师的动画也移植过去,可以先做骨骼重定向,
例如 从缩略图可以看到腿部是 有问题的
实际在游戏中的表现,右腿出现了偏移。
这里的解决方法应该需要用到 动画重定位 (为了把动画重定位,其实修改的是骨骼树)
在这个例子中我主要修改了
这里其实是把第三人称模板的默认骨骼设置修改了
实际游戏中比之前下降了一点,但不够完美
这部分的讲解视频可以参考官方油管
Mixamo 重头戏来了
首先要明确Mixamo上的骨骼和Mannequin是不一样的,也就是说不能像之前的三个例子一样直接把模型移植过去。
这个时候需要用到 骨骼重定向
重定向设置完后可以对动画进行双向导入。也就是说前面三个案例中的动画,可以通过 重定向动画资产 生成新的拷贝给Mixamo模型去用,或者是把Mixamo上的各种动画拿给能兼容Mannequin骨骼的模型去用(这就是之前介绍过的一个convert软件)
关于骨骼重定向的讲解视频可以参考官方油管 和 Smart Poly 的视频
对话系统
对话系统参考油管教程 目前先粗略梳理一下开发流程,后面会添加详细的说明
这个对话系统基于碰撞和按键交互触发。NPC与玩家发生碰撞后按F进入对话,鼠标选择对话选项。
各蓝图类中的Event Dispatchers情况总览
DialogComponent : 绑定 OnExit事件(DialogWidget)
DialogWidget :
OnExit分发事件, OnSpeakFinish分发事件, OnReplyFinish分发事件, OnMouseButtonDown(Override)
绑定OnClicked事件(DialogReplyObject)
Speak : 绑定OnSpeakFinish事件
Reply : 绑定OnReplyFinish事件
DialogEntry_BP : 实现接口UserObjectListEntry
DialogReplyObject : OnClicked分发事件
- 准备工作:
用于交互的接口类 Interaction,实现Interaction接口的组件DialogComponent,玩家添加球型碰撞器InteractionSphere
玩家与NPC碰撞时(将实现了Interaction接口的actor储存到数组中)/离开时(移除数组元素)
- ThirdPersonCharacter
当按下交互按键时,选择与玩家最近的NPC调用Interaction接口的函数OnInteraction()
- DialogComponent
响应接口的调用
Create Widget, Add to Viewport, Set Input Mode UI Only
- DialogComponent
运行BehaviorTree, Blackboard
- DialogTree
Key:DialogWidget(在DialogComponent中赋值), ReplyIndex
序列的第一个任务Speak,代表NPC要说的话
- Speak
执行任务
以text为参数调用Speak事件(DialogWidget)
- DialogWidget
显示SpeakBox隐藏ReplyBox
- DialogWidget
鼠标按下后从NPC的话切换到玩家的话(SPEAK任务结束,进入下一个REPLY任务)
函数OnMouseButtonDown
- Speak
由于Speak绑定了OnSpeakFinish事件, 结束任务,进入行为树序列的下一个任务
- Reply
任务开始执行
传递reply text参数调用Reply事件
- DialogWidget
Reply事件把数组元素构建为对象,存入reply的对话列表中
显示ReplyBox隐藏SpeakBox
- DialogEntry_BP
响应接口的调用,把行为树中的对话内容赋值给当前的widget
- DialogEntry_BP
reply被点击后,调用OnClicked事件(DialogReplyObject)
- DialogWidget
绑定了Onclicked事件,调用OnReplyFinished事件
- Reply
绑定了OnReplyFinish事件,任务结束,根据玩家选择的对话选项进入序列的下一个任务
- Exit
这里假设玩家对话选项选择完后,NPC再说一句话 然后触发结束任务
- DialogComponent
绑定了OnExit事件,Set Input Mode Game Only, Stop Logic (Behavior Tree), Remove widget from Parent
发现的问题:貌似教程里提到的一段节点没有用到?
DialogWidget
可能会用到的插件
Fade Objects:顾名思义是一个组件,可以改变第三人称游戏中相机和玩家之间的物体的材质实现透明的效果(本体是C++写的,但是感觉上比较简单,应该可以研究一下)
AGR:(好像是一个管理系统,没搞懂有什么用)
Async Loading Screen:应该是在读取下一个level时候用的过场动画插件
Cesium:(不知道是什么东西)
Directional & Planet Gravity:一个改变重力方向的插件
Easy Quests:任务系统,基于蓝图开发的组件(感觉可以研究一下)
GOAP NPC:可以给NPC添加AI逻辑?
Graph Formatter:一个理线的插件
Journeyman’s Minimap:小地图插件
Physical Layout Tool :可以给mesh附加物理效果(重力)
Prefabricator:把素材规划成一个prefab,然后随机的生成,可以实时生成
Procedural Building Generator:一个用于城市建模的蓝图,提供了一些选项方便快速建模(感觉有机会用到)
ProInstance Tools Plugin:同样是建模插件,特点是批量生成和管理
Root Motion Guide:(动画相关的插件,没搞懂,但是貌似教程很详细)
UI Navigation:一个做游戏菜单的框架(感觉后面会用到)
Weather System:国人做的,不知道会不会用到
Blockout Tools :提供一些现成的mesh(现在是收费的了)
SuperGrid Starter pack :这是一个工程文件,里面有提供现成的mesh,方便创建关卡的原型
插件下载后保存在engine/marketplace下面。可以看到部分源码?
开发中还未解决的问题
- 按键弹出UI这样的key press event写到哪里比较好?玩家蓝图?关卡蓝图?还是在控件蓝图里写?
案例研究
ContentExample
Geometry
1.2 依次把1 2 3的盒体笔刷排序到最后一项
1.3 没懂有什么用
1.6 非常巧妙的建模(应该用了大量的sub盒体)
FBX
1.2 LOD细节层级,一个非常神奇的例子!(镜头拉远后会变更mesh的材质)
1.3 计算法线(Calculate Normals) 导入法线(Import Normals) 都是什么东西??
1.7 如何把cube变成骨骼体?再添加变形动画?
Navmesh
1.1 让AI通过导航跨过障碍物,利用simple move to location节点。(如果是pawn类的话貌似不能跨过障碍物,但是可以在导航点之间移动)
1.2 利用导航链接代理NavLinkProxy来实现翻越障碍物(自己做案例的时候不能100%成功)
1.3 (没懂和1.1的区别)
Math
1.2 利用time的sin的abs来作为材质(材质中用到了lerp函数,但是向量的算法没搞懂)
1.3 Frac函数的用法
1.4
…
2.9 让物体旋转朝向玩家的例子(复现成功)
2.14 向量点积 dot product 就是向量的乘积
2.17 (材质的案例,没看懂)
2.18 向量积(不知道有什么用)
2.20 (材质函数没搞懂)
Animation
1.3 (尝试做一个用鼠标拖动的滑块)(还没搞懂里面的函数,有没找到的变量名hovered)
(妈的动画部分东西好多)
Blueprints_Overview
1.4 通过构造函数为蓝图类添加组件(感觉没什么用)
1.5 通过构造函数创建动态材质(三个节点)
1.7
Blueprints_Advanced
1.1 在一个区域内随机生成静态网格体(复现成功)
1.2 (也是自动生成,但是没看懂)
1.3 (也是自动生成,但是感觉可以复现出来)
1.4 聚光灯的材质很有朦胧的感觉,说不定可以用来挡镜头
2.1 利用timeline改变球的位置和scale来实现弹球的效果
2.2 摄像机追踪人(跳过)
2.3 接口实现,踩下按钮,让其他物体旋转(复现成功)
2.4 开门关门(感觉可以复现)
2.5 父子类蓝图(没看懂)玩家在吃道具的时候有一个吸附过程 (真牛啊)
Blueprint Communication
1.1 最简单的通过自定义事件触发开关灯,这里灯的亮灭经过了一个timeline。按钮在被按下时材质会发生变化
1.2 实际上是三个actor之间的通信,比较有新意的是,灯的亮度通过电池的容量调节。电池类中定义了与按钮的交互和电池的电量,灯类中定义了与电池的交互和亮灭的细节
1.3
1.4 按钮类通过Get all actors of class 来让一群灯亮,灯类通过set play rate实现随机timeline看起来不同灯有不同的闪烁
2.1 基本的事件分发器,但是通过关卡蓝图实现的中转
2.3 炸弹爆炸,要搞懂这个过程的状态转移
3.2 接口三个拉杆的案例
Blueprint_Input
有三个小游戏案例,首先实现了玩家控制器的切换功能 (虽然还没细看,但是感觉里面的游戏逻辑值得研究)
Blueprint_HUD
这个吃道具的案例用到了很多功能性类,比如game mode,hud,level bp,controller bp
虽然貌似hud已经比较老了,但是有时间可以做一个框架梳理
Blueprint_Splines
1.3 不知道有什么用,通过splinemesh组件拉伸一个管道,但是不能像spline组件一样派生多个拐点 (向量的计算没看懂)
2.2 动态添加spline,实现了随风摆动的灯笼(详细没看)
2.3 树枝生长的动画,用到了很多和spline相关的节点
2.4 模拟鱼的运动(这个太牛逼了,感觉看会就能出师了)
Physics
1.1 给mesh勾选movable和simulate physics来添加物理效果(玩家的抓取系统看起来很复杂 玩家蓝图中定义了一个grabb函数,和官方教程的案例有相似的地方,不过官方教程把抓取做成了一个组件)
1.2 给骨架mesh添加物理,实现了像人类一败涂地的效果
StaticMesh
1.3 为什么!!UV通道是什么东西
官方文档学习笔记
有CPP的实现方法,还没有看。其中切换摄像机视角用到了 SetViewTargetwithBlend 节点 (target is player controller)