Sliding Blocks Won't Slide

Iberlos
Tue, 19 Mar 2019 04:23:26 +0000
World Creation

Hello, my name is Luis,
I have been trying to make a Tetris/CandyCrush like mechanic for a small game where players shoot blocks to acquire points. Basically there is a wall of blocks and if you shoot a block it will destroy any neighbors of the same color in a cascade effect awarding more points. The idea is for the blocks on top of it to slide down the Z axis when blocks under it are destroyed. But they sometimes just float there as long as there is contact with any other blocks. I tried overriding the physics material and setting the friction to zero but that only seems to affect the player, not the other actors in the scene.
The only solution I can think of right now is giving a small space between blocks, but i would like to avoid that.

Here are some screenshots and the c++ class code to demonstrate the problem:
(Problems present themselves the same way in both the server and the clients)

// Fill out your copyright notice in the Description page of Project Settings.

#include "ColorBlock.h"
#include "LuisMFinalCharacter.h"
#include "Components/StaticMeshComponent.h"
#include "Components/BoxComponent.h"
#include "Components/SphereComponent.h"
#include "PhysicalMaterials/PhysicalMaterial.h"
#include "Materials/MaterialInstanceDynamic.h"
#include "Net/UnrealNetwork.h"

// Sets default values
AColorBlock::AColorBlock()
{
 	// 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;

    m_Bounds = CreateDefaultSubobject<UBoxComponent>("Bounds");
    m_Bounds->SetIsReplicated(true);
    m_Bounds->GetBodyInstance()->bLockXRotation = true;
    m_Bounds->GetBodyInstance()->bLockYRotation = true;
    m_Bounds->GetBodyInstance()->bLockZRotation = true;
    m_Bounds->GetBodyInstance()->bLockXTranslation = true;
    m_Bounds->GetBodyInstance()->bLockYTranslation = true;
    RootComponent = m_Bounds;
    m_Mesh = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
    m_Mesh->SetupAttachment(RootComponent);
    m_NighbourChecker = CreateDefaultSubobject<USphereComponent>("NeighbourChecker");
    m_NighbourChecker->SetupAttachment(RootComponent);
    m_NighbourChecker->SetSimulatePhysics(false);
    m_NighbourChecker->SetCollisionProfileName("QuerryOnly");
    m_NighbourChecker->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
    m_Colors.SetNum(3);

    m_ColorIndex = EColorEnum::VE_Grey;
    m_Active = true;

    //SetReplicateMovement(true);
    SetReplicates(true);
}

// Called when the game starts or when spawned
void AColorBlock::BeginPlay()
{
	Super::BeginPlay();

    if (Role == ROLE_Authority)
    {
        m_Bounds->SetSimulatePhysics(true);
        m_Bounds->SetCollisionEnabled(ECollisionEnabled::PhysicsOnly);
        m_ColorIndex = (EColorEnum)FMath::RandRange((int)EColorEnum::VE_Red, (int)EColorEnum::VE_Blue);
    }
    else
    {
        //Disable anything related to physics
        m_Bounds->SetSimulatePhysics(false);
        m_Bounds->SetCollisionProfileName("NoCollision");
        m_Bounds->SetCollisionEnabled(ECollisionEnabled::NoCollision);
        m_Bounds->SetSimulatePhysics(false);
        m_Mesh->SetCollisionProfileName("NoCollision");
        m_Bounds->SetCollisionEnabled(ECollisionEnabled::NoCollision);
    }
    m_Mesh->SetMaterial(0, m_Colors[(int)m_ColorIndex]);
}

// Called every frame
void AColorBlock::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

void AColorBlock::CascadeHit(ALuisMFinalCharacter* a_player)
{
    m_Active = false;
    TArray<AActor*> neighbours;
    TSubclassOf<AActor> templateFilter;
    m_NighbourChecker->GetOverlappingActors(neighbours);

    for (int i = 0; i<neighbours.Num(); i++)
    {
        AColorBlock* block = Cast<AColorBlock>(neighbours[i]);
        if (block != nullptr && block->m_Active == true && block->m_ColorIndex == m_ColorIndex)
        {
            block->CascadeHit(a_player);
        }
    }

    a_player->IncreaseScore();
    Destroy();
}

void AColorBlock::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);

    DOREPLIFETIME(AColorBlock, m_ColorIndex);
}

2 posts - 2 participants