Compare commits

..

2 Commits

Author SHA1 Message Date
NisemonoQ
f57f6b8832 Minor - Ajout de la logique de Projectile au PlayerPawn
Le playerPawn possède une fonction qui pourra appeler le script de projectile.
Prochaine étape, complétion du système de Projectile.
2025-10-17 15:27:19 +02:00
NisemonoQ
8733dfd87f Merge branch 'main' into Bullet 2025-10-17 14:02:35 +02:00
16 changed files with 160 additions and 267 deletions

View File

@@ -10,9 +10,9 @@ r.AllowStaticLighting=False
r.GenerateMeshDistanceFields=True r.GenerateMeshDistanceFields=True
r.DynamicGlobalIlluminationMethod=0 r.DynamicGlobalIlluminationMethod=1
r.ReflectionMethod=0 r.ReflectionMethod=1
r.SkinCache.CompileShaders=True r.SkinCache.CompileShaders=True
@@ -27,12 +27,6 @@ r.DefaultFeature.AutoExposure.ExtendDefaultLuminanceRange=True
r.DefaultFeature.LocalExposure.HighlightContrastScale=0.8 r.DefaultFeature.LocalExposure.HighlightContrastScale=0.8
r.DefaultFeature.LocalExposure.ShadowContrastScale=0.8 r.DefaultFeature.LocalExposure.ShadowContrastScale=0.8
r.Lumen.HardwareRayTracing=False
r.Lumen.Reflections.HardwareRayTracing.Translucent.Refraction.EnableForProject=False
r.Mobile.SupportsGen4TAA=False
r.CustomDepthTemporalAAJitter=False
r.AntiAliasingMethod=1
r.DefaultFeature.MotionBlur=False
[/Script/WindowsTargetPlatform.WindowsTargetSettings] [/Script/WindowsTargetPlatform.WindowsTargetSettings]
DefaultGraphicsRHI=DefaultGraphicsRHI_DX12 DefaultGraphicsRHI=DefaultGraphicsRHI_DX12
@@ -100,7 +94,3 @@ ConnectionType=USBOnly
bUseManualIPAddress=False bUseManualIPAddress=False
ManualIPAddress= ManualIPAddress=
[CoreRedirects]
+ClassRedirects=(OldName="/Script/M4_CPP.M4_CentipedeController",NewName="/Script/M4_CPP.M4_CentipedeController")

Binary file not shown.

Binary file not shown.

View File

@@ -10,42 +10,21 @@ AM4_CentipedeBody::AM4_CentipedeBody()
GetStaticMeshComponent()->SetStaticMesh(MeshRef.Object); GetStaticMeshComponent()->SetStaticMesh(MeshRef.Object);
} }
static ConstructorHelpers::FObjectFinder<UMaterialInterface> HeadMatRef(TEXT("/Game/CTP/05_Material/MI_Head.MI_Head"));
if (HeadMatRef.Succeeded())
{
HeadMaterial = HeadMatRef.Object;
}
static ConstructorHelpers::FObjectFinder<UMaterialInterface> BodyMatRef(TEXT("/Game/CTP/05_Material/MI_Body.MI_Body"));
if (BodyMatRef.Succeeded())
{
BodyMaterial = BodyMatRef.Object;
}
GetStaticMeshComponent()->SetRelativeScale3D(FVector(1.f, 0.4f, 0.4f)); GetStaticMeshComponent()->SetRelativeScale3D(FVector(1.f, 0.4f, 0.4f));
GetStaticMeshComponent()->SetMobility(EComponentMobility::Movable);
GetStaticMeshComponent()->SetCollisionObjectType(ECollisionChannel::ECC_WorldDynamic);
GetStaticMeshComponent()->SetGenerateOverlapEvents(true);
GetStaticMeshComponent()->SetCollisionEnabled(ECollisionEnabled::QueryOnly); GetStaticMeshComponent()->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
GetStaticMeshComponent()->SetCollisionProfileName(TEXT("OverlapAll")); GetStaticMeshComponent()->SetGenerateOverlapEvents(true);
GetStaticMeshComponent()->SetMobility(EComponentMobility::Movable);
} }
void AM4_CentipedeBody::SetAsHead(bool bHead) void AM4_CentipedeBody::SetAsHead(bool bHead)
{ {
bIsHead = bHead; bIsHead = bHead;
if (bIsHead)
if (bIsHead) {
{ GetStaticMeshComponent()->SetDefaultCustomPrimitiveDataVector4(0, FVector4(1.0, 0.0, 0.0, 1.0));
if (HeadMaterial) }
{ else
GetStaticMeshComponent()->SetMaterial(0, HeadMaterial); {
} GetStaticMeshComponent()->SetDefaultCustomPrimitiveDataVector4(0, FVector4(0.0, 1.0, 0.0, 1.0));
} }
else }
{
if (BodyMaterial)
{
GetStaticMeshComponent()->SetMaterial(0, BodyMaterial);
}
}
}

