Loading...
Loading...
Unreal Engine patterns, Actor/Component model, Blueprints vs C++, and best practices
npx skill4agent add davincidreams/agent-team-plugins unreal.uproject.Build.cs.upluginSource/Content/Config/DefaultEngine.iniBinaries/MyGame/
Source/
MyGame/
Public/ # Headers (.h)
Player/
Enemies/
UI/
Systems/
Private/ # Implementation (.cpp)
Player/
Enemies/
UI/
Systems/
MyGame.Build.cs
MyGame.h
Content/
Blueprints/
Maps/
Materials/
Textures/
Meshes/
Audio/
UI/
Config/
DefaultEngine.ini
DefaultGame.ini
DefaultInput.ini
Plugins/
MyGame.uproject// Header - Public/Player/MyCharacter.h
UCLASS()
class MYGAME_API AMyCharacter : public ACharacter
{
GENERATED_BODY()
public:
AMyCharacter();
protected:
virtual void BeginPlay() override;
virtual void Tick(float DeltaTime) override;
virtual void SetupPlayerInputComponent(UInputComponent* Input) override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float MaxHealth = 100.f;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
UHealthComponent* HealthComponent;
UFUNCTION(BlueprintCallable, Category = "Combat")
void TakeDamage(float Amount, AActor* DamageCauser);
private:
UPROPERTY()
float CurrentHealth;
};// Implementation - Private/Player/MyCharacter.cpp
AMyCharacter::AMyCharacter()
{
PrimaryActorTick.bCanEverTick = true;
HealthComponent = CreateDefaultSubobject<UHealthComponent>(TEXT("HealthComp"));
}
void AMyCharacter::BeginPlay()
{
Super::BeginPlay();
CurrentHealth = MaxHealth;
}// Editable in editor, readable/writable in Blueprints
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float Speed;
// Only visible in editor, read-only in Blueprints
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
USceneComponent* Root;
// Replicated for multiplayer
UPROPERTY(Replicated)
int32 Score;
// Replicated with notification
UPROPERTY(ReplicatedUsing = OnRep_Health)
float Health;// C++ base with BlueprintNativeEvent
UFUNCTION(BlueprintNativeEvent, Category = "Combat")
void OnDeath();
void OnDeath_Implementation(); // Default C++ behavior, overridable in BP// Ability
UCLASS()
class UGA_FireBall : public UGameplayAbility
{
GENERATED_BODY()
public:
virtual void ActivateAbility(...) override;
virtual void EndAbility(...) override;
virtual bool CanActivateAbility(...) const override;
};
// Gameplay Effect for damage
UCLASS()
class UGE_FireDamage : public UGameplayEffect
{
// Configure in editor: damage value, duration, tags
};// Single-cast delegate
DECLARE_DELEGATE_OneParam(FOnHealthChanged, float);
// Multi-cast delegate (Blueprint compatible)
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnHealthChangedDynamic, float, NewHealth);
// Usage in class
UPROPERTY(BlueprintAssignable)
FOnHealthChangedDynamic OnHealthChanged;
// Broadcast
OnHealthChanged.Broadcast(CurrentHealth);void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInput)
{
auto* EIC = CastChecked<UEnhancedInputComponent>(PlayerInput);
EIC->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyCharacter::Move);
EIC->BindAction(JumpAction, ETriggerEvent::Started, this, &AMyCharacter::StartJump);
}TSoftObjectPtr<UTexture2D>PrimaryActorTick.bCanEverTick = falseGetWorldTimerManager().SetTimer()void Foo(const FString& Name)Cast<>// Server-authoritative function
UFUNCTION(Server, Reliable)
void ServerFireWeapon(FVector Direction);
// Multicast to all clients
UFUNCTION(NetMulticast, Unreliable)
void MulticastPlayFireEffect();
// Client-only
UFUNCTION(Client, Reliable)
void ClientShowDamageNumber(float Amount);
// Replication conditions
void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutProps) const override
{
Super::GetLifetimeReplicatedProps(OutProps);
DOREPLIFETIME_CONDITION(AMyCharacter, Health, COND_OwnerOnly);
}