0.前言
- 使用两个类:A类和B类。
- actor之间的通信,实际就是寻找实列化的actor。
1.直接调用
也就是直接在A中获取到B。
1.在场景中找
。此时可以使用虚幻自带的搜索函数:UGameplayStatics::GetActorsOfClass/GetAllActorsOfClass
.
注意在蓝图中也可以使用
1.1.对于
GetActorsOfClass:获取第一个找到的指定actor
这个函数的源码在这
static void GetAllActorsOfClass
(const UObject* WorldContextObject,
TSubclassOf ActorClass//TSubclassOf是安全引用对应类的模板。)
这里参数可以直接这样给(GetWorld(),YourClassName::StaticClass())
> AActorB* ActorB =
> Cast<AActorB>(UGameplayStatics::GetActorOfClass(GetWorld(),
> AActorB::StaticClass()));
其中GetWorld()是获取此时A类所在的世界信息,用于指定世界。AActorB::StaticClass()获取指定的B类型。
1.2.对GetAllActorsOfClass
,获取世界中所有指定的Actor
源码:
static void GetAllActorsOfClass
>(
>const UObject* WorldContextObject,//(actor所在的世界)
> TSubclassOf<AActor> ActorClass,
> TArray<AActor*>& OutActors
> );
可以看出相对于GetActorClass第三个参数是引用类型,这里做为返回值。
这里就相当于c++中的父类指针指向子类的多态。后面转换为B直接使用Cast即可。
2.生成时自带
- 2.1.在生成A时可以直接在B中生成,将B自己作为A的一个参数传入。
使用的是:GetWorld()->SpawnActor
它有几个重载:这里仅给出一个:
AActor* SpawnActor
( UClass* InClass//就是要生成的类ClassName::StaticClass(),
FVector const* Location=NULL,
FRotator const* Rotation=NULL,
const FActorSpawnParameters& SpawnParameters = FActorSpawnParameters()
//这是actor细节面板上的一些额为参数设置,如碰撞预设设置
);
随后再利用这个A设置里面的B类指针成员。
额为的:对于蓝图可以直接在A中将B指针的变量设置为生成公开以及可编辑实列,这样,在蓝图使用spawnActor后,可以直接下拉节点设置B指针变量
注意:这里的B变量是bool类型。
3.在其他类中保存
利用其他actor来保存实列化的B类。A再通过这个Actor获取B。
一般使用虚幻的GamePlay框架里的。senc如Controller,GameMode,GameInstance.来保存实列化的B类。
2.利用回调
就是通过回调函数将actor类或者相关信息作为参数传入。
1.绑定回调函数。
- 1.1虚幻自有一套代理系统。存放在DelegateCombinations.h 这个文件。
也可以在编译器中输入这个,再F12跳转。
DECLARE_DELEGATE( DelegateName )
-
1.2
对代理上的参数设置,如果要类,可以看上面的GetActorClass,使用TSubclassOf ActorClass这个做为参数。
再代理绑定的函数里再细致做处理。
-
1.3
关于代理的知识自行上网查找。
-
1.4
这里是使用B来设置A,就可以在A中实现代理。代理所要绑定的回调函数使用B中的,函数参数设为A,这样一来就可以在A中callB中的函数,将自己传给B,用B中的成员设置自己。这种形式在代码中也容易实现,只要包含头文件。
对于蓝图有另一种形式
-
1.5
代理的使用,有很多场景,如UI中的按钮。
2.蓝图使用事件分发器
-
2.1
一般,将分发器建立在要调用分发器所绑定函数的位置。而将分发器绑定的函数放在要被使用到的类中。
如使用B来设置A,以及A调用B的功能,就可以将分发器放在A中。再在B中建立函数,参数设置为A,以及调用A中的分发器绑定函数。然后,在A中call分发器,将自己传入。
-
2.2
不过由于在B中要获取到A的分发器,就是要在编译阶段找到A。
所以一般A为虚幻中好找的类,和上面直接调用中的3一样,如Controller,GameMode,GameInstance.而B为自己建立的其他Actor,如一辆车。
3.接口
本质是将一个功能单独成一个类,方便区分一个基类下少部分不同行为的子类。
这里A要使用B中的某个功能,也就是操作B。B实现一个接口函数
-
3.1
在A中调用B的接口函数,就要获取到B这个类,先判断B是否继承这个接口,再转为接口类,最后使用这个类里的函数。
-
3.2
对于获取B这个类,可以使用上面的所有方法。
-
3.3
蓝图和c++一样的思路,只在实现上有些不同,这里不多赘述。
4.总结
actor的通信实际上是,实列A怎么寻找到实列B。
对于虚幻,有些类是很容易获取到的。我们可以以这些类为基础,来实现对于不容易获取到的Actor的通信。