Spawning Pickups(What, Where, When to Spawn)
06.Defining What to Spawn
SpawnVolume.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 |
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "GameFramework/Actor.h"
#include "SpawnVolume.generated.h"
UCLASS()
class BATTERYCOLLECTOR_API ASpawnVolume : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ASpawnVolume();
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every frame
virtual void Tick( float DeltaSeconds ) override;
/*Returns the WhereToSpawn subobject*/
FORCEINLINE class UBoxComponent* GetWhereToSpawn() const { return WhereToSpawn; }
/*Find a random point within the Boxcomponent*/
UFUNCTION(BlueprintPure, Category = "Spawning")
FVector GetRandomPointInVolume();
private:
/*Box Component to specify where pickups should be spawned*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly,
Category = "Spawning", meta = (AllowPrivateAccess = "true"))
class UBoxComponent* WhereToSpawn;
};
|
cs |
23)UFUNCTION이랑 FORCEINLINE은 호환이 안된다.
만약 GetMesh를 BlueprintCallable로 만들고 싶다면 FORCEINLINE매크로를 사용하지 말아야한다.
26)박스 컴포넌트 볼륨 속의 랜덤한 좌표를 반환해서 벡터값으로 변환한다
SpawnVolume.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 |
// Fill out your copyright notice in the Description page of Project Settings.
#include "BatteryCollector.h"
#include "SpawnVolume.h"
#include "Kismet/KismetMathLibrary.h"
// Sets default values
ASpawnVolume::ASpawnVolume()
{
// Set this actor to call Tick() every frame.
PrimaryActorTick.bCanEverTick = false;
//Create the Box Component to represent the spawn volume
WhereToSpawn = CreateDefaultSubobject<UBoxComponent>(TEXT("WhereToSpawn"));
RootComponent = WhereToSpawn;
}
// Called when the game starts or when spawned
void ASpawnVolume::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ASpawnVolume::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
}
FVector ASpawnVolume::GetRandomPointInVolume(){
FVector SpawnOrigin = WhereToSpawn->Bounds.Origin;
FVector SpawnExtent = WhereToSpawn->Bounds.BoxExtent;
return UKismetMathLibrary::RandomPointInBoundingBox(
SpawnOrigin, SpawnExtent);
}
|
cs |
5)키즈멧 라이브러리: 플레이어 컨트롤러나 각종 유용한 기능
블루프린트뿐만 아니라 코드에서도 값에 접근할 수 있게 해준다.
15)박스 컴포넌트를 루트로 설정한다, 새 컴포넌트가 추가되면 이를 중심으로 삼게된다.
30) 모든 박스 컴포넌트에는 중점과 면까지의 거리값이 벡터 값으로 들어있는데 그 값을 받아온것.
WhereToSpawn를 콜하지 않고 직접가져다 쓸수 있게 됐는데,
현재 함수가 SpawnVolume과 같은 클래스 내에 있기 때문이다.
만약 게임모드 등과 같이 다른 클래스였다면 GetSpawnVolume등과 같은 함수를 사용했어야 한다.
33,34)GetRandomPointInBoundingBox 함수: 원점과 각 축의 길이를 파라미터로 받는다.
랜덤한 x,y,z값을 각각 만들어내는 것 보다 조금더 쉽게 계산해 낼수 있다.
07.Defining What to Spawn
SpawnVolume.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 |
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "GameFramework/Actor.h"
#include "SpawnVolume.generated.h"
UCLASS()
class BATTERYCOLLECTOR_API ASpawnVolume : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ASpawnVolume();
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every frame
virtual void Tick( float DeltaSeconds ) override;
/*Returns the WhereToSpawn subobject*/
FORCEINLINE class UBoxComponent* GetWhereToSpawn() const { return WhereToSpawn; }
/*Find a random point within the Boxcomponent*/
UFUNCTION(BlueprintPure, Category = "Spawning")
FVector GetRandomPointInVolume();
protected:
/**The pickup to spawn*/
UPROPERTY(EditAnywhere, Category = "spawn")
TSubclassOf<class APickup> WhatToSpawn;
private:
/*Box Component to specify where pickups should be spawned*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly,
Category = "Spawning", meta = (AllowPrivateAccess = "true"))
class UBoxComponent* WhereToSpawn;
//Handle spawning a new pickup
void SpawnPickup();
};
|
cs |
32) TSubclassOf<class ~> APickup클래스나 자손클래스만으로 한정하여 사용할수있다.
UCLASS포인터와 유사하기때문에 전방선언,
SpawnVolume.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 |
// Fill out your copyright notice in the Description page of Project Settings.
#include "BatteryCollector.h"
#include "SpawnVolume.h"
#include "Kismet/KismetMathLibrary.h"
#include "Pickup.h"
// Sets default values
ASpawnVolume::ASpawnVolume()
{
// Set this actor to call Tick() every frame.
PrimaryActorTick.bCanEverTick = false;
//Create the Box Component to represent the spawn volume
WhereToSpawn = CreateDefaultSubobject<UBoxComponent>(TEXT("WhereToSpawn"));
RootComponent = WhereToSpawn;
}
// Called when the game starts or when spawned
void ASpawnVolume::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ASpawnVolume::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
}
FVector ASpawnVolume::GetRandomPointInVolume(){
/***/
FVector SpawnOrigin = WhereToSpawn->Bounds.Origin;
FVector SpawnExtent = WhereToSpawn->Bounds.BoxExtent;
return UKismetMathLibrary::RandomPointInBoundingBox(SpawnOrigin, SpawnExtent);
}
void ASpawnVolume::SpawnPickup(){
//1.If we have set something to spawn:
if (WhatToSpawn != NULL){
//2.Check for a valid world:
UWorld* const World = GetWorld();
if (World){
//3.Set the spawn parameters
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
SpawnParams.Instigator = Instigator;
/**Get a random location to spawn at*/
FVector SpawnLocation = GetRandomPointInVolume();
//Get a random rotation for the spawned item
FRotator SpawnRotation;
SpawnRotation.Yaw = FMath::FRand()*360.0f;
SpawnRotation.Pitch = FMath::FRand()*360.0f;
SpawnRotation.Roll = FMath::FRand()*360.0f;
//4.spawn the pickup
APickup* const SpawnedPickup = World->SpawnActor<APickup>(WhatToSpawn,
SpawnLocation, SpawnRotation, SpawnParams);
}
}
} |
cs |
7)헤더가 아니라 소스파일에 인클루드 하는 이유:
헤더에서는 전방선언만으로 잘통하지만 pickup클래스를 직접다루게 되면 좀더 많은 정보가 필요할거라
소스파일에 인클루드한 것이다.
즉, 다른곳에서라도 spawnVolume.h를 인클루드할 필요가 있으면, 그거만 인클루드하면 된다.
이렇게 해서 헤더를 분리되게하고 의존성을 떨어뜨리는것.
40~)아이템 만드는 단계
//1. If we have set something to spawn 생성할 것이 설정되어 있다면
//2. Check for a valid world 월드가 유효한지 확인
//3. Set the spawn parameters 생성범위를 설정하고
//4. spawn the pickup 아이템 생성
49) 누가 아이템을 만들었는지, 누가 만들게 했는지 명시
51) 아이템이 랜덤한 위치에서 소환하게 한다.
53) 아이템에 랜덤한 회전을 준다.
08.Setting Timers for Spawning
SpawnVoume.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 |
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "GameFramework/Actor.h"
#include "SpawnVolume.generated.h"
UCLASS()
class BATTERYCOLLECTOR_API ASpawnVolume : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ASpawnVolume();
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every frame
virtual void Tick( float DeltaSeconds ) override;
/*Returns the WhereToSpawn subobject*/
FORCEINLINE class UBoxComponent* GetWhereToSpawn() const { return WhereToSpawn; }
/*Find a random point within the Boxcomponent*/
UFUNCTION(BlueprintPure, Category = "Spawning")
FVector GetRandomPointInVolume();
protected:
/**The pickup to spawn*/
UPROPERTY(EditAnywhere, Category = "spawn")
TSubclassOf<class APickup> WhatToSpawn;
FTimerHandle SpawnTimer;
//Minimum spawn delay
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spawning")
float SpawnDelayRangeLow;
//Maximum spawn delay
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spawning")
float SpawnDelayRangeHigh;
private:
/*Box Component to specify where pickups should be spawned*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly,
Category = "Spawning", meta = (AllowPrivateAccess = "true"))
class UBoxComponent* WhereToSpawn;
//Handle spawning a new pickup
void SpawnPickup();
//The current spawn delay
float SpawnDelay;
};
|
cs |
34)FTimerHandle형은 UPROPERTY를 달아줄필요가 없다.
FTimerHandle형이 어떠한 값이 아니기때문이다.
UPROPERTY 에디터에서 편집 가능하고 가비지 콜렉션에도 포함될수 있다.
SpawnVolume.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 |
// Fill out your copyright notice in the Description page of Project Settings.
#include "BatteryCollector.h"
#include "SpawnVolume.h"
#include "Kismet/KismetMathLibrary.h"
#include "Pickup.h"
// Sets default values
ASpawnVolume::ASpawnVolume()
{
// Set this actor to call Tick() every frame.
PrimaryActorTick.bCanEverTick = false;
//Create the Box Component to represent the spawn volume
WhereToSpawn = CreateDefaultSubobject<UBoxComponent>(TEXT("WhereToSpawn"));
RootComponent = WhereToSpawn;
//Set the spawn delay range
SpawnDelayRangeLow = 1.0f;
SpawnDelayRangeHigh = 4.5f;
}
// Called when the game starts or when spawned
void ASpawnVolume::BeginPlay()
{
Super::BeginPlay();
SpawnDelay = FMath::FRandRange(SpawnDelayRangeLow, SpawnDelayRangeHigh);
GetWorldTimerManager().SetTimer(SpawnTimer, this, &ASpawnVolume::SpawnPickup, SpawnDelay, false);
}
// Called every frame
void ASpawnVolume::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
}
FVector ASpawnVolume::GetRandomPointInVolume(){
FVector SpawnOrigin = WhereToSpawn->Bounds.Origin;
FVector SpawnExtent = WhereToSpawn->Bounds.BoxExtent;
return UKismetMathLibrary::RandomPointInBoundingBox(SpawnOrigin, SpawnExtent);
}
void ASpawnVolume::SpawnPickup(){
//1.If we have set something to spawn:
if (WhatToSpawn != NULL){
//2.Check for a valid world:
UWorld* const World = GetWorld();
if (World){
//3.Set the spawn parameters
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
SpawnParams.Instigator = Instigator;
/**Get a random location to spawn at*/
FVector SpawnLocation = GetRandomPointInVolume();
//Get a random rotation for the spawned item
FRotator SpawnRotation;
SpawnRotation.Yaw = FMath::FRand()*360.0f;
SpawnRotation.Pitch = FMath::FRand()*360.0f;
SpawnRotation.Roll = FMath::FRand()*360.0f;
//4.spawn the pickup
APickup* const SpawnedPickup = World->SpawnActor<APickup>(
WhatToSpawn, SpawnLocation, SpawnRotation, SpawnParams);
SpawnDelay = FMath::FRandRange(SpawnDelayRangeLow, SpawnDelayRangeHigh);
GetWorldTimerManager().SetTimer(SpawnTimer, this, &ASpawnVolume::SpawnPickup, SpawnDelay, false);
}
}
} |
cs |
28)게임속 실행중인 모든 타이머를 추적한다.
핸들을 가져다가
spawnTimer 클래스를 위해서 spawnPickup에 바인딩(this)하고 spawndelay만큼의 시간이 흐르고나면 호출.
false 반복은 안함.
66, 67) 아이템 생성시 범위 내 값으로 타이머 시간을 랜덤하게 새로뽑기 위해서
detail에서 시간이랑 스폰할 것을 조절할수 있게 된다.
'프로그래밍 > Unreal' 카테고리의 다른 글
[08]Battery Collector_power추가, 아이템 획득시 power 증가시키기 (0) | 2017.05.07 |
---|---|
[07]BatteryCollector_아이템습득 (0) | 2017.05.06 |
[06]Battery Collector_기초적인 아이템 물리(자유낙하) 적용 (0) | 2017.05.02 |
[05]Battery Collector_기초적인 아이템제작 (0) | 2017.04.30 |
[04] BluePrint 집만들기_SlidingDoor, Props, Lighting (0) | 2017.04.23 |