View File

@@ -1,110 +1,40 @@
#include "M4_CentipedeController.h" #include "M4_CentipedeController.h"
#include "M4_LOG.h"
#include "M4_Gamemode.h" #include "M4_Gamemode.h"
#include "M4_Mushroom.h"
#include "Kismet/GameplayStatics.h"
UM4_CentipedeController::UM4_CentipedeController() AM4_CentipedeController::AM4_CentipedeController()
{ {
PrimaryActorTick.bCanEverTick = true;
Root = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
RootComponent = Root;
} }
void UM4_CentipedeController::Initialize(FSubsystemCollectionBase& Collection) void AM4_CentipedeController::BeginPlay()
{ {
Super::Initialize(Collection); Super::BeginPlay();
SpawnCentipede();
UE_LOG(M4_CPP, Warning, TEXT("Centipede Controller Initialized")); PreviousPositions.SetNum(BodyCount);
for (int i = 0; i < BodyCount; ++i)
}
void UM4_CentipedeController::Deinitialize()
{
UE_LOG(M4_CPP, Warning, TEXT("Centipede Controller Deinitialized"));
BodySegments.Empty();
PreviousPositions.Empty();
SegmentDirections.Empty();
Super::Deinitialize();
}
void UM4_CentipedeController::StartCentipede(FVector SpawnLocation)
{
if (BodySegments.Num() > 0)
{ {
UE_LOG(M4_CPP, Warning, TEXT("Centipede already spawned")); PreviousPositions[i] = BodySegments[i]->GetActorLocation();
return;
}
for (int32 i = 0; i < BodyCount; ++i)
{
FVector SegmentLocation = SpawnLocation - FVector(0.f, i * CellSize, 0.f);
AM4_CentipedeBody* Body = GetWorld()->SpawnActor<AM4_CentipedeBody>(
AM4_CentipedeBody::StaticClass(),
SegmentLocation,
FRotator::ZeroRotator
);
if (Body)
{
BodySegments.Add(Body);
if (i > 0)
{
Body->PreviousBody = BodySegments[i - 1];
BodySegments[i - 1]->NextBody = Body;
}
Body->SetAsHead(i == 0);
}
} }
SegmentHistory.SetNum(BodyCount);
for (int32 i = 0; i < BodyCount; ++i)
{
if (BodySegments.IsValidIndex(i) && BodySegments[i])
{
FVector InitialPos = BodySegments[i]->GetActorLocation();
int32 InitialHistorySize = SegmentSpacing * (i + 1) + MaxHistorySize;
for (int32 j = 0; j < InitialHistorySize; ++j)
{
SegmentHistory[i].Add(InitialPos);
}
}
}
for (AM4_CentipedeBody* Segment : BodySegments) for (AM4_CentipedeBody* Segment : BodySegments)
{ {
SegmentDirections.Add(Segment, FVector2D(0.f, 1.f)); SegmentDirections.Add(Segment, FVector2D(0.f, 1.f));
} }
UE_LOG(M4_CPP, Warning, TEXT("Centipede spawned with %d segments"), BodySegments.Num());
} }
TStatId UM4_CentipedeController::GetStatId() const void AM4_CentipedeController::SpawnCentipede()
{ {
RETURN_QUICK_DECLARE_CYCLE_STAT(UM4_CentipedeController, STATGROUP_Tickables); FVector SpawnLocation = GetActorLocation();
}
void UM4_CentipedeController::SpawnCentipede()
{
AM4_Gamemode* GM = Cast<AM4_Gamemode>(GetWorld()->GetAuthGameMode());
if (!GM) return;
FVector SpawnLocation = FVector( UE_LOG(LogTemp, Warning, TEXT("Controller spawn location: X=%.2f, Y=%.2f, Z=%.2f"),
GM->MushroomSpawnBounds.Max.X,
0.f,
0.f
);
UE_LOG(M4_CPP, Warning, TEXT("Controller spawn location: X=%.2f, Y=%.2f, Z=%.2f"),
SpawnLocation.X, SpawnLocation.Y, SpawnLocation.Z); SpawnLocation.X, SpawnLocation.Y, SpawnLocation.Z);
if (SpawnLocation.IsZero()) if (SpawnLocation.IsZero())
{ {
UE_LOG(M4_CPP, Error, TEXT("Controller position is zero! Check spawn parameters.")); UE_LOG(LogTemp, Error, TEXT("Controller position is zero! Check spawn parameters."));
return; return;
} }
@@ -133,68 +63,80 @@ void UM4_CentipedeController::SpawnCentipede()
} }
} }
void UM4_CentipedeController::Tick(float DeltaTime) void AM4_CentipedeController::Tick(float DeltaTime)
{ {
Super::Tick(DeltaTime); Super::Tick(DeltaTime);
if (BodySegments.Num() == 0) return; if (BodySegments.Num() == 0) return;
AM4_CentipedeBody* Head = BodySegments[0]; TimeSinceLastMove += DeltaTime;
if (Head && Head->bIsHead)
if (TimeSinceLastMove >= MoveInterval)
{ {
FVector CurrentPos = Head->GetActorLocation(); TimeSinceLastMove = 0.f;
FVector2D SegmentDirection = GetSegmentDirection(Head);
TArray<FVector> TempPositions;
bool bRowChanged = CheckCollision(Head, SegmentDirection); TempPositions.SetNum(BodySegments.Num());
if (bRowChanged) for (int32 i = 0; i < BodySegments.Num(); ++i)
{ {
FVector NewPos = CurrentPos - FVector(0.f, 0.f, CellSize); TempPositions[i] = BodySegments[i]->GetActorLocation();
Head->SetActorLocation(NewPos);
SegmentDirection.Y *= -1.f;
SetSegmentDirection(Head, SegmentDirection);
}
else
{
FVector NewPos = CurrentPos + FVector(0.f, SegmentDirection.Y * CentipedeSpeed * DeltaTime, 0.f);
Head->SetActorLocation(NewPos);
} }
SegmentHistory[0].Add(Head->GetActorLocation()); for (int32 i = 0; i < BodySegments.Num(); ++i)
if (SegmentHistory[0].Num() > MaxHistorySize)
{ {
SegmentHistory[0].RemoveAt(0); AM4_CentipedeBody* Segment = BodySegments[i];
}
}
for (int32 i = 1; i < BodySegments.Num(); ++i)
{
AM4_CentipedeBody* Segment = BodySegments[i];
if (!Segment) continue;
int32 PrevIndex = i - 1;
int32 HistoryLookback = SegmentSpacing;
if (SegmentHistory[PrevIndex].Num() > HistoryLookback)
{
int32 HistoryIndex = SegmentHistory[PrevIndex].Num() - HistoryLookback - 1;
FVector TargetPos = SegmentHistory[PrevIndex][HistoryIndex];
Segment->SetActorLocation(TargetPos); if (!Segment) continue;
SegmentHistory[i].Add(Segment->GetActorLocation()); if (Segment->bIsHead)
if (SegmentHistory[i].Num() > MaxHistorySize)
{ {
SegmentHistory[i].RemoveAt(0); FVector CurrentPos = Segment->GetActorLocation();
FVector2D SegmentDirection = GetSegmentDirection(Segment);
bool bShouldDescend = CheckCollision(Segment, SegmentDirection);
if (bShouldDescend)
{
FVector NewPos = CurrentPos - FVector(0.f, 0.f, CellSize);
Segment->SetActorLocation(NewPos);
SegmentDirection.Y *= -1.f;
SetSegmentDirection(Segment, SegmentDirection);
UE_LOG(LogTemp, Warning, TEXT("Head at index %d descending"), i);
}
else
{
FVector NewPos = CurrentPos + FVector(0.f, SegmentDirection.Y * CellSize, 0.f);
Segment->SetActorLocation(NewPos);
}
}
else
{
if (i > 0)
{
Segment->SetActorLocation(PreviousPositions[i - 1]);
if (BodySegments[i - 1])
{
FVector2D PrevDirection = GetSegmentDirection(BodySegments[i - 1]);
SetSegmentDirection(Segment, PrevDirection);
}
}
} }
} }
}
for (int32 i = 0; i < BodySegments.Num(); ++i)
{
PreviousPositions[i] = BodySegments[i]->GetActorLocation();
}
UpdateHeadStatus(); UpdateHeadStatus();
}
} }
bool UM4_CentipedeController::CheckCollision(AM4_CentipedeBody* Segment, FVector2D Direction) bool AM4_CentipedeController::CheckCollision(AM4_CentipedeBody* Segment, FVector2D Direction)
{ {
if (!Segment) return false; if (!Segment) return false;
@@ -206,58 +148,19 @@ bool UM4_CentipedeController::CheckCollision(AM4_CentipedeBody* Segment, FVector
const float LeftBound = GM->MushroomSpawnBounds.Min.Y; const float LeftBound = GM->MushroomSpawnBounds.Min.Y;
const float RightBound = GM->MushroomSpawnBounds.Max.Y; const float RightBound = GM->MushroomSpawnBounds.Max.Y;
const float MinRows = GM->MushroomSpawnBounds.Min.X;
const float MaxRows = GM->MushroomSpawnBounds.Max.X;
if (NextPos.Y <= LeftBound || NextPos.Y >= RightBound) if (NextPos.Y <= LeftBound || NextPos.Y >= RightBound)
{ {
return true; return true;
} }
if (CurrentPos.Z > MinRows && NextPos.Z <= MinRows)
{
// On inverse la direction de descente pour remonter
FVector2D CurrentDirection = GetSegmentDirection(Segment);
CurrentDirection.Y *= -1.f;
SetSegmentDirection(Segment, CurrentDirection);
return true; // Collision détectée, le centipede descendra à la prochaine itération
}
// Vérification si on atteint la limite haute // TODO: Ajouter vérification collision avec mushroom
if (CurrentPos.Z < MaxRows && NextPos.Z >= MaxRows) // if (IsMushroomAt(NextPos)) return true;
{
// On inverse la direction de montée pour descendre
FVector2D CurrentDirection = GetSegmentDirection(Segment);
CurrentDirection.Y *= -1.f;
SetSegmentDirection(Segment, CurrentDirection);
return true; // Collision détectée, le centipede remontera à la prochaine itération
}
int32 NextGridZ = FMath::RoundToInt(NextPos.Z / CellSize);
int32 NextGridY = FMath::RoundToInt(NextPos.Y / CellSize);
TArray<AActor*> FoundMushrooms;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), AM4_Mushroom::StaticClass(), FoundMushrooms);
for (AActor* Actor : FoundMushrooms)
{
FVector MushroomPos = Actor->GetActorLocation();
// Conversion de la position du mushroom en coordonnées de grille (Z, Y)
int32 MushroomGridZ = FMath::RoundToInt(MushroomPos.Z / CellSize);
int32 MushroomGridY = FMath::RoundToInt(MushroomPos.Y / CellSize);
// Vérification si c'est la même cellule de grille
if (NextGridZ == MushroomGridZ && NextGridY == MushroomGridY)
{
return true;
}
}
return false; return false;
} }
FVector2D UM4_CentipedeController::GetSegmentDirection(AM4_CentipedeBody* Segment) FVector2D AM4_CentipedeController::GetSegmentDirection(AM4_CentipedeBody* Segment)
{ {
if (SegmentDirections.Contains(Segment)) if (SegmentDirections.Contains(Segment))
{ {
@@ -266,7 +169,7 @@ FVector2D UM4_CentipedeController::GetSegmentDirection(AM4_CentipedeBody* Segmen
return FVector2D(0.f, 1.f); return FVector2D(0.f, 1.f);
} }
void UM4_CentipedeController::SetSegmentDirection(AM4_CentipedeBody* Segment, FVector2D Direction) void AM4_CentipedeController::SetSegmentDirection(AM4_CentipedeBody* Segment, FVector2D Direction)
{ {
if (Segment) if (Segment)
{ {
@@ -274,7 +177,7 @@ void UM4_CentipedeController::SetSegmentDirection(AM4_CentipedeBody* Segment, FV
} }
} }
void UM4_CentipedeController::UpdateHeadStatus() void AM4_CentipedeController::UpdateHeadStatus()
{ {
for (int32 i = 0; i < BodySegments.Num(); ++i) for (int32 i = 0; i < BodySegments.Num(); ++i)
{ {
@@ -290,29 +193,37 @@ void UM4_CentipedeController::UpdateHeadStatus()
} }
} }
void UM4_CentipedeController::OnSegmentDestroyed(AM4_CentipedeBody* DestroyedSegment) void AM4_CentipedeController::OnSegmentDestroyed(AM4_CentipedeBody* DestroyedSegment)
{ {
if (!DestroyedSegment) return; if (!DestroyedSegment) return;
int32 SegmentIndex = BodySegments.Find(DestroyedSegment); int32 SegmentIndex = BodySegments.Find(DestroyedSegment);
if (SegmentIndex == INDEX_NONE) return; if (SegmentIndex == INDEX_NONE) return;
UE_LOG(LogTemp, Warning, TEXT("Segment %d destroyed"), SegmentIndex);
if (SegmentIndex + 1 < BodySegments.Num()) if (SegmentIndex + 1 < BodySegments.Num())
{ {
AM4_CentipedeBody* NewHead = BodySegments[SegmentIndex + 1]; AM4_CentipedeBody* NewHead = BodySegments[SegmentIndex + 1];
if (NewHead) if (NewHead)
{ {
NewHead->SetAsHead(true); NewHead->SetAsHead(true);
NewHead->PreviousBody = nullptr; NewHead->PreviousBody = nullptr;
UE_LOG(LogTemp, Warning, TEXT("New head created at index %d"), SegmentIndex + 1);
} }
} }
if (SegmentIndex > 0 && BodySegments[SegmentIndex - 1]) if (SegmentIndex > 0 && BodySegments[SegmentIndex - 1])
{ {
BodySegments[SegmentIndex - 1]->NextBody = nullptr; BodySegments[SegmentIndex - 1]->NextBody = nullptr;
} }
BodySegments.RemoveAt(SegmentIndex); BodySegments.RemoveAt(SegmentIndex);
SegmentHistory.RemoveAt(SegmentIndex); PreviousPositions.RemoveAt(SegmentIndex);
SegmentDirections.Remove(DestroyedSegment); SegmentDirections.Remove(DestroyedSegment);
// TODO: Spawner un mushroom à la position du segment détruit
// SpawnMushroomAt(DestroyedSegment->GetActorLocation());
} }

View File

@@ -85,7 +85,8 @@ void AM4_Gamemode::BeginPlay()
); );
} }
} }
// Spawn centipede controller
PRINT_SCREEN(TEXT("Spawning Centipede Controller"), FColor::Green); PRINT_SCREEN(TEXT("Spawning Centipede Controller"), FColor::Green);
FVector CentipedeSpawnLocation = FVector( FVector CentipedeSpawnLocation = FVector(
@@ -97,13 +98,16 @@ void AM4_Gamemode::BeginPlay()
// PRINT SCREEN Max.X value // PRINT SCREEN Max.X value
PRINT_SCREEN(*FString::Printf(TEXT("Mushroom Spawn Bounds Max.X: %.2f"), MushroomSpawnBounds.Max.X), FColor::Green); PRINT_SCREEN(*FString::Printf(TEXT("Mushroom Spawn Bounds Max.X: %.2f"), MushroomSpawnBounds.Max.X), FColor::Green);
UM4_CentipedeController* Controller = GetWorld()->GetSubsystem<UM4_CentipedeController>(); CentipedeController = GetWorld()->SpawnActor<AM4_CentipedeController>(
if (Controller) AM4_CentipedeController::StaticClass(),
CentipedeSpawnLocation,
FRotator::ZeroRotator
);
if (CentipedeController)
{ {
Controller->BodyCount = CentipedeBodyCount; CentipedeController->BodyCount = CentipedeBodyCount;
Controller->CellSize = CellSize; CentipedeController->CellSize = CellSize;
Controller->StartCentipede(CentipedeSpawnLocation);
} }
} }

