Here’s the header…
The declaration is pretty much verbatim from the base class afaik. The thing is, it renders correctly if I add a second one of these to the actor. Or if I copy and paste the original one. So it makes me suspect an issue with deserializing properties somehow. Like it fails to get the property type to draw in the details pane or something.
[FONT=Courier New]// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#pragma once
#include “Perception/AIPerceptionSystem.h”
#include “Perception/AIPerceptionComponent.h”
#include “AITacticalPerceptionComponent.generated.h”
DECLARE_LOG_CATEGORY_EXTERN(LogAITacticalPerception, Warning, All);
USTRUCT()
struct FTacticalActorSenseInfo
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
AActor * threat;
UPROPERTY()
float activation;
};
// wonky bloody macro so we can have a return value delegate method call… ugh!
DECLARE_DELEGATE_RetVal_ThreeParams(float , FActivationScoreDelegate, float , float , FTacticalActorSenseInfo& );
UCLASS(ClassGroup=AI, HideCategories=(Activation, Collision), meta=(BlueprintSpawnableComponent), config=Game)
class TACTICALAI_API UAITacticalPerceptionComponent : public UAIPerceptionComponent
{
GENERATED_UCLASS_BODY()
public:
// how quickly should an ideal sight sense activate the perception threshold (modified by curves)
UPROPERTY(EditDefaultsOnly,BlueprintReadWrite, Category = “AI Tactical Perception”, Config)
float TacticalSenseSightThreatBaseValue = 10.0f;
// how quickly should an ideal hearing sense activate the perception threshold (modified by curves)
UPROPERTY(EditDefaultsOnly,BlueprintReadWrite, Category = "AI Tactical Perception", Config)
float TacticalSenseHeardThreatBaseValue = 10.0f;
// ignore non hostiles?
UPROPERTY(EditDefaultsOnly, Category = "AI Tactical Perception", Config)
bool IgnoreNonCharacterActors = true;
// what is the threshold for actually sensing an enemy?
UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = "AI Tactical Perception", Config)
float TacticalSenseActivationThreshold = 0.5f;
/** How much activation do we have if we spot an actor within our field of view */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sense")
UCurveFloat* PeripheralVisionCurve;
/** Scale activation of spotting based on distance curve */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sense")
UCurveFloat * DistanceVisionCurve;
/** Scale activation of spotting based on movement of threat */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sense")
UCurveFloat * MovementAwarenessCurve;
// visible stuff for debugging?
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "AI Tactical Perception")
float Alertness = 0.6;
virtual void GetHostileActors(TArray<AActor*>& OutActors) const override;
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction * ThisTickFunction) override;
// get a new delegate to bind to for scoring purposes
FActivationScoreDelegate& GetNewActivationScoreDelegate();
// functions used to score activation value for threat..
// score an individual threat for activation
void UpdateThreatActivation(float DeltaTime,FTacticalActorSenseInfo& info);
// perception update handler (from the AIPerceptionComponent broadcast delegate)
UFUNCTION()
void HandlePerceptionUpdate(TArray<AActor *> targets);
// scoring methods (take input score and threat, return changed score)
float ActivationScoreAngle(float currentactivation, float DeltaTime, FTacticalActorSenseInfo& info);
float ActivationScoreDistance(float currentactivation, float DeltaTime, FTacticalActorSenseInfo& info);
void ForgetHostileActor(AActor * act);
#if !UE_BUILD_SHIPPING
void GrabGameplayDebuggerData(TArray<FString>& OnScreenStrings, TArray<FGameplayDebuggerShapeElement>& DebugShapes) const;
#endif // !UE_BUILD_SHIPPING
protected:
// this holds the array of “sensed” actors… i.e. ones we have perceived and need to calculate activation values for
TArray<FTacticalActorSenseInfo> SensedHostileActors;
TArray<FActivationScoreDelegate> ActivationScoringDelegates;
};