Unreal C++/C++ Pawn2018. 8. 22. 18:49

언리얼 엔진에서 C++를 이용한 Pawn 클래스 기반으로 커스텀 폰 클래스 정의하기


언리얼 엔진에서 Actor와 Pawn이 다른 점은 Pawn은 AddMovementInput()함수를 사용하여 전후좌우상하로 이동할 수 있으므로 키보드의 입력을 Pawn에 반영할 수 있다는 것이다


여기서는 C++를 사용하여 Pawn 기반의 MyPawn 클래스를 생성하고 키보드(W, A, S, D)키를 누를 때마다 해당 폰이 전후좌우로 이동하는 기능을 작성해보고자 한다


C++ 프로젝트 생성

Pawn 기반 C++ 클래스 생성(MyPawn)



.h 헤더파일 ( 적색 코드는 추가한 내용)

// Fill out your copyright notice in the Description page of Project Settings.


#pragma once


#include "CoreMinimal.h"

#include "GameFramework/Pawn.h"

#include "Components/InputComponent.h"

#include "GameFramework/FloatingPawnMovement.h"

#include "Camera/CameraComponent.h"

#include "MyPawn.generated.h"


UCLASS()

class CPP_PAWN_TEST_API AMyPawn : public APawn

{

GENERATED_BODY()


public:

// Sets default values for this pawn's properties

AMyPawn();


UPROPERTY(EditAnywhere)

UStaticMeshComponent* Mesh;


UPROPERTY(EditAnywhere)

UCameraComponent* Camera;


protected:

// Called when the game starts or when spawned

virtual void BeginPlay() override;


public:

// Called every frame

virtual void Tick(float DeltaTime) override;


// Called to bind functionality to input

virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;


void MoveForward(float Value);

void MoveRight(float Value);

};



.cpp 파일 (적색 코드는 추가된 내용)

// Fill out your copyright notice in the Description page of Project Settings.


#include "MyPawn.h"


// Sets default values

AMyPawn::AMyPawn()

{

  // Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.

PrimaryActorTick.bCanEverTick = true;


Mesh = CreateDefaultSubobject<UStaticMeshComponent>("MyMesh");

CreateDefaultSubobject<UFloatingPawnMovement>("PawnMovement");

Camera = CreateDefaultSubobject<UCameraComponent>("MyCamera");

}


// Called when the game starts or when spawned

void AMyPawn::BeginPlay()

{

Super::BeginPlay();

}


// Called every frame

void AMyPawn::Tick(float DeltaTime)

{

Super::Tick(DeltaTime);

}


// Called to bind functionality to input

void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)

{

Super::SetupPlayerInputComponent(PlayerInputComponent);

PlayerInputComponent->BindAxis("MoveForward", this, &AMyPawn::MoveForward);

PlayerInputComponent->BindAxis("MoveRight", this, &AMyPawn::MoveRight);

}


void AMyPawn::MoveForward(float Value)

{

AddMovementInput(GetActorForwardVector(), Value);

}


void AMyPawn::MoveRight(float Value)

{

AddMovementInput(GetActorRightVector(), Value);

}



Axis Mappings

언리얼 에디터에서 Edit > 프로젝트 세팅 > 엔진 > 입력 > Axis Mappings

MoveForward 라는 바인딩 이름으로 W(1.0), S(-1.0) 등록

MoveRight 라는 바인딩 이름으로  D(1.0), A(-1.0) 키를 등록



실행 테스트

완성된 C++ MyPawn 클래스를 Content Browser에서 드래그하여 뷰포트에 놓는다

