U++ Tag
2026/7/24 16:45:09 网站建设 项目流程

在UE中,Tag用于给对象添加一个名称标记,之后可以通过标签来判断对象属于哪一类。

一、Actor Tag

用于给整个Actor添加标签。

AActor内部已经定义:

TArray<FName> Tags;

不需要自己重新声明 Tags。官方将它描述为用于对 Actor 进行分组和分类的 FName 数组。

1.在蓝图细节面板中添加Actor Tag

Details
→ Actor
→ Tags

2.在cpp中添加Actor Tag

一般构造函数中添加:

Tags.Add(TEXT("Interactable"));

不过更推荐用AddUnique():

Tags.AddUnique(TEXT("Interactable"));

前者会添加重名标签,后者不会。

3.检查Actor是否拥有Tag

ActorHasTag()

返回布尔值,例:

检查自身:

if (ActorHasTag(TEXT("Interactable"))) { UE_LOG(LogTemp, Warning, TEXT("当前 Actor 可以交互")); }

检查其他对象:

void AMyActor::CheckActor(AActor* OtherActor) { if (OtherActor && OtherActor->ActorHasTag(TEXT("Enemy"))) { UE_LOG(LogTemp, Warning, TEXT("发现敌人")); } }

ActorHasTag() 会检查该 Actor 的 Tags 数组中是否包含指定的 FName。

4.在碰撞事件中检查Tag

例如角色碰到不同物体时,根据 Tag 执行不同逻辑:

void AMyActor::OnBeginOverlap( UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) { if (!OtherActor) { return; } if (OtherActor->ActorHasTag(TEXT("Enemy"))) { UE_LOG(LogTemp, Warning, TEXT("碰到了敌人")); } else if (OtherActor->ActorHasTag(TEXT("Pickup"))) { UE_LOG(LogTemp, Warning, TEXT("碰到了可拾取物")); } }

5.在射线检测中检查Tag

FHitResult HitResult; bool bHit = GetWorld()->LineTraceSingleByChannel( HitResult, Start, End, ECC_Visibility ); if (bHit) { AActor* HitActor = HitResult.GetActor(); if (HitActor && HitActor->ActorHasTag(TEXT("Interactable"))) { UE_LOG( LogTemp, Warning, TEXT("射线检测到可交互物体:%s"), *HitActor->GetName() ); } }

6.运行时添加和删除Tag

OtherActor->Tags.AddUnique(TEXT("Selected"));

OtherActor->Tags.Remove(TEXT("Selected"));

OtherActor->Tags.Empty();

7.查找所有拥有某个Tag的Actor

#include "Kismet/GameplayStatics.h" TArray<AActor*> EnemyActors; UGameplayStatics::GetAllActorsWithTag( GetWorld(), TEXT("Enemy"), EnemyActors ); for (AActor* EnemyActor : EnemyActors) { if (EnemyActor) { UE_LOG( LogTemp, Warning, TEXT("找到敌人:%s"), *EnemyActor->GetName() ); } }

注意头文件;该操作属于较慢操作,不应该放在Tick()中没帧调用。

二、ComponentTag

一个Actor中通常包括多个组件:

Actor
├── BoxCollision
├── BodyMesh
├── HeadMesh
└── Camera

UActorComponent 自带:

TArray<FName> ComponentTags;

1.给组件添加Tag

AMyActor::AMyActor() { MyMesh = CreateDefaultSubobject<UStaticMeshComponent>( TEXT("MyMesh") ); SetRootComponent(MyMesh); MyMesh->ComponentTags.AddUnique(TEXT("Body")); }

2.检查组件Tag

if (MyMesh->ComponentHasTag(TEXT("Body"))) { UE_LOG(LogTemp, Warning, TEXT("这个组件是身体网格")); }

3.射线检测判断命中组件

HeadMesh->ComponentTags.AddUnique(TEXT("Head")); BodyMesh->ComponentTags.AddUnique(TEXT("Body")); LegMesh->ComponentTags.AddUnique(TEXT("Leg")); if (bHit) { AActor* HitActor = HitResult.GetActor(); UPrimitiveComponent* HitComponent = HitResult.GetComponent(); if (HitActor && HitActor->ActorHasTag(TEXT("Robot"))) { UE_LOG(LogTemp, Warning, TEXT("命中了机器人")); } if (HitComponent) { if (HitComponent->ComponentHasTag(TEXT("Head"))) { UE_LOG(LogTemp, Warning, TEXT("命中了机器人的头部")); } else if (HitComponent->ComponentHasTag(TEXT("Body"))) { UE_LOG(LogTemp, Warning, TEXT("命中了机器人的身体")); } else if (HitComponent->ComponentHasTag(TEXT("Leg"))) { UE_LOG(LogTemp, Warning, TEXT("命中了机器人的腿部")); } } }

4.根据Tag查找Actor内的组件

FindComponentByTag()

UActorComponent* FoundComponent = FindComponentByTag( UStaticMeshComponent::StaticClass(), TEXT("Head") );

三、Gameplay Tags

UE 官方将 Gameplay Tag 定义为一种用户自定义的、具有层级结构的概念标签,可以像布尔值或标志位一样驱动游戏逻辑。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询