View File

@@ -31,8 +31,9 @@ AM4_Mushroom::AM4_Mushroom()
const FVector2D MushroomScale = FVector2D(0.3f, 0.25f); const FVector2D MushroomScale = FVector2D(0.3f, 0.25f);
GetStaticMeshComponent()->SetRelativeScale3D(FVector(1.f, 0.45f, 0.20f)); GetStaticMeshComponent()->SetRelativeScale3D(FVector(1.f, 0.45f, 0.20f));
// Set collision profile to overlap all // Custom preset for more advanced collision configuration
GetStaticMeshComponent()->SetCollisionProfileName(TEXT("OverlapAll")); GetStaticMeshComponent()->SetCollisionProfileName(UCollisionProfile::CustomCollisionProfileName);
GetStaticMeshComponent()->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap);
} }

View File

@@ -32,6 +32,12 @@ AM4_PlayerPawn::AM4_PlayerPawn()
{ {
MoveAction = MoveActionRef.Object; MoveAction = MoveActionRef.Object;
} }
static ConstructorHelpers::FObjectFinder<UInputAction> ShootActionRef(TEXT("/Game/CTP/03_Input/IA_Shoot.IA_Shoot"));
if (ShootActionRef.Succeeded())
{
ShootAction = ShootActionRef.Object;
}
} }
void AM4_PlayerPawn::BeginPlay() void AM4_PlayerPawn::BeginPlay()
@@ -64,10 +70,23 @@ void AM4_PlayerPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputCompo
{ {
Input->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AM4_PlayerPawn::Move); Input->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AM4_PlayerPawn::Move);
} }
if (ShootAction)
{
Input->BindAction(ShootAction, ETriggerEvent::Triggered, this, &AM4_PlayerPawn::Shoot);
}
} }
} }
void AM4_PlayerPawn::Move(const FInputActionInstance& Instance) void AM4_PlayerPawn::Move(const FInputActionInstance& Instance)
{ {
LastMoveValue = Instance.GetValue().Get<FVector2D>().GetSafeNormal(); LastMoveValue = Instance.GetValue().Get<FVector2D>().GetSafeNormal();
} }
void AM4_PlayerPawn::Shoot(const FInputActionInstance& Inst)
{
if (Inst.GetValue().Get<bool>() == true)
{
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Red, TEXT("Input Space Pressed"));
}
};