컴포넌트로 포함된 카메라의 위치와 각도를 언리얼 에디터에서 변경하려면 Camera 변수에 매크로UFUNCTION(EditAnywhere0 를 설정해 주어야 한다

뷰포트에서 MyPawn을 선택하고 [디테일] 뷰에서 Mesh 변수를 선택한 후 Static Mesh 패널에서 Cube 등 임의의 메시를 선택하여 설정한다


게임을 실행하여 W, S, A, D 키를 이용하여 이동할 수 있는지 확인한다

만약 카메라만 이동하고 메시가 이동하지 않으면, Mesh 변수를 선택하고 [디테일]뷰의 Pawn 패널에서 Auto Possess Player 항목에 Disabled 가 아닌 Player0를 설정하면 된다


Posted by cwisky
Unreal C++/C++ Actor2018. 8. 21. 18:57

C++ 클래스를 이용하여 액터를 생성하고 Z 위치를 변경하는 예

https://www.youtube.com/watch?v=K8iSi1oGaBI


C++ 프로젝트 생성

C++ 클래스 생성(Actor 클래스 기반, 클래스이름: CubeActor 등으로 지정)

Content Browser 안에 C++ 클래스가 보이지 않으면 우측 하단의 [뷰옵션] > [C++ 클래스 표시] 선택

VS에 CubeActor.h, CubeActor.cpp 파일이 생성된다


CubeActor.cpp의 Tick 함수에 아래의 적색부분 같이 작성하여 게임 시작시에 큐브가 상승하도록 한다

// Fill out your copyright notice in the Description page of Project Settings.


#include "CubeActor.h"



// Sets default values

ACubeActor::ACubeActor()

{

  // 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;

}


// Called when the game starts or when spawned

void ACubeActor::BeginPlay()

{

Super::BeginPlay();

}


// Called every frame

void ACubeActor::Tick(float DeltaTime)

{

Super::Tick(DeltaTime);

FVector NewLoc = GetActorLocation();

NewLoc.Z += 5;

SetActorLocation(NewLoc);

}


위와 같이 cpp 파일을 편집하여 VS에서 저장하고 UE4의 툴바에서 [컴파일] 버튼을 누른다

컴파일이 완료되면 컨텐츠 브라우저에서 CubeActor를 드래그하여 뷰포트에 올릴 수 있지만 아무런 형제가 없기에 뷰포트에서 선택할 수도 없는 상태가 된다

이와같이 C++ 액터클래스 드래그하여 뷰포트에서 보여지고 또 마우스로 선택이 가능하도록 하려면 가시적인 컴포넌트 한개는 있어야 한다.


C++액터 클래스에 컴포넌트를 포함시키고자 한다면 다음과 같은 코드를 h, cpp 파일에 추가한다(적색부분 참조)

// Fill out your copyright notice in the Description page of Project Settings.


#pragma once


#include "CoreMinimal.h"

#include "GameFramework/Actor.h"

#include "CubeActor.generated.h"


UCLASS()

class CPP_CUBE_API ACubeActor : public AActor

{

GENERATED_BODY()

public:

// Sets default values for this actor's properties

ACubeActor();


protected:

// Called when the game starts or when spawned

virtual void BeginPlay() override;


public:

// Called every frame

virtual void Tick(float DeltaTime) override;


UPROPERTY(EditAnywhere)

UStaticMeshComponent* Mesh;

};



cpp 코드에 다음과 같이 액터에 컴포넌트를 등록하는 부분을 작성한다

// Fill out your copyright notice in the Description page of Project Settings.


#include "CubeActor.h"



// Sets default values

ACubeActor::ACubeActor()

{

  // 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;

Mesh = CreateDefaultSubobject<UStaticMeshComponent>("MyMesh");

}


// Called when the game starts or when spawned

void ACubeActor::BeginPlay()

{

Super::BeginPlay();

}


// Called every frame

void ACubeActor::Tick(float DeltaTime)

{

Super::Tick(DeltaTime);

FVector NewLoc = GetActorLocation();

NewLoc.Z += 5;

SetActorLocation(NewLoc);

}




위와같이 작성이 되었으면 VS에서 저장하고 UE4에서 [컴파일] 버튼을 누르고 컴파일을 완료한다

이제 컨텐츠 브라우저에서 CubeActor 를 드래그하여 뷰포트에 올리면 뷰포트에 형체는 없지만 방향표시 기즈모가 나타나기 때문에 [디테일] 뷰에서 Mesh 변수에 구체적인 스테틱 메시를 지정해 줄 수 있게 된다




Posted by cwisky

언리얼 엔진에서 C++ 클래스는 Blueprint 클래스 안에서 변수로 선언될 수도 있고 블루프르린트 클래스의 부모 클래스가 될 수 있다. 

아래처럼 UCLASS 매크로를 선언해주면 된다


UCLASS (BlueprintType)     // BP안에 선언되는 변수의 자료형(Type)이 될 수 있도록 선언

UCLASS Blueprintable)      // BP 클래스를 생성할 때 부모 클래스가 될 수 있도록 선언

