공부/Unreal

24.07.17

월러비 2024. 7. 23. 15:46

SphereTrace

  • TArray<TEnumAsByte<EObjectTypeQuery>>
    • EObjectTypeQuery는 C에서 또는 ‘일반 변수’로 쓰면 상관 없지만, ‘TArray’ 또는 ‘UPROPERTY’에 들어가게 된다면 TEnumAsByte로 지정하고 선언해야한다.
      • Byte형으로 지정되어있으면 상관없지만, 그렇지 않은 경우가 많다.
  • ignores : 추적할때 제외할 액터들을 모아놓은 배열이다.
  • AddRadialImpulse : ‘중심점’으로 부터 ‘지정된 힘’만큼 ‘힘이 퍼지는걸’ 받아서 얼마만큼 날라갈지 정하는 함수다.

Trigger

  • OnActorBeginOverlap : 보통은 다른데서 연결을 했지만 이번 예제는 직접 오버랩 델리게이트를 연결했다.

LineTrace

  • BlueprintAssignable : 블루프린트에서 연결할 수 있도록 열어주는 기능이다.
  • LineTraceSingleByProfile로 추적한거
    • false가 의미하는 것 : 예를 들어, 박스 메쉬의 충돌체 추적을 ‘박스 원형’으로 할것이냐, ‘삼각형의 집합 하나 하나를 추적할것이냐’ 를 정하는 옵션이다.
  • ignores 배열 넣은거

컴파일 속도 너무 느려서 변경한것

  • C:\Users\dpffn\AppData\Roaming\Unreal Engine\UnrealBuildTool
  • PHC false와 코어수 8개로 작성함
  • 원래는 주소 한줄만 있고 아무것도 없었다.

멀티 트레이스

전부 Default일때

  • 채널 : 처음 걸리는 것만 체크
    • Block이 나올때까지 뚫는다.
    • Block을 만나면 뚫는것을 멈춘다.
  • 오브젝트 : 걸리는거 전부 체크
    • Block만 검출한다.

03 예제, 멀티 트레이스

  • Single 탐색은 차이가 없다. : 하나만 충돌하면 끝이기 때문이다.
    • 멀티 충돌 탐색은 Multi, Profile, Objects로 나뉘어서 사용된다.
    • Single도 3가지 방식으로 나뉘지만 별 차이가 없다.
      • 코드의 내부적으로는 Single이나 Multi나 2가지 방식으로 사용된다. ⇒ ‘Chanel’ 과 ‘Objects’
      • LineTraceMulti와 LinTraceMultiByProfile은 Chanel로 구분하기 때문에 내부적으로는 똑같은 기능을 가진다.

ETraceTypeQuery 확인 방법

  • 편집 - 프로젝트 세팅 - 콜리전 - Preset - BlockAll - 트레이스 타입 확인 (오브젝트 타입은 전에 설명 했다고 함)
  • 오브젝트 타입과는 또 다른 그룹이라고 생각해라
    • 오브젝트 타입과 ‘별도로’ 동작하는 그룹이다.
    • 오브젝트 타입 : 충돌과 관련이 있다.
    • 트레이스 타입 : 추적과 관련이 있다.
  • Visibility : 보일거냐
  • Camera : 카메라에 랜더링 될거냐
  • 트레이스 타입은 나중에 직접 만들 수 있다.
  • 기본이 Chanel인 이유 : 기본적으로 트레이스 타입으로 되어있기 때문이다.
    • 오브젝트 for 오브젝트로 하더라도 나중에는 채널로 변경한다.

충돌 탐지 후 출력

  • for로 반복을 시킬때 ‘주소를 참조 &’하면 주소 안의 값이 변경될 수도 있기 때문에 ‘const’를 작성해 상수로 만들어서 값이 변경되지 않도록 해야한다.
    • 변수를 선언할때 static으로 선언하면 최초 한번의 선언으로 ‘공용 영역’으로 넘어가기 때문에 값이 변경되지 않는다.
  • cpp 파일 - 충돌을 무시할 배열 생성 - 충돌 결과를 저장할 배열 생성 - ‘채널’ 로 충돌 추적 함수 호출 - 오브젝트 타입 충돌 지정 - 오브젝트 타입 충돌 추적 함수 호출 - 실행 시간을 누적하여 2초를 기준으로 결과를 출력하게 한다.
//cpp
FVector start = GetActorLocation();
FVector start1 = FVector(start.X + 50, start.Y, start.Z);
FVector start2 = FVector(start.X - 50, start.Y, start.Z);