View File

@@ -11,7 +11,7 @@ AM4_Projectile::AM4_Projectile()
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComp")); MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComp"));
MeshComp-> SetRelativeScale3D(FVector(1.f, .1f,.1f)); MeshComp-> SetRelativeScale3D(FVector(1.f, .1f,.1f));
MeshComp->BodyInstance.SetCollisionProfileName(TEXT("Projectile")); MeshComp->BodyInstance.SetCollisionProfileName(TEXT("Projectile"));
MeshComp->OnComponentHit.AddDynamic(this, &AM4_Projectile::OnHit); MeshComp->OnComponentHit.AddDynamic(this, &AM4_Projectile::OnHit);
} }
void AM4_Projectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector Impulse, const FHitResult& Hit) void AM4_Projectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector Impulse, const FHitResult& Hit)

View File

@@ -22,10 +22,4 @@ public:
bool bIsHead = false; bool bIsHead = false;
void SetAsHead(bool bHead); void SetAsHead(bool bHead);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Materials")
UMaterialInterface* HeadMaterial;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Materials")
UMaterialInterface* BodyMaterial;
}; };

View File

@@ -1,60 +1,50 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "M4_CentipedeBody.h" #include "M4_CentipedeBody.h"
#include "Subsystems/WorldSubsystem.h"
#include "M4_CentipedeController.generated.h" #include "M4_CentipedeController.generated.h"
UCLASS() UCLASS()
class M4_CPP_API UM4_CentipedeController : public UTickableWorldSubsystem class M4_CPP_API AM4_CentipedeController : public AActor
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
UM4_CentipedeController(); AM4_CentipedeController();
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual void Deinitialize() override;
void StartCentipede(FVector SpawnLocation);
virtual void BeginPlay() override;
virtual void Tick(float DeltaTime) override; virtual void Tick(float DeltaTime) override;
virtual TStatId GetStatId() const override;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Centipede") UPROPERTY(EditAnywhere)
int32 BodyCount = 10; int32 BodyCount = 10;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Centipede") UPROPERTY(EditAnywhere)
float CellSize = 50.f; float CellSize = 50.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Centipede") UPROPERTY(EditAnywhere)
float MoveInterval = 0.1f; float MoveInterval = 0.1f;
UFUNCTION(BlueprintCallable, Category = "Centipede")
void OnSegmentDestroyed(AM4_CentipedeBody* DestroyedSegment); void OnSegmentDestroyed(AM4_CentipedeBody* DestroyedSegment);
private: private:
UPROPERTY() UPROPERTY()
TArray<AM4_CentipedeBody*> BodySegments; TArray<AM4_CentipedeBody*> BodySegments;
TArray<TArray<FVector>> SegmentHistory; // Historique pour chaque segment
int32 MaxHistorySize = 200; UPROPERTY()
USceneComponent* Root;
UPROPERTY(EditAnywhere, Category = "Centipede")
int32 SegmentSpacing = 15; // Distance en nombre de frames entre segments
float TimeSinceLastMove = 0.f; float TimeSinceLastMove = 0.f;
float CentipedeSpeed = 400.f;
bool bFirstTick = true;
TArray<FVector> PreviousPositions; TArray<FVector> PreviousPositions;
TMap<AM4_CentipedeBody*, FVector2D> SegmentDirections; TMap<AM4_CentipedeBody*, FVector2D> SegmentDirections;
void SpawnCentipede(); void SpawnCentipede();
void UpdateHeadStatus(); void UpdateHeadStatus();
bool CheckCollision(AM4_CentipedeBody* Segment, FVector2D Direction); bool CheckCollision(AM4_CentipedeBody* Segment, FVector2D Direction);
FVector2D GetSegmentDirection(AM4_CentipedeBody* Segment); FVector2D GetSegmentDirection(AM4_CentipedeBody* Segment);
void SetSegmentDirection(AM4_CentipedeBody* Segment, FVector2D Direction); void SetSegmentDirection(AM4_CentipedeBody* Segment, FVector2D Direction);
}; };

