UE5--014--DodgeballFunctionLibrary--HealthInterface--HealthComponent--LookAtActorComponent
1. DodgeballFunctionLibrary
1.1 DodgeballFunctionLibrary.h
#pragma once #include "CoreMinimal.h" #include "Kismet/BlueprintFunctionLibrary.h" #include "DodgeballFunctionLibrary.generated.h" /** * */ UCLASS() class C005DODGEBALL_API UDodgeballFunctionLibrary : public UBlueprintFunctionLibrary { GENERATED_BODY() public: static bool CanSeeActor(const UWorld* World, FVector Location, const AActor* TargetActor, TArray<const AActor*> IgnoreActors = TArray<const AActor*>()); };
1.2 DodgeballFunctionLibrary.cpp
#include "DodgeballFunctionLibrary.h" #include "Engine/World.h" #include "DrawDebugHelpers.h" #include "CollisionQueryParams.h" bool UDodgeballFunctionLibrary::CanSeeActor(const UWorld* World, FVector Location, const AActor* TargetActor, TArray<const AActor*> IgnoreActors) { // Store the results of the Line Trace FHitResult Hit; // Where the Line Trace starts and ends FVector Start = Location; FVector End = TargetActor->GetActorLocation(); FCollisionQueryParams QueryParams; // Ignore the actors specified QueryParams.AddIgnoredActors(IgnoreActors); // The trace channel we want to compare against ECollisionChannel Channel = ECollisionChannel::ECC_Visibility; // Execute the Line Trace World->LineTraceSingleByChannel(Hit, Start, End, Channel,QueryParams); // Show the Line Trace inside the game DrawDebugLine(World, Start, End, FColor::Red); // return !Hit.bBlockingHit; }
2. HealthInterface
2.1 HealthInterface.h
#pragma once #include "CoreMinimal.h" #include "UObject/Interface.h" #include "HealthInterface.generated.h" // This class does not need to be modified. UINTERFACE(MinimalAPI) class UHealthInterface : public UInterface { GENERATED_BODY() }; /** * */ class C005DODGEBALL_API IHealthInterface { GENERATED_BODY() // Add interface functions to this class. This is the class that will be inherited to implement this interface. public: UFUNCTION(BlueprintNativeEvent, Category = Health) void OnDeath(); virtual void OnDeath_Implementation() = 0; UFUNCTION(BlueprintNativeEvent, Category = Health) void OnTakeDamage(); virtual void OnTakeDamage_Implementation() = 0; };
2.2 HealthInterface.cpp
#include "HealthInterface.h" // Add default functionality here for any IHealthInterface functions that are not pure virtual.
3. HealthComponent
3.1 HealthComponent.h
#pragma once #include "CoreMinimal.h" #include "Components/ActorComponent.h" #include "HealthComponent.generated.h" UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) class C005DODGEBALL_API UHealthComponent : public UActorComponent { GENERATED_BODY() public: // Sets default values for this component's properties UHealthComponent(); protected: // Called when the game starts virtual void BeginPlay() override; // The Owner's initial and current amount health points UPROPERTY(EditDefaultsOnly, Category = Health) float Health = 100.f; public: // Called every frame virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; // Take health points from its Owner void LoseHealth(float Amount); FORCEINLINE float GetHealthPercent() const { return Health / 100.f; } };
3.2 HealthComponent.cpp
#include "HealthComponent.h" #include "Kismet/KismetSystemLibrary.h" // With this line #include "HealthInterface.h" #include "GameFramework/Actor.h" // Sets default values for this component's properties UHealthComponent::UHealthComponent() { // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features // off to improve performance if you don't need them. PrimaryComponentTick.bCanEverTick = false; // ... } // Called when the game starts void UHealthComponent::BeginPlay() { Super::BeginPlay(); // ... } // Called every frame void UHealthComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); // ... } void UHealthComponent::LoseHealth(float Amount) { Health -= Amount; if (GetOwner()->Implements<UHealthInterface>()) { IHealthInterface::Execute_OnTakeDamage(GetOwner()); } if (Health <= 0.f) { Health = 0.f; if (1 == 0) { UKismetSystemLibrary::QuitGame(this, nullptr, EQuitPreference::Quit, true); } else { if (GetOwner()->Implements<UHealthInterface>()) { IHealthInterface::Execute_OnDeath(GetOwner()); } } } }
4. LookAtActorComponent
4.1 LookAtActorComponent.h
#pragma once #include "CoreMinimal.h" #include "Components/SceneComponent.h" #include "LookAtActorComponent.generated.h" UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) class C005DODGEBALL_API ULookAtActorComponent : public USceneComponent { GENERATED_BODY() public: // Sets default values for this component's properties ULookAtActorComponent(); FORCEINLINE void SetTarget(class AActor* NewTarget) { TargetActor = NewTarget; } FORCEINLINE bool CanSeeTarget() const { return bCanSeeTarget; } protected: // Called when the game starts virtual void BeginPlay() override; class AActor* TargetActor; bool bCanSeeTarget = false; bool LookAtActor(); public: // Called every frame virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; };
4.2 LookAtActorComponent.cpp
#include "LookAtActorComponent.h" #include "GameFramework/Actor.h" #include "Kismet/KismetMathLibrary.h" #include "DodgeballFunctionLibrary.h" // Sets default values for this component's properties ULookAtActorComponent::ULookAtActorComponent() { // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features // off to improve performance if you don't need them. PrimaryComponentTick.bCanEverTick = true; // ... } // Called when the game starts void ULookAtActorComponent::BeginPlay() { Super::BeginPlay(); // ... } // Called every frame void ULookAtActorComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); // ... bCanSeeTarget = LookAtActor(); } bool ULookAtActorComponent::LookAtActor() { if (TargetActor == nullptr) return false; TArray<const AActor*> IgnoreActors = { GetOwner(), TargetActor }; if (UDodgeballFunctionLibrary::CanSeeActor(GetWorld(), GetComponentLocation(), TargetActor, IgnoreActors)) { FVector Start = GetOwner()->GetActorLocation(); FVector End = TargetActor->GetActorLocation(); // Calculate the necessary rotation for the Start point to face the End point FRotator LookAtRotation = UKismetMathLibrary::FindLookAtRotation(Start, End); //Set the enemy’s rotation to that rotation GetOwner()->SetActorRotation(LookAtRotation); return true; } return false; }
                    
                
                
            
        
浙公网安备 33010602011771号