Unreal Engine C++ The Ultimate Shooter Course (5)

Date:     Updated:

카테고리:

Chapter 12 Download Footsteps Assets

12-230 Download Footsteps Assets

  • finish

12-231 Setup Assets for Footsteps

check

mat

12-232 Define Physical Surface Types

surface

// shooter.h
#define EPS_Metal EPhysicalSurface::SurfaceType1
#define EPS_Stone EPhysicalSurface::SurfaceType2
#define EPS_Tile EPhysicalSurface::SurfaceType3
#define EPS_Grass EPhysicalSurface::SurfaceType4
#define EPS_Water EPhysicalSurface::SurfaceType5

12-233 Creating Physical Materials

phy

metal

stone

move

grass

12-234 Footstep Sync Markers

  • It has bug so in the meantime, we’re going to have to wait and make do with just our trimmed animations
  • If we have an animation notify to play a sound here at jog start, is that going to be played in addition to the animation notify in jog forward That’s an issue
  • We can solve this issue by designating one particular animation to be the leader and one particular animation to be a follower
  • The leader will have its animation notifies, all triggered, whereas all followers will not have their animation notifies triggered if they’re following a leader

12-235 Custom Anim Notify

bp

notify

save

receive

l

node

run

step

  • As we see here, that’s because the forward animation is designated to be the leader and the jog left animation is the follower in relation to the jog forward animation
  • And so that means we won’t get double footstep and notifies played at the same time

12-236 Adding Notifies to Animations

noti

left

12-237 Setting Bone Name for Each Notify

foot

12-238 Playing Sounds with Anim Notify

step

12-239 Line Trace for Physical Surface Type

reconnect

add

drag

12-240 The Grass Surface Type

drop

ran

12-241 Get Surface Type

// Shooter.Builds.cs

//..

// Now that we have PhysicsCore, we will be able to have the physical surface type as a function return type
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG", "PhysicsCore" });

//..

noti

12-242 Implement Footsteps Notify

metal

ran

step

play

return

12-243 Jumping and Landing Sounds

jump

sel

notify

noti

local

buti

branch

un

12-244 Turning Hips While Running

bp

ro

normal

node

ani

forty

time

12-245 Turn Hips While Running Backwards

back

temp

space

set

is

backward

pose

last

shoot


Chapter 13 Multiple Character Meshes

13-246 Retargeting the Animation Blueprint

hu

dup

match

for

mon

13-247 Setting Up TwinBlast Character Blueprint

soc

disgun

re

mesh

monta

world

hand

bp

13-248 Tweaking TwinBlast

key

13-249 Phase

save


Chapter 14 The Enemy Class

14-250 Enemy Assets

test

14-251 The Enemy Class

class

bp

in

14-252 Bullet Hit Interface

inter

class SHOOTER_API IBulletHitInterface
{
	GENERATED_BODY()

	// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:

	// BlueprintNativeEvent에 대해 나중에 좀 알아봐야함
	UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
	void BulletHit(FHitResult HitResult);
};
class SHOOTER_API AEnemy : public ACharacter, public IBulletHitInterface
{
	//..

public:
	// IBulletHitInterface의 BulletHit를 구현한거라고 하는데 이게 말이 되는지 모르겠음
	virtual void BulletHit_Implementation(FHitResult HitResult) override;
}

14-253 Bullet Hit Interface

enemy

void AEnemy::BulletHit_Implementation(FHitResult HitResult)
{
	if (ImpactSound)
	{
		UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation());
	}
	if (ImpactParticles)
	{
		UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ImpactParticles, HitResult.Location, FRotator(0.f), true);
	}
}

14-254 Explosive

actor

new

mesh

14-255 Damage

class SHOOTER_API AEnemy : public ACharacter, public IBulletHitInterface
{
	//..

