【UEC++】常用函数使用方法总结

Delay 函数的使用

FLatentActionInfo LatentInfo;
LatentInfo.CallbackTarget = this;
LatentInfo.ExecutionFunction = "此处输入之后要调用的函数名";
LatentInfo.Linkage = 1;
LatentInfo.UUID = 100;
UKismetSystemLibrary::Delay(this, 间隔时间, LatentInfo);

FTimerHandle 用法

在C++里面也有实现类似Delay的函数:

GetWorld()->GetTimerManager().SetTimer(TH_StanceAction, this, &AALSVLearnDemoCharacter::ResetStanceActionCount, .3f);

相比之下这个函数比Delay更好用也更容易记住。

他的函数定义是这样的:

void SetTimer(FTimerHandle& InOutHandle, UserClass* InObj, typename FTimerDelegate::TUObjectMethodDelegate< UserClass >::FMethodPtr InTimerMethod, float InRate, bool InbLoop = false, float InFirstDelay = -1.f);

各个参数的意义:

/**
* 设置一个计时器在设定的时间间隔调用给定的本机函数。
* 如果已经设置了计时器,对于这个句柄,它将替换当前计时器。
* @param inouthandle如果传入的句柄指向一个已经存在的计时器,它将在添加新的计时器之前被清除。在这两种情况下都会返回新计时器的新句柄。
* @param inobj对象调用计时器函数。
* @param indermethod定时器触发时调用的方法。
* @param inrate设置和触发之间的时间(秒)。如果 <= 0.f,清除现有的计时器。
* @param inbloop true表示按Rate间隔触发,false表示只触发一次。
* @param infirstdelay循环计时器第一次迭代的时间(以秒为单位)。如果 < 0.f将使用InRate。
* /

对当前计时器清零:
GetWorld()->GetTimerManager().ClearTimer(TH_StanceAction);

获取触发时间:
GetWorld()->GetTimerManager().GetTimerRate(TH_StanceAction)

获取剩余时间:
GetWorld()->GetTimerManager().GetTimerRemaining(TH_StanceAction)

输出枚举变量名称

const UEnum* CompileModeEnum = StaticEnum<枚举类型>();
if (CompileModeEnum)
{
	UE_LOG(LogTemp, Warning, TEXT("枚举变量名 :  %s"),
	       *CompileModeEnum->GetDisplayNameTextByValue(static_cast<uint8>(枚举变量)).ToString());
}

任意按键绑定函数

使用 BindKey 的时候需要添加 Slate 模块!
InputComponent->BindKey(EKeys::T, IE_Pressed, this, &AALS_Player_Controller::SwitchShowTraces);

在游戏运行中生成某个Actor

.h 
TSubclassOf<生成的类型的基类名> PawnToSpawn;

.cpp
GetWorld()->SpawnActor<生成的Actor类型>(生成的Actor对应的类, 出生地址, 出生旋转角度)

在游戏中生成AI控制的Actor

SpawnAIFromClass能够在生成actor的同时生成AI控制器

UAIBlueprintHelperLibrary::SpawnAIFromClass(GetWorld(), EnemyClass, nullptr, FVector(-198.f, -27.f, 95.f),
FRotator(0.f, 0.f, 0.f), false, nullptr);

使用委托函数进行碰撞检测

.h

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="XXXX")
USphereComponent* DetectSphere;

// 委托函数
UFUNCTION()
void OnDetectSphereOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
	                                UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep,
	                                const FHitResult& SweepResult);
UFUNCTION()
void OnDetectSphereOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
		UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

.cpp

// 绑定委托函数 
// 开始重叠的时候才会调用OnDetectSphereOverlapBegin函数
DetectSphere->OnComponentBeginOverlap.AddDynamic(this, &AXXXX::OnDetectSphereOverlapBegin);
// 结束重叠的时候才会调用OnDetectSphereOverlapBegin函数
DetectSphere->OnComponentEndOverlap.AddDynamic(this, &AXXXX::OnDetectSphereOverlapEnd);

让Actor自动按照指定的方向移动

FTransform Transform = GetActorTransform();
Transform.SetLocation(GetActorLocation() + UKismetMathLibrary::Normal(Direction) * DeltaSeconds * Speed);
SetActorTransform(Transform);

AI 自动寻路

EnemyController = GetController<AAIController>(); // 使用前要先获取AI控制器

FAIMoveRequest MoveRequest;
MoveRequest.SetGoalActor(TargetCharacter);
MoveRequest.SetAcceptanceRadius(0.f); // 之间相差多少算是移动停止了

FNavPathSharedPtr NavPath;
EnemyController->MoveTo(MoveRequest, &NavPath);

需要在地图中添加Nav Mesh Bounds Bolume来规划AI的行走路线,添加之后按下P键就可以看到绿颜色,绿色的就是代表AI可以心走的区域,可以使用Nav Modifier Volume进行修剪AI的行走区域。

AI 停止或者继续移动

EnemyController->PauseMove(RequestID); // AI 停止移动

nemyController->ResumeMove(RequestID); // AI 继续运动

将UI加载到屏幕中

  • 变量声明
// 运行游戏时的UI静态资源
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="UI")
TSubclassOf<UUserWidget> GameRunHUDAsset;

// 保存UI的变量
UPROPERTY()
UUserWidget* GameRunHUD;
  • 函数调用

先在BeginPlaye中初始化数据:

if (GameRunHUDAsset)
{
	GameRunHUD = CreateWidget<UUserWidget>(this, GameRunHUDAsset);
}

在展示它的地方使用:

if (GameRunHUD)
{
	GameRunHUD->AddToViewport();
}

在销毁它的地方使用:

if (GameRunHUD)
{
	GameRunHUD->RemoveFromViewport();
}

更新摄像机管理器中摄像机的位置

void UpdateViewTargetInternal(FTViewTarget& OutVT, float DeltaTime)
{
	if (OutVT.Target)
	{
		FVector OutLocation;
		FRotator OutRotation;
		float OutFOV;

		// 判断该变量是否是 基类角色的子类 并且 已经获取到了控制的角色
		if (判断条件 && 自定义函数更新属性 : CustomCameraBehavior(DeltaTime, OutLocation, OutRotation, OutFOV))
		{
			// ……
		}
		else
		{
			// 否则就用原来的
			OutVT.Target->CalcCamera(DeltaTime, OutVT.POV);
		}
	}
}

判断y是否是Y的子类

y->IsA<Y>()

射线检测的写法

建议不要直接调用KismetSystemLibrary库里面的射线检测,直接按照下面的形式写即可。

  • 球体射线检测
FVector TraceOrigin; // 起始点
float TraceRadius; // 射线半径
ECollisionChannel TraceChannel; // 射线通道

// ……   这里进行对应的逻辑处理

// 获取当前世界
UWorld* World = GetWorld();
check(World);

// 配置射线检测参数
FCollisionQueryParams Params;
Params.AddIgnoredActor(this);
Params.AddIgnoredActor(ControlledCharacter);

// 储存碰撞结果
FHitResult HitResult;
// 说明 射线检测的形状
const FCollisionShape SphereCollisionShape = FCollisionShape::MakeSphere(TraceRadius);
const bool bHit = World->SweepSingleByChannel(HitResult, TraceOrigin, TargetCameraLocation,  FQuat::Identity, TraceChannel, SphereCollisionShape, Params);

a类中是否包含B类组件并返回该组件

UActorComponent* Comp = a->GetComponentByClass(B::StaticClass());

从数据表中读取行名为RowName的数据

FDataTableRowHandle MovementModel;

// 打印Actor当前的文件地址
const FString ContextString = GetFullName();
/*
 * UE_LOG(LogTemp, Warning, TEXT("GetFullName: %s"), *ContextString);
 * 输出 GetFullName: ALS_CharacterBP_C /Game/Maps/UEDPIE_0_M_Level1.M_Level1:PersistentLevel.ALS_CharacterBP_C_0
 * 前面是名字,后面是地址。
 */

// 从数据表中读取 行名为RowName的数据,记得要初始化。
FALSMovementStateSettings* OutRow =
	MovementModel.DataTable->FindRow<FALSMovementStateSettings>(MovementModel.RowName, ContextString);
check(OutRow);
MovementData = *OutRow;
  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值