Add mouse cell selection with camera, controller, game mode

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
yuichipandaandClaude Sonnet 5.5 committed 2026-11-01 18:15:43 +09:00
1 parent ed2b879889
commit 46e5509e3c
9 files changed
+202

No files matched your search

+1
View File
@@ -2,6 +2,7 @@
[/Script/EngineSettings.GameMapsSettings]
GameDefaultMap=/Engine/Maps/Templates/OpenWorld
GlobalDefaultGameMode=/Script/Tactica.TacticaGameMode
[/Script/Engine.RendererSettings]
r.AllowStaticLighting=False
+31
View File
@@ -1,6 +1,7 @@
#include "GridCell.h"
#include "Components/StaticMeshComponent.h"
#include "Engine/StaticMesh.h"
#include "Materials/MaterialInstanceDynamic.h"
#include "UObject/ConstructorHelpers.h"
AGridCell::AGridCell()
@@ -23,4 +24,34 @@ AGridCell::AGridCell()
MeshComponent->SetRelativeScale3D(FVector(0.95f, 0.95f, 0.1f));
// 板の上面がActorの原点の高さに来るよう、厚さの半分(5cm)下げる
MeshComponent->SetRelativeLocation(FVector(0.0f, 0.0f, -5.0f));
// カーソルのレイキャスト(Visibilityチャンネル)に当たるようにする
MeshComponent->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
MeshComponent->SetCollisionResponseToAllChannels(ECR_Ignore);
MeshComponent->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block);
// 標準マテリアルを割り当てる(色パラメータ"Color"を持つ)
static ConstructorHelpers::FObjectFinder<UMaterialInterface> BaseMaterial(
TEXT("/Engine/BasicShapes/BasicShapeMaterial.BasicShapeMaterial"));
if (BaseMaterial.Succeeded())
{
MeshComponent->SetMaterial(0, BaseMaterial.Object);
}
}
void AGridCell::BeginPlay()
{
Super::BeginPlay();
DynamicMaterial = MeshComponent->CreateDynamicMaterialInstance(0);
SetHighlighted(false);
}
void AGridCell::SetHighlighted(bool bHighlighted)
{
if (DynamicMaterial)
{
DynamicMaterial->SetVectorParameterValue(TEXT("Color"),
bHighlighted ? HighlightColor : NormalColor);
}
}
@@ -0,0 +1,15 @@
#include "TacticaCameraPawn.h"
#include "Camera/CameraComponent.h"
ATacticaCameraPawn::ATacticaCameraPawn()
{
PrimaryActorTick.bCanEverTick = false;
Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
SetRootComponent(Camera);
// 3x3グリッド(中心 (100,100))を斜め上から見下ろす位置。
// 配置したPawnのActor位置を変えれば調整できる
Camera->SetRelativeLocation(FVector(-250.0f, 100.0f, 450.0f));
Camera->SetRelativeRotation(FRotator(-60.0f, 0.0f, 0.0f));
}
@@ -0,0 +1,9 @@
#include "TacticaGameMode.h"
#include "TacticaPlayerController.h"
#include "TacticaCameraPawn.h"
ATacticaGameMode::ATacticaGameMode()
{
DefaultPawnClass = ATacticaCameraPawn::StaticClass();
PlayerControllerClass = ATacticaPlayerController::StaticClass();
}
@@ -0,0 +1,62 @@
#include "TacticaPlayerController.h"
#include "GridCell.h"
#include "Components/InputComponent.h"
#include "InputCoreTypes.h"
DEFINE_LOG_CATEGORY_STATIC(LogTacticaInput, Log, All);
ATacticaPlayerController::ATacticaPlayerController()
{
bShowMouseCursor = true;
}
void ATacticaPlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
if (InputComponent)
{
InputComponent->BindKey(EKeys::LeftMouseButton, IE_Pressed, this,
&ATacticaPlayerController::OnClick);
}
}
void ATacticaPlayerController::PlayerTick(float DeltaTime)
{
Super::PlayerTick(DeltaTime);
AGridCell* Cell = GetCellUnderCursor();
if (Cell == HoveredCell)
{
return;
}
if (HoveredCell)
{
HoveredCell->SetHighlighted(false);
}
HoveredCell = Cell;
if (HoveredCell)
{
HoveredCell->SetHighlighted(true);
}
}
AGridCell* ATacticaPlayerController::GetCellUnderCursor() const
{
FHitResult Hit;
if (GetHitResultUnderCursor(ECC_Visibility, false, Hit))
{
return Cast<AGridCell>(Hit.GetActor());
}
return nullptr;
}
void ATacticaPlayerController::OnClick()
{
if (const AGridCell* Cell = GetCellUnderCursor())
{
UE_LOG(LogTacticaInput, Log, TEXT("Cell clicked: (%d, %d)"),
Cell->GridCoord.X, Cell->GridCoord.Y);
}
}
+20
View File
@@ -5,6 +5,7 @@
#include "GridCell.generated.h"
class UStaticMeshComponent;
class UMaterialInstanceDynamic;
UCLASS()
class TACTICA_API AGridCell : public AActor
@@ -29,4 +30,23 @@ public:
// 歩行可能か
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Grid")
bool bIsWalkable = true;
// 通常時の色
UPROPERTY(EditAnywhere, Category = "Grid|Highlight")
FLinearColor NormalColor = FLinearColor(0.15f, 0.15f, 0.15f);
// ハイライト時の色
UPROPERTY(EditAnywhere, Category = "Grid|Highlight")
FLinearColor HighlightColor = FLinearColor(1.0f, 0.8f, 0.1f);
// ハイライトのON/OFF
void SetHighlighted(bool bHighlighted);
protected:
virtual void BeginPlay() override;
private:
// 色変更用のダイナミックマテリアル
UPROPERTY()
TObjectPtr<UMaterialInstanceDynamic> DynamicMaterial;
};
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "TacticaCameraPawn.generated.h"
class UCameraComponent;
// 固定の俯瞰カメラ
UCLASS()
class TACTICA_API ATacticaCameraPawn : public APawn
{
GENERATED_BODY()
public:
ATacticaCameraPawn();
UPROPERTY(VisibleAnywhere, Category = "Camera")
TObjectPtr<UCameraComponent> Camera;
};
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "TacticaGameMode.generated.h"
UCLASS()
class TACTICA_API ATacticaGameMode : public AGameModeBase
{
GENERATED_BODY()
public:
ATacticaGameMode();
};
@@ -0,0 +1,30 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "TacticaPlayerController.generated.h"
class AGridCell;
UCLASS()
class TACTICA_API ATacticaPlayerController : public APlayerController
{
GENERATED_BODY()
public:
ATacticaPlayerController();
protected:
virtual void SetupInputComponent() override;
virtual void PlayerTick(float DeltaTime) override;
private:
// カーソル下のマスを返す(なければnullptr)
AGridCell* GetCellUnderCursor() const;
void OnClick();
// 現在ハイライト中のマス
UPROPERTY()
TObjectPtr<AGridCell> HoveredCell;
};