09. Extending the Character Class / 10.Collecting Pickups
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 |
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "GameFramework/Actor.h"
#include "Pickup.generated.h"
UCLASS()
class BATTERYCOLLECTOR_API APickup : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
APickup();
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every frame
virtual void Tick( float DeltaSeconds ) override;
/**Return the mesh for the pickup*/
FORCEINLINE class UStaticMeshComponent* GetMesh() const{ return PickupMesh; }
UFUNCTION(BlueprintPure, Category = "Pickup")
bool IsActive(); //값을 반환해줄 함수
//Allows other classes to saftely change whether or not pickup is active
UFUNCTION(BluePrintCallable, Category = "Pickup")
void SetActive(bool NewPickupState);
//Function to call when the pickup is collected
UFUNCTION(BlueprintNativeEvent)
void WasCollected();//배터리 아이템을 먹고 일어나야할일?
virtual void WasCollected_Implementation();
protected:
/**True when the pickup can be used, and false when pickup is deactivated*/
bool blsActive;
private:
//static mesh to represent the pickup in the level
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pickup", meta = (AllowPrivateAccess = "true"))
class UStaticMeshComponent* PickupMesh;
};
|
cs |
캐릭터에서 블루프린트 네이티브 이벤트는 이벤트 발생시 코드에서 설정한 부분을 실행한다.
블루프린트에서는 설정불가.
임플멘테이션(Implementation): virtual 함수, 자식클래스에서 오버라이딩이 가능해야한다.
34)자식 클래스에서 오버라이딩 할 수 있다.
하지만 하나의 함수호출로 wascollected를 코드 임플멘테이션과 블루프린트 임플멘테이션이
호출하는 방법 대로만 실행된다. 그래서 둘을 같이 놓거나 둘다 만들어놓거나 하지 않는다.
pickup.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 |
// Fill out your copyright notice in the Description page of Project Settings.
#include "BatteryCollector.h"
#include "Pickup.h"
// Sets default values
APickup::APickup()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
//all pickups start activate
blsActive = true;
PickupMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("PickupMesh"));
RootComponent = PickupMesh;
}
// Called when the game starts or when spawned
void APickup::BeginPlay()
{
Super::BeginPlay();
}
void APickup::Tick(float DeltaTime){
Super::Tick(DeltaTime);
}
//return active state
bool APickup::IsActive(){
return blsActive;
}
//change active state
void APickup::SetActive(bool NewPickupState){
blsActive = NewPickupState;
}
void APickup::WasCollected_Implementation(){
//log a debug message
FString PickupDebugString = GetName();
UE_LOG(LogClass, Log, TEXT("You have collected &s"), *PickupDebugString);
} |
cs |
40)LogClass는 기본 임플멘테이션에 사용된다.
BatteryPickup.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 |
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Pickup.h"
#include "BatteryPickup.generated.h"
UCLASS()
class BATTERYCOLLECTOR_API ABatteryPickup : public APickup
{
GENERATED_BODY()
// Sets default values for this actor's properties
public:
ABatteryPickup();
// Called when the game starts or when spawned
virtual void BeginPlay() override;
/**Override the WasCollected function_us Implementation
because it's a Bluepirnt Native Event*/
void WasCollected_Implementation() override;
};
|
cs |
21) WasCollected 함수 오버라이드. 블루프린트 네이티브 이벤트이기 때문에 임플멘테이션 사용.
BatteryPickup.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 |
// Fill out your copyright notice in the Description page of Project Settings.
#include "BatteryCollector.h"
#include "BatteryPickup.h"
//Set Default values
ABatteryPickup::ABatteryPickup(){
//GetMesh()->SetSimulatePhysics(true);
//생성되자마자 자유낙하(물리적용)
}
void ABatteryPickup::BeginPlay()
{
Super::BeginPlay();
GetMesh()->SetSimulatePhysics(true);
}
void ABatteryPickup::WasCollected_Implementation(){
//Use the base pickup behavior
Super::WasCollected_Implementation();
//Destroy the battery
Destroy();
}
|
cs |
BatteryCollectorCharacter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 |
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "GameFramework/Character.h"
#include "BatteryCollectorCharacter.generated.h"
UCLASS(config=Game)
class ABatteryCollectorCharacter : public ACharacter
{
GENERATED_BODY()
/** Camera boom positioning the camera behind the character */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class USpringArmComponent* CameraBoom;
/** Follow camera */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class UCameraComponent* FollowCamera;
/** Collection sphere */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class USphereComponent* CollectionSphere; |
cs |
19~21) 캐릭터에 아이템 인식을 위한 원 추가.
BatteryCollectorCharacter.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99 |
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#include "BatteryCollector.h"
#include "BatteryCollectorCharacter.h"
#include "Pickup.h"
//////////////////////////////////////////////////////////////////////////
// ABatteryCollectorCharacter
ABatteryCollectorCharacter::ABatteryCollectorCharacter()
{
// Set size for collision capsule
GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);
// set our turn rates for input
BaseTurnRate = 45.f;
BaseLookUpRate = 45.f;
// Don't rotate when the controller rotates. Let that just affect the camera.
bUseControllerRotationPitch = false;
bUseControllerRotationYaw = false;
bUseControllerRotationRoll = false;
// Configure character movement
GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input...
GetCharacterMovement()->RotationRate = FRotator(0.0f, 540.0f, 0.0f); // ...at this rotation rate
GetCharacterMovement()->JumpZVelocity = 600.f;
GetCharacterMovement()->AirControl = 0.2f;
// Create a camera boom (pulls in towards the player if there is a collision)
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
CameraBoom->AttachTo(RootComponent);
CameraBoom->TargetArmLength = 300.0f; // The camera follows at this distance behind the character
CameraBoom->bUsePawnControlRotation = true; // Rotate the arm based on the controller
// Create a follow camera
FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
FollowCamera->AttachTo(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation
FollowCamera->bUsePawnControlRotation = false; // Camera does not rotate relative to arm
//create the collection sphere
CollectionSphere = CreateDefaultSubobject<USphereComponent>(TEXT("CollectionSphere"));
CollectionSphere->AttachTo(RootComponent);
CollectionSphere->SetSphereRadius(300.0f);
// Note: The skeletal mesh and anim blueprint references on the Mesh component (inherited from Character)
// are set in the derived blueprint asset named MyCharacter (to avoid direct content references in C++)
}
//////////////////////////////////////////////////////////////////////////
// Input
void ABatteryCollectorCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
// Set up gameplay key bindings
check(InputComponent);
InputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
InputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
InputComponent->BindAction("Collect", IE_Pressed, this, &ABatteryCollectorCharacter::CollectPickups);
InputComponent->BindAxis("MoveForward", this, &ABatteryCollectorCharacter::MoveForward);
InputComponent->BindAxis("MoveRight", this, &ABatteryCollectorCharacter::MoveRight);
// We have 2 versions of the rotation bindings to handle different kinds of devices differently
// "turn" handles devices that provide an absolute delta, such as a mouse.
// "turnrate" is for devices that we choose to treat as a rate of change, such as an analog joystick
InputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
InputComponent->BindAxis("TurnRate", this, &ABatteryCollectorCharacter::TurnAtRate);
InputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
InputComponent->BindAxis("LookUpRate", this, &ABatteryCollectorCharacter::LookUpAtRate);
// handle touch devices
InputComponent->BindTouch(IE_Pressed, this, &ABatteryCollectorCharacter::TouchStarted);
InputComponent->BindTouch(IE_Released, this, &ABatteryCollectorCharacter::TouchStopped);
}
void ABatteryCollectorCharacter::CollectPickups(){
//Get all overlapping actors and store them in an array
TArray < AActor* > CollectedActors;
CollectionSphere->GetOverlappingActors(CollectedActors);
//For each Actor we collected
for (int32 iCollected = 0; iCollected < CollectedActors.Num(); ++iCollected){
// Cast the actor to APickup
APickup* const TestPickup = Cast<APickup>(CollectedActors[iCollected]);
//If the cast is successful and the pickup is valid and active
if (TestPickup && !TestPickup->IsPendingKill() && TestPickup->IsActive()){
//call the pickup's wascollected function
TestPickup->WasCollected();
//deactivate the pickup
TestPickup->SetActive(false);
}
}
}
|
cs |
44~46)원 추가.
60,61)BindAction 점프와 같이 일회성 이벤트를 발생시키는 것
BindAxis 회전 등 두 말단 사이의 값이 지속적으로 전달되는 이벤트를 발생시킨다.
76~96)추가
79, 80) CollectionSphere와 오버랩되는 모든 액터를 배열로 받아옴
82~)월드에 놓이게되면 자동으로 오버랩 시작/끝, 이벤트가 시작되서 일어나는 모든 액터를 기록하게 된다.
85) 오버랩되는 액터중 연관있는 액터만 형변환으로 걸러낸다.
89~91) 해당아이템의 wasCollected 함수를 호출한다
BatteryCollectorCharacter.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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 |
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "GameFramework/Character.h"
#include "BatteryCollectorCharacter.generated.h"
UCLASS(config=Game)
class ABatteryCollectorCharacter : public ACharacter
{
GENERATED_BODY()
/** Camera boom positioning the camera behind the character */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class USpringArmComponent* CameraBoom;
/** Follow camera */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class UCameraComponent* FollowCamera;
/** Collection sphere */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class USphereComponent* CollectionSphere;
public:
ABatteryCollectorCharacter();
/** Base turn rate, in deg/sec. Other scaling may affect final turn rate. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
float BaseTurnRate;
/** Base look up/down rate, in deg/sec. Other scaling may affect final rate. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
float BaseLookUpRate;
protected:
/** Called for forwards/backward input */
void MoveForward(float Value);
/** Called for side to side input */
void MoveRight(float Value);
/**
* Called via input to turn at a given rate.
* @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
*/
void TurnAtRate(float Rate);
/**
* Called via input to turn look up/down at a given rate.
* @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
*/
void LookUpAtRate(float Rate);
/** Handler for when a touch input begins. */
void TouchStarted(ETouchIndex::Type FingerIndex, FVector Location);
/** Handler for when a touch input stops. */
void TouchStopped(ETouchIndex::Type FingerIndex, FVector Location);
protected:
// APawn interface
virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;
// End of APawn interface
/*CAlled when we press a key to collect any pickups inside the CollectionSphere*/
UFUNCTION(BlueprintCallable, Category = "Pickups")
void CollectPickups();
public:
/** Returns CameraBoom subobject **/
FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
/** Returns FollowCamera subobject **/
FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }
/**return collectionsphere subobject*/
FORCEINLINE class USphereComponent* GetCollectionSphere() const { return CollectionSphere; }
};
|
cs |
'프로그래밍 > Unreal' 카테고리의 다른 글
[09]Battery Collector _ power 일정수준씩 감소시키기 (0) | 2017.05.11 |
---|---|
[08]Battery Collector_power추가, 아이템 획득시 power 증가시키기 (0) | 2017.05.07 |
[06]Battery Collector _ spawn 결정(언제, 어디서, 무엇을) (0) | 2017.05.02 |
[06]Battery Collector_기초적인 아이템 물리(자유낙하) 적용 (0) | 2017.05.02 |
[05]Battery Collector_기초적인 아이템제작 (0) | 2017.04.30 |