npruehs / ue4-rts

Real-time strategy plugin and showcase for Unreal Engine 4.
MIT License
747 stars 151 forks source link

Buildings - constructing halfway through the floor (plane) #135

Closed Zimbo1786 closed 3 years ago

Zimbo1786 commented 4 years ago

Hi all,

When asking a builder to construct a building, the building cursor is created (which is above the plane) and when building placement is confirmed, the building is sometimes placed above the plan (as it should be) or it is placed halfway through the plane (which is incorrect). Just wondering if anyone else has faced this or might have a solution?

The first image shows the building being constructed halfway through the floor: image

This image shows the setup of the builder unit (I have placed the capsule collision as the root of the unit so that collision actually works - I found unless doing this, the unit walks through all other actors): image

The second image shows the setup of the building (as above, I have placed the box collision as the root of the building so that collision actually works): image

I have tried adjusting the builder and the building collision heights, mesh locations etc. and so far nothing seems to have worked. Any help would be appreciated.

npruehs commented 4 years ago

Hey @Zimbo1786 !

That's odd, especially with the building cursor showing correct locations. Here's the code path that's used for placing the construction site:

You might wanna investigate along these lines to find out where the building locations gets wrong.

Hope that helps!

Zimbo1786 commented 4 years ago

Hi @npruehs ,

Thanks for the tips, I have looked and I created a few extra logging steps and it looks like the building does not have a valid index number.

The code is here in the ARTSPlayerController::IssueBeginConstructionOrder

for (auto SelectedActor : SelectedActors)
{
    if (!IsValid(SelectedActor) || SelectedActor->GetOwner() != this)
    {
        continue;
    }

    BuildingIndex = URTSConstructionLibrary::GetConstructableBuildingIndex(SelectedActor, BuildingClass);

    if (BuildingIndex != INDEX_NONE)
    {
        UE_LOG(LogRTS, Log, TEXT("Ordered actor %s does not have a valid BuildingIndex %s."), *SelectedActor->GetName(), *BuildingClass->GetName());

        break;
    }
}
npruehs commented 4 years ago

BuildingIndex != INDEX_NONE indicates a valid building index :)

Zimbo1786 commented 4 years ago

Hi @npruehs,

Thanks for that - just a question then as still learning C++, with the code below:

bool ARTSPlayerControllerSkirmish::IssueBeginConstructionOrder(TSubclassOf BuildingClass, const FVector& TargetLocation) { // Determine index. int32 BuildingIndex = INDEX_NONE;

for (auto SelectedActor : SelectedActors)
{
    if (!IsValid(SelectedActor) || SelectedActor->GetOwner() != this)
    {
        continue;
    }

    BuildingIndex = URTSConstructionLibrary::GetConstructableBuildingIndex(SelectedActor, BuildingClass);

    if (BuildingIndex != INDEX_NONE)
    {
        UE_LOG(LogRTS, Log, TEXT("Ordered actor %s does have a valid BuildingIndex %s."), *SelectedActor->GetName(), *BuildingClass->GetName());

        break;
    }
}

if (BuildingIndex == INDEX_NONE)
{
    UE_LOG(LogRTS, Log, TEXT("BuildingIndex is false %s."));

    return false;
}

FRTSOrderData BeginConstructionOrder;
BeginConstructionOrder.OrderClass = URTSBeginConstructionOrder::StaticClass();
BeginConstructionOrder.TargetLocation = TargetLocation;
BeginConstructionOrder.Index = BuildingIndex;

UE_LOG(LogRTS, Log, TEXT("BeginConstructionOrder at %s."), *BeginConstructionOrder.TargetLocation.ToString());

return IssueOrderToSelectedActors(BeginConstructionOrder);

}

Where the BuildingIndex != INDEX_NONE, and it is a valid building index, with the break in the function - does this skip the rest of the code in the bool function or does something else? Is it similar to the continue in the SelectedActor section?

Zimbo1786 commented 4 years ago

So I have been able to look through the code and compare line by line for the plugin in my project and for the RTSProject and all is looking like it lines up. I have also checked the Behaviour Trees and the Orders to ensure that there is nothing going on there and again both comparisons are okay.

What I have noticed in the logs is that when the building is through the plane (incorrect), the Z value is -0.00 and when it sits above the plane (correct), it has a Z-value of +0.00. Not sure if this is leading me back to the Skeletal Mesh and it's positioning to the capsule....

npruehs commented 4 years ago

Hey @Zimbo1786 ,

that all sounds very odd to me. I vaguely recall a similar issue at the very beginning of A Year Of Rain, but I'm not sure what the reason/solution was.

Can you share a minimum repro?

Thanks, Nick

Zimbo1786 commented 4 years ago

Hey @npruehs,

I have finally found out what the issue was - nothing to do with the code or orders, but was to do with the box collision on the building and under the Collision section: -> Collision Presets (when set to OverlapAllDynamic, the building stays above the plan every time, however when set to Custom and set it to WorldDynamic and set the block to WorldDynamic, the building then goes through the floor).

Trying to come up with a collision preset that allows the building to block pawns, but also stay above the plane - will keep trying, but consider the issue closed.

Image below: image

Zimbo1786 commented 3 years ago

Closing so as to keep it around for anyone with similar issues can see and resolve.