UCLASS(Blueprintable, BlueprintType)


#include "Object.h"


#include "PlayerClass.generated.h"


UCLASS(BlueprintType)


class PROTOTYPE2_API UPlayerClass : public UObject

{

   GENERATED_BODY()


public:


UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Player Variables")

FString playerName;


UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Player Variables")

FString playerTeam;


UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Player Variables")

FString picPath;


UPlayerClass(const FObjectInitializer& ObjectInitializer);


UFUNCTION(BlueprintCallable, Category = "Import")

virtual void ImportPic(const FString& Path);


};



언리얼 엔진에서는 모든 식별자에 Pascal Case(첫자를 대문자로) 사용


언리얼  클래스 Prefix


U - UObject 하위 클래스 예) UTexture

A - AActor 하위 클래스 예) AGameMode

F - 이외의 모든 클래스와 struct 들 예) FName, FVector

T - 템플릿 예) TArray, TMap

I - 인터페이스 클래스 예) ITransaction

E - Enum 타입 예) ESelectionMode

b - Boolean 변수 예) bEnabled



C++ 변수가 BP의 Set, Get 노드 지원되도록 하려면

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Damage")

int32 TotalDamage;



C++ 클래스를 BP 안에서 인스턴스화하고 함수를 호출하는 예

Blueprint 프로젝트 안에서 Object 클래스를 기반으로 C++클래스를 아래처럼 생성한다


MyObject.h

// Fill out your copyright notice in the Description page of Project Settings.


#pragma once


#include "CoreMinimal.h"

#include "UObject/NoExportTypes.h"

#include "MyObject.generated.h"


/**

 * 

 */

UCLASS(BlueprintType)

class CPP_IN_BPPROJ_API UMyObject : public UObject

{

GENERATED_BODY()

public:

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Test")

int Score;


UFUNCTION(BlueprintCallable, Category="Test")

int Add(int a, int b);


UFUNCTION(BlueprintCallable, Category = "Test")

static void Create(UClass *ObjectClass, UMyObject* &CreatedObject);

};




MyObject.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "MyObject.h"


int UMyObject::Add(int a, int b)

{

return a+b;

}


void UMyObject::Create(UClass * ObjectClass, UMyObject *& CreatedObject)

{

CreatedObject = NewObject<UMyObject>((UMyObject*)GetTransientPackage(), ObjectClass);

}



Blueprint 클래스에서 다음과 같이 MyObject 클래스의 인스턴스를 생성하고 사용할 수 있다


Posted by cwisky
Android Screen Mirroring2018. 8. 15. 22:44

Screen Mirroring

동일한 WiFi 네트워크에 연결된 PC와 스마트폰이 있다면 스마트폰에 앱을 설치하여 스마트폰의 화면을 PC 모니터에 표시할 수 있다


PC와 스마트폰 측에서 각각 설정을 해줘야 한다


Windows 10에서 설정하기

시작 > 설정 > 시스템 > PC에 화면표시



안드로이드 폰에서 설정하기


화면 상단 설정 패널을 열고 검색란을 선택한다





