I have created three scripts. One is An Actor that is to be spawned. 2nd Script Spawns Instance of those actors to form a grid. Third script spawns an single instance of the actor. I wish that the actor spawned by the 3rd script can generate overlap events for the other actors spawned by the 2nd script. How do i do it. I don’t know what i am doing wrong.
Here are my scripts
HexGridMesh.cpp(Mesh to be SPAWNED)
// Fill out your copyright notice in the Description page of Project Settings.
#include "HexGridMesh.h"
#include "Components/StaticMeshComponent.h"
#include "Engine/Classes/Materials/MaterialInstanceDynamic.h"
// Sets default values
AHexGridMesh::AHexGridMesh()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
TileValue = 0;
HexTileMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("HexTileMesh"));
RootComponent = HexTileMesh;
ColorParamName = "Color";
NumberParamName = "Number";
CanMoveMesh = false;
HexTileMesh->OnComponentBeginOverlap.AddDynamic(this, &AHexGridMesh::OnOverlapBegin);
//HexTileMesh->OnComponentEndOverlap.AddDynamic(this, &AHexGridMesh::OnOverlapEnd);
}
// Called when the game starts or when spawned
void AHexGridMesh::BeginPlay()
{
Super::BeginPlay();
//Creating a dynamic material with material index 0
HexDynamicMaterial = HexTileMesh->CreateDynamicMaterialInstance(0);
}
// Called every frame
void AHexGridMesh::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
int AHexGridMesh::GetValue()
{
return TileValue;
}
void AHexGridMesh::SetValue(int Gvalue)
{
TileValue = Gvalue;
}
void AHexGridMesh::SettingMaterials()
{
//Checking if the dynamic material exists
if (HexDynamicMaterial && (AlphaArray.Num() > 0 ) && (AlphaArray.Num() < 5))
{
//Assigning the alpha based on tile value
HexDynamicMaterial->SetTextureParameterValue(NumberParamName, AlphaArray[TileValue]);
//Assigning RGB Based on tile value
switch (TileValue)
{
case 1: HexDynamicMaterial->SetVectorParameterValue(ColorParamName, FLinearColor(1, 0, 0, 1));
break;
case 2: HexDynamicMaterial->SetVectorParameterValue(ColorParamName, FLinearColor(0, 1, 0, 1));
break;
case 3: HexDynamicMaterial->SetVectorParameterValue(ColorParamName, FLinearColor(0, 0, 1, 1));
break;
default : HexDynamicMaterial->SetVectorParameterValue(ColorParamName, FLinearColor(0.5, 0.5, 0.5, 1));
}
}
}
void AHexGridMesh::UnlockMesh()
{
CanMoveMesh = true;
}
bool AHexGridMesh::LockMesh()
{
CanMoveMesh = false;
//Returns true value if successfully locked the mesh onto hexgrid
return true;
}
bool AHexGridMesh::GetMeshStatus()
{
return CanMoveMesh;
}
void AHexGridMesh::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
// Other Actor is the actor that triggered the event. Check that is not ourself.
if ((OtherActor != nullptr) && (OtherActor != this) && (OtherComp != nullptr))
{
UE_LOG(LogTemp, Warning, TEXT("Overlapping actor is %s"), *OtherActor->GetName());
}
}
HexGrid.cpp(Created a grid/pattern using actors instance)
// Fill out your copyright notice in the Description page of Project Settings.
#include "HexGrid.h"
#include "HexGridMesh.h"
#include "Engine/World.h"
// Sets default values
AHexGrid::AHexGrid()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
xGridsize = 5;
yGridsize = 5;
xOffset = 15.25;
yOffset = 8.65;
yDisplace = 17.446;
CalcYPos = 0;
}
// Called when the game starts or when spawned
void AHexGrid::BeginPlay()
{
Super::BeginPlay();
SpawnGrid();
}
// Called every frame
void AHexGrid::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AHexGrid::SpawnGrid()
{
int i = 0;
int j = 0;
for (i = 0; i < xGridsize; i++)
{
for (j = 0; j < yGridsize; j++)
{
if (HexagonMesh != NULL)
{
if (GetWorld())
{
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
SpawnParams.Instigator = Instigator;
if (i % 2 == 0)
{
CalcYPos = (yDisplace*j);
}
else
{
CalcYPos = (yDisplace*j) + yOffset;
}
SpawnedItemsArray[i][j] = GetWorld()->SpawnActor<AHexGridMesh>(HexagonMesh, FVector(xOffset * i, CalcYPos, 0), FRotator(0, 0, 0), SpawnParams);
SpawnedItemsArray[i][j]->AttachToActor(this, FAttachmentTransformRules::KeepWorldTransform);
}
}
}
}
}
HexSpawner.cpp(Creates an Single Instance of the HEX MESH to be interacted by the player)
// Fill out your copyright notice in the Description page of Project Settings.
#include "HexSpawner.h"
#include "Components/BoxComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Engine/World.h"
#include "HexGridMesh.h"
// Sets default values
AHexSpawner::AHexSpawner()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
HexSpawnBox = CreateDefaultSubobject<UBoxComponent>(TEXT("HexSpawnBox"));
RootComponent = HexSpawnBox;
}
// Called when the game starts or when spawned
void AHexSpawner::BeginPlay()
{
Super::BeginPlay();
//Spawning the first hex
SpawnHexagonMesh();
}
void AHexSpawner::SpawnHexagonMesh()
{
if (HexagonMesh != NULL)
{
if (GetWorld())
{
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
SpawnParams.Instigator = Instigator;
MySpawnedHexMesh = GetWorld()->SpawnActor<AHexGridMesh>(HexagonMesh, HexSpawnBox->GetComponentLocation(), FRotator(0, 0, 0), SpawnParams);
MySpawnedHexMesh->SetValue(FMath::RandRange(1,3));
MySpawnedHexMesh->SettingMaterials();
MySpawnedHexMesh->UnlockMesh();
}
}
}
MyPawn.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyPawn.h"
#include "Camera/CameraComponent.h"
#include "Components/InputComponent.h"
#include "GameFramework/PlayerController.h"
#include "HexGridMesh.h"
#include "HexSpawner.h"
#include "Engine/World.h"
#include "Engine/Public/EngineUtils.h"
// Sets default values
AMyPawn::AMyPawn()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
OrthoCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("OrthoCamera")); //Assigning the camera
OrthoCameraComponent->SetupAttachment(RootComponent);
OrthoCameraComponent->RelativeLocation = FVector(15.0, 30.0f, 150.0f); // Position the camera
OrthoCameraComponent->RelativeRotation = FRotator(-90.0, 0.0, 0);
OrthoCameraComponent->ProjectionMode = ECameraProjectionMode::Orthographic;
OrthoCameraComponent->OrthoWidth = 384;
PController = NULL;
SelectedHexMesh = NULL;
WorldDirection = FVector(0, 0, 0);
WorldDirection = FVector(0, 0, 0);
CanHoldHex = true;
CurrentHexSpawner = NULL;
IsReadyToSpawn = false;
}
// Called when the game starts or when spawned
void AMyPawn::BeginPlay()
{
Super::BeginPlay();
PController = Cast<APlayerController>(GetController());
PController->bShowMouseCursor = true;
PController->bEnableClickEvents = true;
if (GetWorld())
{
for (TActorIterator<AActor> MyItr(GetWorld()); MyItr; ++MyItr)
{
CurrentHexSpawner = Cast<AHexSpawner>(*MyItr);
if (CurrentHexSpawner)
{
break;
}
}
}
}
// Called every frame
void AMyPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//Updating the hexmesh location according to the mouse position if its movable
if (CanHoldHex && SelectedHexMesh != NULL)
{
PController->DeprojectMousePositionToWorld(WorldLocation, WorldDirection);
SelectedHexMesh->SetActorLocation(FVector(WorldLocation.X, WorldLocation.Y, 1));
}
}
// Called to bind functionality to input
void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
//Binding Firing events
PlayerInputComponent->BindAction("MHold", IE_Pressed, this, &AMyPawn::HoldHex);
PlayerInputComponent->BindAction("MHold", IE_Released, this, &AMyPawn::ReleaseHex);
}
void AMyPawn::HoldHex()
{
//Checking what was hit by the mouse cursor and then getting that actor's instance details
FHitResult HitResult;
PController->GetHitResultUnderCursor(ECollisionChannel::ECC_WorldStatic, false, HitResult);
if (HitResult.bBlockingHit)
{
if (HitResult.GetActor()->GetClass()->IsChildOf(AHexGridMesh::StaticClass()))
{
SelectedHexMesh = Cast<AHexGridMesh>(HitResult.GetActor());
if (SelectedHexMesh->GetMeshStatus())
{
CanHoldHex = true;
}
}
}
}
void AMyPawn::ReleaseHex()
{
if (SelectedHexMesh == NULL)
{
return;
}
//Removing the property to move the mesh
CanHoldHex = false;
//Locking the mesh's movement
IsReadyToSpawn = SelectedHexMesh->LockMesh();
if (IsReadyToSpawn && CurrentHexSpawner)
{
CurrentHexSpawner->SpawnHexagonMesh();
}
//Removing the mesh instance details
SelectedHexMesh = NULL;
}