UE4 Actor和Component

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
https://blog.csdn.net/mrbaolong/article/details/115288232

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值