검색란에 screen mirroring 라고 입력하고 검색하여 Screen Mirroring Assistant 를 선택하여 설치한다




Screen Mirroring Assistant을 설치한 후에 앱을 실행한다






앱이 실행되면 START 버튼을 누른다





동일한 WiFi 네트워크에 연결된 PC의 이름을 자동으로 찾아 아래처럼 표시해주므로 선택한다




연결대상 PC의 화면 우측하단에 다음과 같은 메시지가 뜨면 [예] 버튼을 누른다. 

잠시후 PC모니터에 스마트폰 화면이 표시된다



Posted by cwisky
HUD2018. 8. 14. 19:42

HUD ( Head Up Display)

  • 이용자 인터페이스 이벤트를 생성하기 위해 UE3에서 부터 사용되어 왔으며 UE4에서 새로 추가된 UMG가 그 자리를 대체하므로 사용빈도는 줄었지만 단순한 이용자 인터페이스신속히 작성하여 테스트해보기 위해서 여전히 사용되고 있다 
  • HUD 클래스는 화면에 인터페이스를 표시하기 위해 DrawText, DrawLine DrawTexture, DrawRect 등 다양한 함수를 포함하고 있고 이용자의 마우스에 반응하는 HitBox도 추가할 수 있다
  • 위젯과 함께 사용할 수도 있으며 서로 독립적으로 작동한다
  • 화면의 동일한 위치에 위젯과 HUD가 내용을 표시하는 경우에는 위젯이 위에 그려진다
  • Set Show HUD : 화면에 표시되는 HUD를 보이거나 보이지 않게 할 수 있다
  • Set Show Debug Info : 몇가지 기본적인 디버깅 정보가 출력되도록 ON/OFF 할 수 있다
  • HUD 클래스가 아닌 다른 클래스에서 HUD 인스턴스에 접근하기 위해서는 다음과 같이 하면된다
  • GetPlayerController->GetHUD
  • Receive Draw HUD 이벤트를 이용하여 DrawText 등의 기능을 사용한다
  • HUD 클래스가 제공하는 Add HitBox 노드를 사용하면 보이지 않는 박스를 스크린에 설정할 수 있다
  • 화면에 추가된 HitBox는 보이지 않기 때문에 보이도록 하려면 그 위에 사각형(Draw Rect)을 그려주면 된다
  • HitBox는 Cursor Over, Click 이벤트를 발생하므로 이용자의 마우스에 반응할 수 있는 기능을 작성할 수 있다


HUD 테스트 절차

  1. 커스텀 GameMode 클래스 생성
  2. 커스텀 HUD 클래스 생성(HUD_Test)
  3. GameMode 에서 커스텀 HUD클래스를 등록
  4. 월드셋팅/Game Mode 패널에서 커스텀 GameMode 등록
  5. HUD 클래스의 이벤트 그래프에서 HUD 설정과 이벤트를 정의한다


HUD_Test 의 이벤트 그래프에 다음과 같이 작성

작성된 HUD의 내용이 화면에 표시되기 위해서는 Set Show HUD 노드에서 체크해야 한다

아래의 Show Debug Info노드에 체크하면 몇가지 기본적인 디버깅 메시지가 화면에 표시되지만 Draw Text 기능은 작동하지 않으므로 주의한다



Posted by cwisky
AI Perception2018. 7. 12. 00:26

UE4에서 액터의 시각으로 상대 액터를 인지하는 인공지능 기능을 사용하기 위한 컴포넌트 설정법. 아래의 예는 2D 횡스크롤 게임 환경에서 사용한 경우이다


1. 상대방에게 감지 당할 액터에게는 AI Perception Stimuli Source 컴포넌트를 추가한다



2. AI Perception Stimuli Source 컴포넌트를 가진 상대방을 감지하고자 하는 액터에 AI Perception 컴포넌트를 추가하고 On Perception Updated 이벤트를 추가한다




소음을 발생하고 상대방이 소음에 반응하도록 설정하기


