可以开灭的灯,可以开合的门,可以拾取的装备,可以乘坐的载具等等,在世界中每个可以与玩家交互的Actor实现逻辑大多是都是类似的,其通用的也是可交互的前提 就是Character中有这个Actor的实例(直接或间接获得)。
例子1:可以开灭的灯
交互最主要的逻辑就是Character获得灯的实例然后调用开关灯的函数。
灯
创建一个带有基本切换开灭功能的灯
可切换的灯
从Character出发
- 交互时,发射一条光线追踪(LineTrace)
- 在碰撞到Actor时尝试将其类型强转(CastTo)为灯
- 转换成功后直接调用灯的开关灯函数
就是这么简单,可以实现超远距离交互,还可以绑定至Tick上实时交互,但是如果我们需要在Character进入灯的范围就把灯打开,离开这个范围就把灯灭掉,同时我们可以手动开灭灯,那这种方法显然不能够实现。
从Actor出发
- 灯有范围(BoxCollision,SphereCollision,CapsuleCollision)
- 某个Actor进入这个范围(BeginOverlap)时尝试将其类型强转(CastTo)为Character
- Charactor中有个保存着灯实例的变量,默认为空
- 转换成功后直接设置Character中灯的变量并将自己赋值给它
- 交互时,Character检测自己变量中的灯的实例是否为空(IsValid),如果不为空就调用灯的开关灯函数
- Actor退出这个范围(EndOverlap)时尝试将自己的实例从中删除(设为空)
同样的,虽然这样能实现Actor主动交互,但它需要包含组件(BoxCollision),只能通过蓝图继承实现而不能通过蓝图接口实现。
如果你的世界中只有一个可以开灭的灯,直接在这个灯中写与Character的通信自然没有问题,但你的世界若有成百上千个可以与玩家产生互动的Actor(Pawn)呢?如果那样的话在每个actor中写通信逻辑自然是不符合常理的。
什么是蓝图继承/蓝图接口
继承是面向对象编程(java,c++,python)语言的基石。
当你添加新蓝图时让你选择父类继承就是子类继承父类的特征(蓝图变量)和行为(蓝图函数),使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
在这里我们稍带一提,不会深入,有兴趣的可以去学习面向对象编程。
蓝图接口
就如名字所说,是一个接口,定义一些抽象的函数(接口中不能实现具体的逻辑,需要由实现了这个接口的类覆写函数),而由其他蓝图能够在不知道这是什么类只知道它实现了这个接口(通过CastTo判断是否实现了这个接口)的情况下调用其接口定义的抽象函数。
什么情况下用继承/接口
比如说你需要可以开灭的灯(继承自Actor)和一个可以开闭的门(继承自Actor),你既可以用继承实现,也可以用接口实现。
你若想在玩家进入灯(门)的范围的时候就打开,需要一个BoxCollision,那么就用继承实现,因为接口目前只能不能含有组件。
但是你需要可以开灭的灯(继承自Actor)和一个可以乘坐的汽车(继承自Pawn,其实一般继承自WheeledVehicle,但它同样继承自Pawn),那么就需要使用接口实现,虽然Pawn同样是继承自Actor,但你需要Pawn的其他实现(可被Controller掌控等等)。
实例
使用继承实现
InteractiveActor定义的两个函数(Start,End),其目的是为了继承自它的类覆写这两个函数实现特定的功能
Character
Start中传入的自身的引用,因为 有可能 在交互的actor中需要。
我们在上文例子中创建的可交互的灯稍稍修改一下就可以了。
-
重新设置父类
image.png
-
覆写函数(Start,End)
函数
在这里我们实现的重叠事件在父类(InteractiveActor)中也是实现,它会先实现父类的逻辑,再处理自己的逻辑。
使用接口实现
-
创建接口
新建资源
2.应用接口,依旧是在类设置中
细节面板
3.实现接口函数
蓝图节点搜索
Dame:百度云
网友评论