23.05.22 ~ 2023.05.28 개발일지
저번주 내적을 하는 과정에서 계산을 명확하게 하지 않은 부분들이 다수 존재했다
이번주에 철저하게 값을 로깅하며 수정하는 작업을 거쳤다
수정 및 추가된 부분은 다음과 같다
IFCharacter.cpp
void AIFCharacter::WeakAttack()
{
if (::IsValid(Target))
{
// check if enemy is in character's sight (DotProduct on chracter's forward vector and character to enemy vector)
float DotProduct = FVector::DotProduct(GetActorForwardVector(), (Target->GetActorLocation() - GetActorLocation()).GetSafeNormal());
if (DotProduct > 0.4)
{
...
}
}
AnimInstance->PlayWeakAttackMontage();
}
...
void AIFCharacter::Execute()
{
if (::IsValid(Target))
{
// check if character and enemy are facing(DotProduct on both character's forward vector)
float DotProduct = FVector::DotProduct(GetActorForwardVector(), Target->GetActorForwardVector());
// if character and enemy are facing
if (DotProduct < 0)
{
...
}
}
}
IFEnemyAnimInstance.cpp
void UIFEnemyAnimInstance::React(AActor* Target, AActor* Causer)
{
// check if character and enemy are facing(DotProduct on both character's forward vector)
float DotProduct = FVector::DotProduct(Causer->GetActorForwardVector(), Target->GetActorForwardVector());
FRotator CurrentRotation = Target->GetActorRotation();
if (DotProduct < 0)
{
Target->SetActorRotation(FRotator(CurrentRotation.Pitch, Causer->GetActorRotation().Yaw + 180, CurrentRotation.Roll));
Montage_Play(ReactFrontMontage);
}
else
{
Target->SetActorRotation(FRotator(CurrentRotation.Pitch, Causer->GetActorRotation().Yaw, CurrentRotation.Roll));
Montage_Play(ReactBackMontage);
}
}
Normalize 를 하지 않거나, Forward Vector가 아닌 일반 Vector를 받아오는 등에서 오는 문제점들을 개선하였다
코드에서 사이즈를 조절하던 것을 Public 변수로 두어 몽타주 창에서 수정 가능하도록 두었다
Enhanced Input의 Trigger에는 어떤 키를 누르고 있다면 실행이 되지 않도록 하는 기능은 없다
그래서 Trigger를 추가로 만들어주었다
InputTriggerBlock.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "InputTriggers.h"
#include "InputTriggerBlock.generated.h"
/**
*
*/
UCLASS(NotBlueprintable, meta = (DisplayName = "Block", NotInputConfigurable = "true"))
class INFINITEFIGHTER_API UInputTriggerBlock : public UInputTrigger
{
GENERATED_BODY()
public:
virtual ETriggerType GetTriggerType_Implementation() const override { return ETriggerType::Blocker; }
virtual ETriggerState UpdateState_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue ModifiedValue, float DeltaTime) override;
// Actions that will cancel the combo if it is triggered
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Trigger Settings", meta = (DisplayThumbnail = "false"))
TObjectPtr<const UInputAction> BlockAction = nullptr;
};
GetTriggerType
을 사용해 트리거 타입을 Blocker로 두었다 (실행할 것이 아닌, 실행을 막아줄 것이기 때문)
BlockAction
을 두고 현재 입력 받는 액션이 BlockAction
이라면 실행하도록 한다
InputTriggerBlock.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Game/InputTriggerBlock.h"
#include "InputAction.h"
#include "EnhancedPlayerInput.h"
ETriggerState UInputTriggerBlock::UpdateState_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue ModifiedValue, float DeltaTime)
{
const FInputActionValue ActionValue = PlayerInput->GetActionValue(BlockAction);
return IsActuated(ActionValue) ? ETriggerState::Triggered : ETriggerState::None;
}
UpdateState
에서는 BlockAction의 Value값을 받아 값에 따라 트리거할지, 무시할지를 결정한다
이때 값이 있다면 Triggered
가 되는데, Block이 트리거 되는 것이기 때문에 이렇게 설정해주어야 제대로 원하는대로 설정이 된다
추가한 InputTriggerBlock은 Attack
에 추가해서 Aim
중이라면 나가지 않도록 설정했다