총소리와 같은 소음을 발생시켜서 상대방에게 자극이 전달되도록 하려면 Report Noise Event 노드를 사용하면 된다. 이 기능은 AI Perception Stimuli Source 콤포넌트와는 무관하고 다른 설정은 필요 없다

아래처럼 소음을 발생시킬 때 Tag 에 입력된 문자열을 소음 수신측에서 소음을 구별할 때 사용할 수 있다


AI 소음 발생 스크립트

소음을 발생시 태그를 사용하면 수신측에서 쉽게 구별할 수 있다



On Target Perception Updated 이벤트에서 소음을 인지하는 예

아래의 예는 소음 발생 측에서 설정한 Tag를 수신측에서 활용하고 있다



2가지 자극(AISense_Sight, AISense_Hearing ) 모두를 감지하기 위한 AI 소음 수신측의 AIPerception 설정



시각 및 청각적 감지를 위한 노드구성의 예 ( 소리 감지는 Cast Failed 핀으로부터 시작됨을 주의 )




발견했던 플레이어를 다시 놓친 경우의 탐지방법


Posted by cwisky
Networking/Network Cube2017. 12. 28. 11:01

http://unrealengine.tistory.com/category/Networking/Actor%2C%20Function%20Replication

Posted by cwisky
가위 바위 보2017. 12. 28. 02:59

목표 : 언리얼 엔진을 이용하여 2사람이 네트워크 상에서 가위 바위 보 게임을 할 수 있도록 서버와 클라이언트 기능을 완성한다. User Interface, PlayerController, GameMode 컴포넌트들을 적절히 사용하는 방법을 이해하고 사용할 수 있다


언리얼에서 지원하는 Listen Server 시스템을 사용한다

아래의 예제는 완성된 것이 아니므로 이를 참고하여 학습에 도움이 되도록 사용하면 된다


가위 바위 보를 5초 이내에 제시하여 한번의 승부를 결정하고 이와 같은 내용을 3회 반복하여 최종 승부를 판단하며 그 결과를 각 클라이언트 와면에 출력하고 끝난다


위젯 블루프린트 생성

컨텐츠 브라우저에서 마우스 우측 > User Interface > 위젯 블루프린트 > 이름을 BP_GameWidget 으로 입력한다


BP_GameWidget디자이너 모드 화면구성




BP_GameWidget그래프 화면구성



커스텀 PlayerController 생성 (BP_PlayerController)



커스텀 GameMode 생성 (BP_GameMode)



BP_GameMode Count_Down 함수

Posted by cwisky
Mouse Over Color Change2017. 12. 24. 22:47

목표 : 큐브에 마우스가 올라가면 큐브의 색상이 변경되고 내려가면 원래 색상으로 복귀하는 기능을 구현한다


오브젝트(큐브) 위에 마우스 커서가 올라가면 On Begin Cursor Over (cube) 이벤트가 작동한다.

On Begin Cursor Over 이벤트에서 동적 머티리얼의 색상을 변경하면 된다


실행 중에 오브젝트의 머티리얼 기본색상을 변경해야 하므로 동적 머티리얼 인스턴스(Dynamic Material Instance)를 사용해야 한다


1. 공백 프로젝트를 생성한다

2. 컨텐츠 브라우저에서 마우스 우측 > 블루프린트 클래스 > Actor > 이름을 BP_CubeActor 으로 지정한다

3. BP_CubeActor 를 더블클릭하여 열고 [컴포넌트 추가] 버튼을 눌러 큐브를 추가한다



4. 머티리얼을 생성하여 기본색상에 Vector Parameter 노드를 연결한다

 - 컨텐츠 브라우저에서 마우스 우측 > 머티리얼 > 이름을 M_CubeMat 으로 입력한다

 - M_CubeMat를 더블클릭하여 열고 그래프 바탕에서 마우스 우측 > VectorParameter 검색하여 노드 추가

 - 노드의 이름을 ColorParam 으로 입력하고 기본색상을 임의로 선택한다



