3월 1주차 숙제 - Occlusion

Overcle·2023년 3월 5일
0

숙제

목록 보기
1/1

내용
스킬키 만들어서 해당 스킬 사용하면 주변 몬스터 탐색 후 Occlusion, 4초 후 해제.

결과


알고리즘


스킬 발동 시. 몬스터만 충돌되는 "Player Attack" Trace Channel을 이용하여
OverlapMultiByChannel으로 범위안에있는 충돌체 저장 후. 그 안에서 또
Monster만 별도 변수에 저장과 동시에 탐지된 몬스터 Occlusion 활성화.

GetWorldTimerManager().SetTimer() 함수를 이용해 4초뒤
Monster만 따로 저장된 변수를 이용하여 Occlusion 해제.

코드


PlayerCharacter.cpp

KnightCharacter.h


KnightCharacter.cpp

AKnightCharacter::AKnightCharacter()
{
	//배열 초기화
	ResultArray.Init(FOverlapResult(),0);
	ResultArray2.Init(FOverlapResult(), 0);
}
void AKnightCharacter::BeginPlay()
{
	Super::BeginPlay();
	//탐지 스킬 관련정보 저장 및 배열 추가.
	SkillInfo.SlotNumber = 1;
	SkillInfo.SkillNumber = 1;
	SkillInfo.Damage = 0;
	SkillInfo.SkillActor = nullptr;
	SkillInfo.SkillEtc = 10000;
	
	mSkillInfoArray.Add(SkillInfo);
 }
void AKnightCharacter::Skill2()
{
	//SkillNumber 못찾을시 안전트리거용
	int32 SkillNumber = -1;

	//해당 스킬슬롯에 있는 스킬 넘버 불러오기
	int32 Count = mSkillInfoArray.Num();
	for (int32 i = 0; i < Count; ++i)
	{
		if (mSkillInfoArray[i].SlotNumber == 1)
		{
			SkillNumber = mSkillInfoArray[i].SkillNumber;
			break;
		}
	}

	//스킬넘버가 없으면 종료
	if (SkillNumber == -1)
		return;

	//해당 스킬넘버 Animation 실행.
	mAnimInst->UseSkill(SkillNumber);
}
void AKnightCharacter::UseSkill(int32 SkillNumber)
{
	int32 Count = mSkillInfoArray.Num();

	//탐색 스킬 사용시.
	if (SkillNumber == 1)
	{
		PrintViewport(1.f, FColor::Red, TEXT("Skill 2 Enable"));

		//자신을 제외하기 위한 파라미터 설정
		FCollisionQueryParams param(NAME_None, false, this);
		float skillEtc = NULL;

		//탐색 스킬 범위 값 불러오기.
		for (int32 i = 0; i < Count; ++i)
		{
			if (mSkillInfoArray[i].SkillNumber == 1)
				skillEtc = mSkillInfoArray[i].SkillEtc;
		}

		//탐색 범위 안에 Overlap된 몬스터 정보 저장.

		//탐색 범위 및 Trace채널 설정
		bool CollisionEnable = GetWorld()->OverlapMultiByChannel(ResultArray, GetActorLocation(), FQuat::Identity, ECollisionChannel::ECC_GameTraceChannel3,
			FCollisionShape::MakeSphere(skillEtc), param);

		//직관적으로 보기위해 Draw Debug 설정
#if ENABLE_DRAW_DEBUG
		FColor DrawColor = CollisionEnable ? FColor::Red : FColor::Green;

		DrawDebugSphere(GetWorld(), GetActorLocation(), skillEtc, 20, DrawColor, false, 0.3f);
#endif	

		if (CollisionEnable)
		{
			Count = ResultArray.Num();
			AMonster* Monster = nullptr;
			for (int32 i = 0; i < Count; ++i)
			{
				Monster = Cast<AMonster>(ResultArray[i].GetActor());
				if (IsValid(Monster))
				{
					ResultArray2.Add(ResultArray[i]);
					Monster->OnRender(true, 26);
				}
			}

			ResultArray.Init(FOverlapResult(), 0);
		}


		FTimerHandle TimerHandle;
		//FTimerDelegate SkillTimer = FTimerDelegate::CreateStatic(this, &AKnightCharacter::Skill2End,void);
		GetWorldTimerManager().SetTimer(TimerHandle, this, &AKnightCharacter::Skill2End, 4.f, false);


//스킬 1번 사용시. 2번은 엑터를 사용안하기에 별도 코드로 구현
	for (int32 i = 0; i < Count; ++i)
	{
		if (mSkillInfoArray[i].SkillNumber == SkillNumber)
		{
			if (SkillNumber == 1)
				break;

			FActorSpawnParameters SpawnParam;
			SpawnParam.Template = mSkillInfoArray[i].SkillActor;
			SpawnParam.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;


			ASkillProjectile* Skill =
				GetWorld()->SpawnActor<ASkillProjectile>(GetActorLocation()  + GetActorForwardVector() * 100.f,
					GetActorRotation(), SpawnParam);

			break;
		}
	}
		
	}
void AKnightCharacter::Skill2End()
{
	if (ResultArray2.Num() != 0)
	{
		int32 Count = ResultArray2.Num();
		AMonster* Monster = nullptr;
		for (int32 i = 0; i < Count; ++i)
		{
			Monster = Cast<AMonster>(ResultArray2[i].GetActor());

			if (IsValid(Monster))
			{
				Monster->OnRender(false);
			}
		}

		ResultArray2.Init(FOverlapResult(), 0);
	}
}

Monster.cpp, Monster.h

[Monster.h]

public:
	void OnRender(bool On,int32 Color = 16);
[Monster.cpp]

void AMonster::OnRender(bool On, int32 Color)
{
	GetMesh()->SetRenderCustomDepth(On);
	GetMesh()->SetCustomDepthStencilValue(Color);
}
profile
게임 프로그래머 지망생의 발자취

0개의 댓글