美文网首页
UE4 Actor和Component

UE4 Actor和Component

作者: wblong | 来源:发表于2021-03-28 21:27 被阅读0次

UE4 Actor和Component

在UE4游戏场景中看到的所有对象皆是Actor,而Actor复杂的功能是由许多不同的Component共同实现的。UActorComponent提供最一般的功能,USceneComponent提供三维的空间变换以及嵌套功能,UPrimitiveComponent提供了可视化的功能。因此可以根据需要继承不同的组件类来实现自定义的组件类。

Actor 和 Component 关系图

示例

UObject 的生成

ActorComponent都是UObject,有两种生成方式。

构造函数中 CreateDefaultSubobject
UHexTile* newTile = CreateDefaultSubobject<UHexTile>(TEXT("HexTileName"));
构造函数外 NewObject
static int32 TileCounter = 0;
FString TileName = FString::Printf(TEXT("HexTile_%d"), TileCounter++);
UHexTile* NewTile = NewObject<UHexTile>(this, UHexTile::StaticClass(), *TileName);

Actor & ActorComponent

在Actor子类构造函数中添加自定义的ActorComponent子类对象。


ArcGISRendererComponent = CreateDefaultSubobject<UArcGISRendererComponent>(TEXT("ArcGISRendererComponent"));
AddOwnedComponent(ArcGISRendererComponent);

Actor & StaticMeshComponent

在Actor子类构造函数中添加StaticMeshComponent对象。

VisualMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
VisualMesh->SetupAttachment(RootComponent);
static ConstructorHelpers::FObjectFinder<UStaticMesh> CubeAsset(TEXT("StaticMesh'/Game/Mesh/Cube.Cube'"));
if (CubeAsset.Succeeded()) {
    VisualMesh->SetStaticMesh(CubeAsset.Object);
    VisualMesh->SetRelativeLocation(FVector(0.0f,0.0f,0.0f));
  }

创建Actor(SpawnActor)

// Create our sample pawn
ASampleDefaultPawn* arcGISPawn = GetWorld()->SpawnActor<ASampleDefaultPawn>();
// ASSIGN RENDERERVIEW TO THE CURRENT MAIN CAMERA COMPONENT
auto cameraComponent = arcGISPawn->FindComponentByClass<UArcGISCameraComponent>();
cameraComponent->RendererView = rendererView;
arcGISPawn->SetActorLocationAndRotation(Convert::ToFVector(rendererView->GetCameraLocalPosition()),
                                            Convert::ToFQuat(rendererView->GetCameraLocalRotation()));

向Actor对象增加功能组件

构造函数外添加组件。

// Add reposition components to the directional and sky lights
    auto directionalLightActor = UGameplayStatics::GetActorOfClass(GetWorld(), ADirectionalLight::StaticClass());
    auto skyLightActor = UGameplayStatics::GetActorOfClass(GetWorld(), ASkyLight::StaticClass());

    if (directionalLightActor)
    {
        auto directionalLightReposition = NewObject<UArcGISDirectionalLightRepositionComponent>(
            directionalLightActor, UArcGISDirectionalLightRepositionComponent::StaticClass(), NAME_None, RF_Transient);
        directionalLightReposition->RendererView = rendererView;
        directionalLightReposition->RegisterComponent();
    }

    if (skyLightActor)
    {
        auto lightReposition =
            NewObject<UArcGISSkyLightRepositionComponent>(skyLightActor, UArcGISSkyLightRepositionComponent::StaticClass(), NAME_None, RF_Transient);
        lightReposition->RendererView = rendererView;
        lightReposition->RegisterComponent();
    }

组件中反查父Actor

auto owner = CastChecked<ASkyLight>(GetOwner());
owner->SetActorLocation(location);
auto skyLightComponent = StaticCast<USkyLightComponent*>(owner->GetLightComponent());
skyLightComponent->RecaptureSky();

遍历Actor,查找组件

static auto actorClasses =std::vector<TSubclassOf<UActorComponent>>{UArcGISLocationComponent::StaticClass(), UArcGISCameraComponent::StaticClass(), UArcGISDirectionalLightRepositionComponent::StaticClass()};

    // Matrix transform from the old coordinate system to the new one
    auto mTransform = CoordinateSystem.Inverse() * coordinateSystem;

    for (TActorIterator<AActor> it(GetWorld()); it; ++it)
    {
        auto* actor = *it;
        for (const auto& actorClass : actorClasses)
        {
            auto component = actor->GetComponentByClass(actorClass);
            if (component)
            {
                Vector3d newLocation;
                Quaternion newRotation;

                if (actorClass == actorClasses[0])
                {
                    const auto coord = Cast<UArcGISLocationComponent>(component);
                    const auto latLon = LatLon(coord->Latitude, coord->Longitude, coord->Altitude);
                    const auto rotator = Rotator(coord->Heading, coord->Pitch, coord->Roll);

                    if (RendererView->GetSceneType() == SceneType::Global)
                    {
                        Vector3d cartesianPosition = Coordinates::WGS84SphericalToECEF(latLon);
                        newLocation = coordinateSystem.TransformPosition(cartesianPosition);
                        newRotation = coordinateSystem.ToQuaternion() * Coordinates::GetENUCoordinateSystemGlobal(cartesianPosition);
                    }
                    else
                    {
                        Vector3d cartesianPosition = Coordinates::WGS84SphericalToCartesianPlanar(latLon);
                        newLocation = coordinateSystem.TransformPosition(cartesianPosition);
                        newRotation = coordinateSystem.ToQuaternion() * Coordinates::GetENUCoordinateSystemLocal(cartesianPosition);
                    }
                }
                else
                {
                    newLocation = mTransform.TransformPosition(Convert::FromFVector(actor->GetActorLocation()));
                    newRotation = mTransform.ToQuaternion() * Convert::FromFQuat(actor->GetActorRotation().Quaternion());
                }
                actor->SetActorLocationAndRotation(Convert::ToFVector(newLocation), Convert::ToFQuat(newRotation).Rotator(), false, nullptr,
                                                   ETeleportType::ResetPhysics);
                break;
            }
        }
    }

参考链接

UE4 Actor和Component

相关文章

网友评论

      本文标题:UE4 Actor和Component

      本文链接:https://www.haomeiwen.com/subject/chlyhltx.html