View File

@@ -67,7 +67,7 @@ private:
int32 CentipedeBodyCount = 10; int32 CentipedeBodyCount = 10;
UPROPERTY() UPROPERTY()
TObjectPtr<UM4_CentipedeController> CentipedeController; TObjectPtr<AM4_CentipedeController> CentipedeController;
int Score = 0; int Score = 0;
int Lives = 3; int Lives = 3;

View File

@@ -18,6 +18,7 @@ public:
virtual void Tick(float DeltaTime) override; virtual void Tick(float DeltaTime) override;
virtual void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override; virtual void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override;
void Move(const FInputActionInstance& Instance); void Move(const FInputActionInstance& Instance);
void Shoot(const FInputActionInstance& Inst);
protected: protected:
@@ -27,6 +28,10 @@ protected:
UPROPERTY() UPROPERTY()
UInputAction* MoveAction; UInputAction* MoveAction;
UPROPERTY()
UInputAction* ShootAction;
//bool HasShot = false;
float MoveSpeed = 500.f; float MoveSpeed = 500.f;
FVector2D MeshScale = FVector2D(0.6f, 0.5f); FVector2D MeshScale = FVector2D(0.6f, 0.5f);
FVector2D LastMoveValue = FVector2D::ZeroVector; FVector2D LastMoveValue = FVector2D::ZeroVector;