5. BP_CubeActor의 Cube 컴포넌트를 선택하고 [디테일] 뷰의 Material 패널에서 앞서 작성된 M_CubeMat를 설정한다



6. BP_CubeActor의 이벤트 그래프에 다음과 같은 내용을 입력한다



7. BP_CubeActor를 드래그하여 뷰포트에 올리고 실행하여 마우스를 큐브에 올리면 다음과 같이 색상이 변경되고 마우스를 내리면 원래의 색상으로 돌아오는 것을 확인할 수 있다





Posted by cwisky
Cube Color Change2017. 12. 24. 18:34

Dynamic Material Instance


목표 : 큐브가 상하로 이동하면서 1초 주기로 큐브의 색상이 변경되는 작성한다


실행 중에 오브젝트의 재질을 변경하려면 Dynamic Material Instance 방법을 사용해야 한다.


Dynamic Material Instance

머티리얼을 생성하고 편집할 때 머티리얼의 기본색상을 정적인 값으로 설정하면 실행 중에는 머티리얼의 색상을 변경할 수는 없으므로 머티리얼의 기본색상(Base Color)을 설정할 때 Vector Parameter로 설정하고 그 노드의 이름을 기억했다가 스크립트에서 사용하여 실행시간에 색상을 지정할 수 있다


공백 프로젝트를 생성하고 아래의 절차를 따라 동적 머티리얼을 테스트한다


1. 큐브에 적용할 머티리얼을 생성한다

 - 컨텐츠 브라우저에서 마우스 우측 > 머티리얼 > 이름을 M_CubeMat 으로 지정한다


2. M_CubeMat 를 더블클릭하여 열고 기본색상을 파라미터로 설정한다


위의 그림에서 CubeColor 노드는 Vector Parameter 를 검색하면 추가할 수 있고 노드의 이름은 왼쪽 [디테일]뷰의 Parameter 항목에서 편집할 수 있다. 초기의 색상을 편집하려면 CubeColor 노드를 더블클릭하여 색상선택기를 이용하면 된다 



3. 완성된 머티리얼을 원하는 메시에 적용한다

 - 클래스 블루프린트를 생성하고 컴포넌트 추가 버튼을 눌러 큐브를 추가한다

 - 컴포넌트로 추가된 큐브를 선택하고 우측 [디테일] 뷰 / Material 항목에 앞서 생성한 머티리얼(M_CubeMat)을 지정한다



4. 오브젝트에 설정된 머티리얼의 색상을 변경하려면 [Construction Script] 혹은 [이벤트 그래프] 를 이용한다

 - Construction Script에서 머티리얼의 기본색상을 변경하면 언리얼 레벨에디터 상에서 바로 실행되어 효과를 확인할 수 있다.

 - 이벤트 그래프에서 머티리얼의 기본색상을 변경하면 실행시간에만 그 효과를 확인할 수 있다


5. BP_Cube의 Construction Script 탭을 누르고 다음과 같이 작성하면 언리얼 에디터에서 동적 머티리얼의 효과를 볼 수 있다. 동적 머티리얼 인스터스를 생성하고 벡터 파라미터에 임의의 색상을 설정하는 내용이다. 여기서 생성된 MatInstance는 이벤트 그래프에서도 그대로 사용할 수가 있다




6. BP_Cube의 [이벤트 그래프에 다음과 같이 작성한다. 큐브가 상하로 이동하는 중에 1초 주기 마다 큐브의 색상이 임의의 색상으로 변경되도록 한 것이다


위에서 사용된 타임라인 노드는 다음과 같이 설정한다



모두 완성한 후에 실행해보면 다음 그림과 같이 1초마다 큐브의 색상이 임의의 색상으로 변경되고 상하 이동 애니메이션도 제대로 작동하는 것을 확인할 수 있다



Posted by cwisky