(Udemy) Unreal Engine C++ The Ultimate Game Developer Course (2)
섹션 8: Combat
59. Attaching to Sockets
스켈레탈 메쉬에 만들어둔 소켓을 사용
void AWeapon::Equip(AMain* Char)
{
if (Char)
{
SkeletalMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore);
SkeletalMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Ignore);
SkeletalMesh->SetSimulatePhysics(false);
const USkeletalMeshSocket* RightHandSocket = Char->GetMesh()->GetSocketByName("RightHandSocket");
if (RightHandSocket)
{
RightHandSocket->AttachActor(this, Char->GetMesh());
bRotate = false;
}
}
}
60. Weapon Equipping
마우스 왼쪽 버튼을 맵핑해서 무기에 오버래핑 할때 왼쪽클릭하면 지정된 소켓에 부착한다.
이전에 만들어둔 파티클컴포넌트도 사용
61. Weapon Equipping (continued)
62. Switching Blendspaces
스테이트머신 안에 또 스테이트머신을 만들어서 상황별 애니메이션을 설정할수 있음.
여기선 idle/walk/running이 무기를 들었는지 안들었는지에 따라 별개의 블렌드스페이스를 사용.
63. Anim Montages (Attack!)
애니메이션 몽타주를 사용하여 공격 모션을 재생해본다.
void AMain::Attack()
{
bAttacking = true;
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
if (AnimInstance && CombatMontage)
{
AnimInstance->Montage_Play(CombatMontage, 1.35f);
AnimInstance->Montage_JumpToSection(FName("Attack_1"), CombatMontage);
}
}
64. Anim Montages (continued)
Notifies를 넣어서 이벤트 노드로 써먹을 수 있다.
65. Anim Montages (continued)
66. Enemy Combat
플레이어와 마찬가지로 애니메이션 블루프린트와 블렌드스페이스로 적의 애니메이션을 설정.
67. Enemy Combat (continued)
큰 원 하나로 충돌판정을 하여 플레이어를 따라오게 한다.
C++ 코드로 AIController를 사용하기 위해선 build.cs 에다가 "AIModule"을 추가해야 된다. 인클루드는 그냥 "AIController.h"
void AEnemy::MoveToTarget(AMain* Target)
{
SetEnemyMovementStatus(EEnemyMovementStatus::EMS_MoveToTarget);
if (AIController)
{
FAIMoveRequest MoveRequest;
MoveRequest.SetGoalActor(Target);
MoveRequest.SetAcceptanceRadius(5.f);
FNavPathSharedPtr NavPath;
AIController->MoveTo(MoveRequest, &NavPath);
}
}
AcceptanceRadius는 목표지점에 얼마나 가까워져야 성공으로 간주할지의 거리고,
MoveTo의 두번째 인자는 Out으로 정보들을 출력한다.
68. Enemy Combat (continued)
69. Enemy Combat (continued)
70. Console Controller Input
71. Combat Mechanics
무기에도 콜리젼 볼륨을 만들어서 몬스터와 충돌하게 한다.
72. Combat Mechanics (continued)
73. Combat Mechanics (continued)
74. Combat Mechanics (continued)
몬스터도 플레이어와 마찬가지로 몽타쥬와 Notifies를 활용하여 공격
75. Interpolating to the Enemy
76. Enemy Attack Delay
77. Damage and Death
78. Enemy Health Bar
79. Fine Tuning Character Death
80. Fine Tuning Character Death (continued)
81. Refining Pickups
82. Refining Sprinting
83. Extending the Enemy Class
84. Extending the Enemy Class (continued)
85. Refining Gameplay
86. Refining Gameplay (continued)
87. Weapon Trails
소켓 두개를 심고 몽타쥬에 Trail을 설치하여 웨폰 트레일 만들기
88. Spawn Volume Improved
뒤로 갈수록 저자의 엉성한 코딩에 고통받는중.. 빨리 끝내자
섹션 9: Level Changing and Saving the Game
89. Changing Levels in Game
void AMain::SwitchLevel(FName LevelName)
{
auto World = GetWorld();
if (World)
{
FString CurrentLevel = World->GetMapName();
if (FName(CurrentLevel) != LevelName)
{
UGameplayStatics::OpenLevel(World, LevelName);
}
}
}
충돌 볼륨을 만들어서 레벨 변경
90. Saving the Game
플레인 데이터들의 저장
void AMain::SaveGame()
{
UFirstSaveGame* SaveGameInstance = Cast<UFirstSaveGame>(UGameplayStatics::CreateSaveGameObject(UFirstSaveGame::StaticClass()));
SaveGameInstance->CharacterStats.Health = Health;
SaveGameInstance->CharacterStats.MaxHealth = MaxHealth;
UGameplayStatics::SaveGameToSlot(SaveGameInstance, SaveGameInstance->PlayerName, SaveGameInstance->UserIndex);
}
void AMain::LoadGame()
{
UFirstSaveGame* LoadGameInstance = Cast<UFirstSaveGame>(UGameplayStatics::CreateSaveGameObject(UFirstSaveGame::StaticClass()));
LoadGameInstance = Cast<UFirstSaveGame>(UGameplayStatics::LoadGameFromSlot(LoadGameInstance->PlayerName, LoadGameInstance->UserIndex));
Health = LoadGameInstance->CharacterStats.Health;
MaxHealth = LoadGameInstance->CharacterStats.MaxHealth;
}
이렇게쓰는게 맞나싶긴한데 일단은 작동함
91. Saving the Weapon
블루프린트를 이용해서 들고있는 무기를 저장해보자.
UPROPERTY(EditDefaultsOnly, Category = "SaveData")
TMap < FString, TSubclassOf<class AWeapon>> WeaponMap;
아이템 스토리지 클래스를 만들어 키, 섭클래스 쌍의 맵을 만든다.
블루프린트를 만들어 데이터를 저장
if(EquippedWeapon)
{
SaveGameInstance->CharacterStats.WeaponName = EquippedWeapon->Name;
}
저장할 때는 키를 저장
UPROPERTY(EditDefaultsOnly, Category = "SavedData")
TSubclassOf<class AItemStorage> WeaponStorage;
if (WeaponStorage)
{
AItemStorage* Weapons = GetWorld()->SpawnActor<AItemStorage>(WeaponStorage);
if (Weapons)
{
FString WeaponName = LoadGameInstance->CharacterStats.WeaponName;
if (Weapons->WeaponMap.Contains(WeaponName))
{
AWeapon* WeaponToEquip = GetWorld()->SpawnActor<AWeapon>(Weapons->WeaponMap[WeaponName]);
WeaponToEquip->Equip(this);
}
}
}
블루프린트에 저장해둔 TSubclassof로 AWeapon을 생성하면 된다.
92. Pause Menu
HUD를 제작하고 키를 맵핑
93. Pause Menu (continued)
UMG의 애니메이션으로 무브인 무브아웃을 만든다.
94. Pause Menu (continued)
FInputModeGameAndUI InputModeGameAndUI;
SetInputMode(InputModeGameAndUI);
bShowMouseCursor = true;
//
FInputModeGameOnly InputModeGameOnly;
SetInputMode(InputModeGameOnly);
bShowMouseCursor = false;
95. Pause Menu (continued)
96. Pause Menu (continued)
97. Pause Menu (continued)
FString MapName = GetWorld()->GetMapName();
MapName.RemoveFromStart(GetWorld()->StreamingLevelsPrefix);
레벨 이름만 저장하는 방법.
98. Finishing Up
99. Removing All Unused Assets
안쓰는 에셋들 버리고 깔끔하게 새 프로젝트로 이주하는 방법
1. 기존 프로젝트와 똑같은 이름의 C++ 프로젝트를 만든다.
2. Config 파일을 전부 복사한다.
3. Source의 C++파일들을 전부 복사한다.
4. Intermediate 폴더를 삭제한다.
5. Generate Visual Studio Project files.
6. 레벨을 복사한다.
7. 빠진것들을 마저 복사한다.
100. Packaging the Game
Udemy는 이런걸 준다.
이 강좌에 대한 내 평가는 다음과 같다.
'언리얼4 > 온라인 코스' 카테고리의 다른 글
(Udemy) Unreal Engine C++ Developer: Learn C++ and Make Video Games (0) | 2021.03.23 |
---|---|
(Udemy) Unreal Engine Blueprint Game Developer (0) | 2021.03.19 |
(Udemy) Unreal Engine C++ The Ultimate Game Developer Course (1) (0) | 2021.03.07 |
(언리얼 온라인 러닝) 트윈 스틱 슈터 (0) | 2021.03.03 |
(언리얼 온라인 러닝) 언리얼 엔진과의 첫 시간 (0) | 2021.02.16 |