signed

QiShunwang

“诚信为本、客户至上”

UE4 C++学习笔记之动态创建Actor

2020/8/20 14:54:01   来源:

任务:游戏开始时,在场景中某一限定区域内生成一个Actor类

第一步、新建一个C++ Actor类SpawnVolume

SpawnVolume.h代码如下:

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "SpawnVolume.generated.h"

UCLASS()
class LEARNTEST_API ASpawnVolume : public AActor
{
	GENERATED_BODY()

public:

        //声明盒体,用来表示限定的区域
	UPROPERTY(VisibleAnywhere)
	class UBoxComponent* SpawnVloume;

        //声明函数:得到随机生成位置向量
	UFUNCTION(BlueprintPure)
	FVector GetSpawnPoint();

        //声明想创建的类组,此处选择基类为ACreature的类组,可在蓝图类中编辑具体类,在蓝图中使用
	UPROPERTY(EditAnywhere,BlueprintReadOnly)
	TSubclassOf<class ACreature> PawnToSpawn;

        //声明函数:动态生成Actor
	UFUNCTION(BlueprintCallable)
	void SpawnMyPawn(UClass* PawnToSpawn, const FVector&  Location);


public:	
	// Sets default values for this actor's properties
	ASpawnVolume();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

};

SpawnVolumn.cpp代码如下:

#include "SpawnVolume.h"
#include "Components\BoxComponent.h"
#include "Engine\Classes\Kismet\KismetMathLibrary.h"
#include "Engine\Classes\Engine\World.h"
#include "Creature.h"

//定义函数:得到限定区域的随机位置
FVector ASpawnVolume::GetSpawnPoint()
{
        //得到盒体的长宽高
        FVector Extent = SpawnVloume->GetScaledBoxExtent();

        //得到盒体的中心位置
	FVector Origin = SpawnVloume->GetComponentLocation();
    
        //在盒体内部得到随机位置,并返回
	FVector Point = UKismetMathLibrary::RandomPointInBoundingBox(Origin, Extent);
	return Point;
}

//定义函数:生成Actor类,需要传入类组和位置
void ASpawnVolume::SpawnMyPawn(UClass* PawnClass, const FVector& Location)
{
	if (PawnClass)
	{
		UWorld* MyWorld = GetWorld();

		if (MyWorld)
		{
			 MyWorld->SpawnActor<ACreature>(PawnClass, Location, FRotator(0.f));
		}
	}
}

// Sets default values
ASpawnVolume::ASpawnVolume()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

        //创建盒体组件并将其设置为根结点
	SpawnVloume = CreateDefaultSubobject<UBoxComponent>(TEXT("SpawnVloume"));
	RootComponent = SpawnVloume;
}

// Called when the game starts or when spawned
void ASpawnVolume::BeginPlay()
{
	Super::BeginPlay();

        //定义一个位置向量并将其赋值为限定区域的随机位置
	FVector NewLocation = GetSpawnPoint();

        //调用函数,在NewLocation位置生成Actor
	SpawnMyPawn(PawnToSpawn, NewLocation);	
}

// Called every frame
void ASpawnVolume::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

第二步、以SpawnVolume类为父类新建蓝图类MySpawnVolume,在蓝图类中设置想要具体生成的类

然后把该蓝图类拖入场景中,运行游戏即可。