//600만큼 이동된 위치가 나온다.
FVector end1 = start1 + GetActorForwardVector() * 600; 
FVector end2 = start2 + GetActorForwardVector() * 600; 

//Chanel
//라인트레이스 멀티는 '채널'이다.
//UKismetSystemLibrary::LineTraceMultiByProfile

TArray<AActor*> ignores;

TArray<FHitResult> hitResults1;
TArray<FHitResult> hitResults2;

//TraceTypeQuery1 : 프로젝트 세팅에서 확인할 수 있다. => Visible을 의미한다.
UKismetSystemLibrary::LineTraceMulti(GetWorld(), start1, end1, ETraceTypeQuery::TraceTypeQuery1, false, ignores, EDrawDebugTrace::ForOneFrame, hitResults1, true);

TArray<TEnumAsByte<EObjectTypeQuery>> types;

//ObjectTypeQuery1 : WorldStatic
types.Add(EObjectTypeQuery::ObjectTypeQuery1);

UKismetSystemLibrary::LineTraceMultiForObjects(GetWorld(), start2, end2, types, false, ignores, EDrawDebugTrace::ForOneFrame, hitResults2, true);

TotalTime += DeltaTime;
if (TotalTime >= 2.0f)
{
	TotalTime = 0.0f;

	CLog::Log(FString::Printf(L"-- Channel : %d", hitResults1.Num()));
	for (const FHitResult& hitResult : hitResults1)
	{
		//bBlockingHit : 히트 되었느냐 여부 확인하는 변수다.
		//히트 결과의 액터 : 맞은 적 확인
		FString str = FString::Printf(L"Block : %d, %s", hitResult.bBlockingHit, *hitResult.GetActor()->GetActorLabel());

		CLog::Log(str);
	}

	//오브젝트 형식 어떻게 추적되는지 확인용이다.
	CLog::Log(FString::Printf(L"-- Objects : %d", hitResults2.Num()));
	for (const FHitResult& hitResult : hitResults2)
	{
		CLog::Log(hitResult.GetActor()->GetActorLabel());
	}
}

멀티트레이스 정리

  • Chanel 결과 : 오브젝트 타입에 따라 ‘Block’이 나올때까지 뚫고 지나가는것을 결과로 저장한다.
  • Objects 결과 : ‘Block’으로 막히는 오브젝트만 결과로 저장한다.

 

플레이어 생성

게임 모드 파일들 이름 수정 및 ‘루트 경로’ 새로 지정

  • GameModeBase 파일들 이름변경
  • Build.cs 파일 - 루트 경로 지정
    • 지정하는 이유 : ‘../’를 쓰지않게 ‘모듈 경로’를 넣기 위해서이다.
    PublicIncludePaths.Add(ModuleDirectory);
    

캐릭터에 필요한 컴포넌트 생성

  • 컴포넌트 최상위 부모 : UActorComponent
    • 예, CharactorMovementComponent
  • 배치할 수 있는 액터 : SceneComponent를 상속받은 컴포넌트들이다.
    • CapsuleComponent
    • MeshComponent
  • 데이터를 다루는 컴포넌트는 어딘가에 모양으로 붙는것이 아니다.
    • 액터 컴포넌트로부터 만들어진다.
  • 헤더 파일 - ‘스프링 암 컴포넌트’ 선언 - ‘카메라 컴포넌트’ 선언 - cpp 파일 - 컴포넌트 헤더 추가 - 컴포넌트 추가 - 메쉬 위치 지정 - 메쉬 스켈레톤 경로 지정해서 가져오고 지정 - 스프링 암 설정 - 캐릭터 무브먼트 회전 속도 지정
//header
private:
	UPROPERTY(VisibleAnywhere)
		class USpringArmComponent* SpringArm;

	UPROPERTY(VisibleAnywhere)
		class UCameraComponent* Camera;
	
//cpp
CHelpers::CreateComponent<USpringArmComponent>(this, &SpringArm, "SpringArm", GetMesh());
CHelpers::CreateComponent<UCameraComponent>(this, &Camera, "Camera", SpringArm);

//movement는 CreateComponent로 생성하지 못한다.
//Movement = CreateDefaultSubobject<UCMovementComponent>("Movement");
CHelpers::CreateActorComponent<UCMovementComponent>(this, &Movement, "Movement");

