由于工作的原因,就松懈了这么久,现在重拾初心
由于在网上找如何UEC++如何创建线程找不到具体的教程,只有很单一代码片段,对初学者就很不友好
UE创建线程
详细步骤:
1.新建一个c++类,选择None作为父类
2.编写MyRunnable.h文件
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "HAL/Runnable.h"
/**
*
*/
class TESTC_API MyRun:public FRunnable
{
public:
MyRun();
~MyRun();
// 重载线程入口函数
virtual uint32 Run() override;
// 停止线程
virtual void Stop() override;
private:
FThreadSafeBool IsStop;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "TestC/Public/Src/MyRun.h"
#include <iostream>
#include <ostream>
MyRun::MyRun()
:IsStop(false)
{}
MyRun::~MyRun()
{
Stop();
}
uint32 MyRun::Run()
{
if(!IsStop)
{
UE_LOG(LogTemp, Display, TEXT("Running..."));
}
return 0;
}
void MyRun::Stop()
{
IsStop = true;
}
3.在GameMode中管理和创建线程
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "HAL/RunnableThread.h"
#include "Public/Src/MyRun.h"
#include "GameFramework/GameModeBase.h"
#include "TestCGameModeBase.generated.h"
UCLASS()
class TESTC_API ATestCGameModeBase : public AGameModeBase
{
GENERATED_BODY()
public:
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
private:
// 实例化线程
MyRun* Run;
FRunnableThread* Thread;
};
// Copyright Epic Games, Inc. All Rights Reserved.
#include "TestCGameModeBase.h"
void ATestCGameModeBase::BeginPlay()
{
Super::BeginPlay();
Run = new MyRun();
Thread = FRunnableThread::Create(Run,TEXT("Thread"));
UE_LOG(LogTemp,Display,TEXT("Thread Created"));
}
void ATestCGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
Run->Stop();
// 停止线程
if(Thread)
{
Thread->WaitForCompletion();//等待线程完成
delete Thread;
Run = nullptr;
UE_LOG(LogTemp,Display,TEXT("Thread Destroyed"));
}
delete Run;
Thread = nullptr;
UE_LOG(LogTemp,Display,TEXT("111111"));
}
注意不能使用无限循环,此外还要检查Thread的合理性,避免访问空指针
容器TArray
TArray是虚幻C++中的动态数组,类似于vector
测试案例统统在GameMode的BeginPlay中进行
增删
.h文件
// 容器
TArray<int32> TestData;
.cpp文件
// 添加元素
// 添加元素
TestData.Add(1);
TestData.Add(2);
TestData.Add(3);
print();
UE_LOG(LogTemp,Display,TEXT("-----------------"));
// 将元素5插入到下标为0的位置
TestData.Insert(5,0);
print();
UE_LOG(LogTemp,Display,TEXT("-----------------"));
// 将7,8,9插入到下标为2的位置
TestData.Insert({7,8,9},2);
print();
UE_LOG(LogTemp,Display,TEXT("-----------------"));
// 插入数组temp到下标为4的位置
TArray<int32> temp = {11,12,13};
TestData.Insert(temp,4);
print();
UE_LOG(LogTemp,Display,TEXT("-----------------"));
// 删除元素
// 调用RemoveAt删除元素后面的元素会自动往前移
TestData.RemoveAt(1);
print();
// 清空数组
TestData.Reset(TestData.Num());//如果传入的参数不小于当前的数组空间,不会释放现有内存
UE_LOG(LogTemp,Display,TEXT("NUM = %d"),TestData.Num());
UE_LOG(LogTemp,Display,TEXT("-----------------"));
TestData.Empty();// 将数组中的所有元素都清空,同时数量变为0
UE_LOG(LogTemp,Display,TEXT("NUM = %d"),TestData.Num());
改查
// 添加元素
TestData.Add(1);
TestData.Add(2);
TestData.Add(3);
print();
UE_LOG(LogTemp,Display,TEXT("-----------------"));
// 改
TestData[1] = 4;
print();
// 查找元素
bool Exist = TestData.Contains(10); // 在数组中查找是否存在这个元素
if(Exist)
UE_LOG(LogTemp,Display,TEXT("找到了"));
int32 Index = TestData.Find(1); // 正向查找,返回找到的第一个元素的下标,失败返回-1
if(Index != -1)
UE_LOG(LogTemp,Display,TEXT("Find %d"),Index);
Index = TestData.FindLast(1); // 逆向查找,返回找到的第一个元素的下标,失败返回-1
if(Index != -1)
UE_LOG(LogTemp,Display,TEXT("FindLast %d"),Index);