	// Take damage is a function inherited from the actor class
	virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser) override;
}
void AShooterCharacter::SendBullet()
{
	//..

	AEnemy* HitEnemy = Cast<AEnemy>(BeamHitResult.Actor.Get());
	if (HitEnemy)
	{
		// If that actor implements take damage, then it's take damage function will be called
		UGameplayStatics::ApplyDamage(
			BeamHitResult.Actor.Get(),
			EquippedWeapon->GetHeadShotDamage(),
			GetController(),
			this,
			UDamageType::StaticClass());
	}

	//..
}

14-256 Head Shot Damage

bone

void AShooterCharacter::SendBullet()
{
	//..

	if (BeamHitResult.BoneName.ToString() == HitEnemy->GetHeadBone())
	{
		// Head shot
		UGameplayStatics::ApplyDamage(
			BeamHitResult.Actor.Get(),
			EquippedWeapon->GetHeadShotDamage(),
			GetController(),
			this,
			UDamageType::StaticClass());
	}

	//..
}

14-257 Enemy Health Bar

hud

color

set

enemy

node

bind

nice

14-258 Hide Health Bar

why

14-259 Enemy Death Function

float AEnemy::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
	if (Health - DamageAmount <= 0.f)
	{
		Health = 0.f;
		Die();
	}
	else
	{
		Health -= DamageAmount;
	}

	return DamageAmount;
}

14-260 Enemy Anim Instance

anim

blueprint

one

set

14-261 EnemyHit Montage

mon

add

sec

slot

slotin

14-262 Play Montage Sections

void AEnemy::PlayHitMontage(FName Section, float PlayRate)
{
	UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
	if (AnimInstance)
	{
		AnimInstance->Montage_Play(HitMontage, PlayRate);
		AnimInstance->Montage_JumpToSection(Section, HitMontage);
	}
}

hit

14-263 Hit React Delay

void AEnemy::PlayHitMontage(FName Section, float PlayRate)
{
	if (bCanHitReact)
	{
		UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
		if (AnimInstance)
		{
			AnimInstance->Montage_Play(HitMontage, PlayRate);
			AnimInstance->Montage_JumpToSection(Section, HitMontage);
		}

		bCanHitReact = false;
		const float HitReactTime{ FMath::FRandRange(HitReactTimeMin, HitReactTimeMax) };
		GetWorldTimerManager().SetTimer(
			HitReactTimer,
			this,
			&AEnemy::ResetHitReactTimer,
			HitReactTime);
	}
}

14-264 Show Hit Numbers

bp

char

num

14-265 Store Hit Number Locations

store

14-266 Remove Hit Number

void AEnemy::StoreHitNumber(UUserWidget* HitNumber, FVector Location)
{
	HitNumbers.Add(HitNumber, Location);

	FTimerHandle HitNumberTimer;
	FTimerDelegate HitNumberDelegate;
	HitNumberDelegate.BindUFunction(this, FName("DestroyHitNumber"), HitNumber);
	GetWorld()->GetTimerManager().SetTimer(
		HitNumberTimer,
		HitNumberDelegate,
		HitNumberDestroyTime,
		false);
}
void AEnemy::DestroyHitNumber(UUserWidget* HitNumber)
{
	HitNumbers.Remove(HitNumber);
	HitNumber->RemoveFromParent();
}

14-267 Update Hit Number Location

void AEnemy::UpdateHitNumbers()
{
	for (auto& HitPair : HitNumbers)
	{
		UUserWidget* HitNumber{ HitPair.Key };
		const FVector Location{ HitPair.Value };
		FVector2D ScreenPosition;
		UGameplayStatics::ProjectWorldToScreen(
			GetWorld()->GetFirstPlayerController(),
			Location,
			ScreenPosition);
		HitNumber->SetPositionInViewport(ScreenPosition);
	}
}

14-268 Bind Hit Number Text

bind

promote

set

14-269 Animate Hit Numbers

trans

goodnode

14-270 Head Shots

bind

pro

node

head

14-271 Grux Physics Asset

til

phy

col


맨 위로 이동하기

댓글남기기