DAY16
由于工作的原因,就松懈了这么久,现在重拾初心
由于在网上找如何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();// 将数组中的所有元素都清空,同时数量变为0UE_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);