やあ
タイトルの通りだよ。
もっといい方法があれば教えてください。
BPで書いてもいいけどノードをつなぐのが面倒だったので、C++で書いたよ。
概要
キャラクターのCapsuleComponent
のRightVector
をDotProduct
してDegAsin
した結果と、同じくForwardVector
を処理した結果を合わせて、どの向きから攻撃されたかを調べるだけだよ。
実装
hoge.h
// どの方向かを伝えるためのenum UENUM(Blueprintable) enum class EDamageDirection : uint8 { Front = 0, Left = 1, Right = 2, Back = 3, None = 4, }; ENUM_CLASS_FLAGS(EDamageDirection) UCLASS() class AMYPROJECT_API AHoge : ACharacter { GENERATED_BODY() public: UFUNCTION(BlueprintCallable, Category = "Damage") EDamageDirection GetDamageDirection( FHitResult InHitResult ); };
hoge.cpp
EDamageDirection AHoge::GetDamageDirection(FHitResult InHitResult) { FVector RightVector = GetCapsuleComponent()->GetRightVector(); float RightDir = FVector::DotProduct(InHitResult.Normal, RightVector); RightDir = 180 / PI * FMath::Asin(RightDir);; FVector ForwardVector = GetCapsuleComponent()->GetForwardVector(); float ForwardDir = FVector::DotProduct(InHitResult.Normal, ForwardVector); ForwardDir = 180 / PI * FMath::Asin(ForwardDir); //UE_LOG(LogTemp, Log, TEXT("RightDir %.f ForwardDir %.f"), RightDir, ForwardDir); if ( (ForwardDir >= 45 && (RightDir <= 45 && RightDir >= 0)) || (ForwardDir >= 45 && (RightDir >= -45 && RightDir <= 0)) ) { return EDamageDirection::Back; } if ( (ForwardDir <= -45 && (RightDir <= 45 && RightDir >= 0)) || (ForwardDir <= -45 && (RightDir >= -45 && RightDir <= 0)) ) { return EDamageDirection::Front; } if ( ((ForwardDir <= 45 && ForwardDir >= 0) && RightDir >= 45) || ((ForwardDir >= -45 && ForwardDir <= 0) && RightDir >= 45) ) { return EDamageDirection::Left; } if ( ((ForwardDir <= 45 && ForwardDir >= 0) && RightDir <= -45) || ((ForwardDir >= -45 && ForwardDir <= 0) && RightDir <= -45) ) { return EDamageDirection::Right; } return EDamageDirection::None; }
おわり。