大家好,我是阿赵。
在使用Unity引擎的时候,经常会用到的一个功能是通过GameObject.Find去查找场景里面的对象。这次变成在UE引擎里面做同样的事情,这篇文章主要做的事情有2个,第一是从场景里面找到特定的Actor,第二件事是控制Actor的Transform。
一、 蓝图方式
1、查找Actor
蓝图中查找Actor的节点有很多:
[image1]
1.通过类名查找场景中的Actor
使用GetActorOfClass节点,可以查找场景里面第一个匹配的Actor。在class项搜索自己想要的蓝图的类名:
[image2]
如果想查找全部指定类名的Actor,可以用GetAllActorsOfClass,这样返回的是一个数组。
使用GetAllActorsWithInterface节点,可以找到包含某个接口的所有Actor
[image3]
3.通过标签查找Actor
使用GetAllActorsWithTag,可以找到指定了某个标签的所有Actor。
标签的指定,在细节面板可以指定:
[image4]
2、 控制Actor的坐标
1. 获取和设置坐标
获得Actor后,可以用GetActorLocation获得Actor的坐标,然后再通过SetActorLocation重新设置坐标:
[image5]
其他的属性比如旋转或者缩放同理。
2. 结果判空
这里有一个问题,通过GetActor系列方法查找场景中的Actor时,是会存在找不到的情况,所以要对查找的结果判空。
在蓝图里面对一个Actor判空,比较诡异,是通过一个!=(不等于)节点,来判空的。把结果连接到不等于,然后再把输出连接到condition上。
[image6]
二、 C++方式
1、 不指定类型获取所有的Actor
通过获得某个指定的world和level,可以获得这个level上面的所有的actor列表。然后如果需要过滤自己想要的actor,可以在遍历actor列表的时候,判断条件,比如我下面是判断了actor的名字,通过GetName方法可以获得actor的名字,然后筛选。
TArray<AActor*> FoundActors = GetWorld()->GetLevel(0)->Actors;
UE_LOG(LogTemp, Display, TEXT("%d"), FoundActors.Num());
if (FoundActors.Num() > 0)
{for (int i = 0;i<FoundActors.Num();i++){AActor* actor = FoundActors[i];if (actor != nullptr){FString fName = actor->GetName();UE_LOG(LogTemp, Display, TEXT("%s"), *fName);if (fName.Contains(TEXT("TestBallBP"))){actor->SetActorLocation(actor->GetActorLocation() + FVector(0, 0, 2));}}}
}
2、 指定获取Actor
和蓝图对应的方法,C++这边也有,通过类名、接口和标签获取Actor
UGameplayStatics::GetAllActorsOfClass
UGameplayStatics::GetAllActorsWithInterface
UGameplayStatics::GetAllActorsWithTag
比如通过类名获取actor,上面的代码就可以修改成这样:
FString path = TEXT("/Game/BP/TestBallBP.TestBallBP_C");
UClass* bpVar = LoadClass<AActor>(nullptr, *path);
TArray<AActor*> FoundActors;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), bpVar, FoundActors);
if (FoundActors.Num() > 0)
{AActor* ball = FoundActors[0];ball->SetActorLocation(ball->GetActorLocation() + FVector(0, 0, 2));
}
设置Transform的方法,有以下几个,可以设置坐标、旋转、缩放:
SetActorLocation
SetActorRotation
SetActorScale3D