//생성시 메쉬 위치와 회전값
GetMesh()->SetRelativeLocation(FVector(0, 0, -90));
GetMesh()->SetRelativeRotation(FRotator(0, -90, 0));

//스켈레톤 메쉬 지정
USkeletalMesh* mesh;
CHelpers::GetAsset<USkeletalMesh>(&mesh, "SkeletalMesh'/Game/Characters/Mesh/SK_Mannequin.SK_Mannequin'");
GetMesh()->SetSkeletalMesh(mesh);

//스프링암 설정
SpringArm->SetRelativeLocation(FVector(0, 0, 140));
SpringArm->SetRelativeRotation(FRotator(0, 90, 0));
SpringArm->TargetArmLength = 200;
SpringArm->bDoCollisionTest = false;
SpringArm->bUsePawnControlRotation = true;
SpringArm->bEnableCameraLag = true;

// 회전 속도를 지정해 캐릭터가 부드럽게 회전하도록 함
GetCharacterMovement()->RotationRate = FRotator(0, 720, 0);

플레이시 플레이어용 캐릭터 등장시키기

  • 게임 모드 헤더 파일 - 생성자 선언 - cpp 파일 - ‘디폴트 폰 클래스’ 주소로 클래스 가져오기 - 편집 - 프로젝트 세팅 - 맵 & 모드 - 기본 게임모드 : 이름 바꾼 ‘게임 모드 파일’ - 선택된 게임 모드 - 디폴트 폰 클래스에 제대로 들어갔는지 확인
//cpp
CHelpers::GetClass<APawn>(&DefaultPawnClass, "Blueprint'/Game/Player/BP_CPlayer.BP_CPlayer_C'");

애님 인스턴스 클래스 및 블루프린트 생성

  • C++ 클래스 생성 - 모든 클래스 - AnimInstance 검색 - 애니메이션 블루프린트 클릭 - 스켈레톤 지정 - 부모 클래스 : C++ 애님 인스턴스 클래스 지정

기본 상태 애니메이션 출력

  • 플레이어 cpp 파일 - 애님 인스턴스 헤더 추가 - 애님 인스턴스 클래스 선언 및 저장 - 애니메이션 블루프린트 클래스 가져와서 저장 - 메쉬에 애님 클래스 지정 - 애니메이션 블루프린트 - 애니메이션 삽입
//cpp
//애님 클래스 지정
TSubclassOf<UCAnimInstance> animInstance;
CHelpers::GetClass<UCAnimInstance>(&animInstance, "AnimBlueprint'/Game/ABP_Character.ABP_Character_C'");
GetMesh()->SetAnimClass(animInstance);

상속 구조 설명

  • 다룰 수 있는 최상위 클래스 : UObject - AActor - APawn - ACharacter - (작성한)ACPlayer
    • APawn - InputComponent
      • ACharacter는 APawn을 상속받고 있으니 InputComponent 또한 상속받는다.
    • ACharacter - CharacterMovementComponent
    • ACPlayer - 움직임(멈춰라, 이동해라, 회전해라)을 구현할 컴포넌트를 작성 : MovementComponent
      • ACPlayer는 부모들을 상속받아서 ‘배치, 입력, 이동’ 등의 기능들을 같이 상속받는다.
    • UActorComponent - USceneComponent
      • CharacterMovementComponent는 UActorComponent로부터 직접 상속받아져있다.
        • 즉, ‘데이터를 다루기만 한다.’
      • ACharacter 는 USceneComponent로부터 직접 상속받아져있다.

액터 컴포넌트 클래스 생성

  • MovementComponent : 캐릭터의 움직임에 관련된 데이터를 정리하는 클래스를 작성한다.
  • C++ 클래스 생성 - 액터 컴포넌트 클릭

속도 값 선언

  • 헤더 파일 - 열거형 매크로 생성 : 블루프린트 타입으로 선언 - 걷기 ‘ 달리기 ‘ 질주 로 정의 - 속도값 배열 선언 및 속도 정의
//header
UENUM(BlueprintType)
enum class ESpeedType : uint8
{
	Walk = 0, Run, Sprint, Max,
};

private:
	UPROPERTY(EditAnywhere, Category = "Speed")
		float Speed[(int32)ESpeedType::Max] = { 200, 400, 600 };

 

'공부 > Unreal' 카테고리의 다른 글

24.07.19  (0) 2024.07.26
24.07.18  (1) 2024.07.23
24.07.15  (1) 2024.07.17
24.07.12  (0) 2024.07.15
24.07.11  (1) 2024.07.14