diff --git a/Config/DefaultEngine.ini b/Config/DefaultEngine.ini index b6b8052..baf6d99 100644 --- a/Config/DefaultEngine.ini +++ b/Config/DefaultEngine.ini @@ -88,35 +88,37 @@ ManualIPAddress= -Profiles=(Name="Vehicle",CollisionEnabled=QueryAndPhysics,ObjectTypeName="Vehicle",CustomResponses=,HelpMessage="Vehicle object that blocks Vehicle, WorldStatic, and WorldDynamic. All other channels will be set to default.",bCanModify=False) -Profiles=(Name="UI",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Block),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ",bCanModify=False) +Profiles=(Name="NoCollision",CollisionEnabled=NoCollision,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="No collision") -+Profiles=(Name="BlockAll",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=,HelpMessage="WorldStatic object that blocks all actors by default. All new custom channels will use its own default response. ") -+Profiles=(Name="OverlapAll",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ") -+Profiles=(Name="BlockAllDynamic",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=,HelpMessage="WorldDynamic object that blocks all actors by default. All new custom channels will use its own default response. ") -+Profiles=(Name="OverlapAllDynamic",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that overlaps all actors by default. All new custom channels will use its own default response. ") -+Profiles=(Name="IgnoreOnlyPawn",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that ignores Pawn and Vehicle. All other channels will be set to default.") -+Profiles=(Name="OverlapOnlyPawn",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that overlaps Pawn, Camera, and Vehicle. All other channels will be set to default. ") -+Profiles=(Name="Pawn",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object. Can be used for capsule of any playerable character or AI. ") -+Profiles=(Name="Spectator",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="WorldStatic"),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore)),HelpMessage="Pawn object that ignores all other actors except WorldStatic.") -+Profiles=(Name="CharacterMesh",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="CharacterMesh",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object that is used for Character Mesh. All other channels will be set to default.") ++Profiles=(Name="BlockAll",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Projectile")),HelpMessage="WorldStatic object that blocks all actors by default. All new custom channels will use its own default response. ") ++Profiles=(Name="OverlapAll",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap),(Channel="Projectile",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ") ++Profiles=(Name="BlockAllDynamic",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Projectile")),HelpMessage="WorldDynamic object that blocks all actors by default. All new custom channels will use its own default response. ") ++Profiles=(Name="OverlapAllDynamic",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap),(Channel="Projectile",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that overlaps all actors by default. All new custom channels will use its own default response. ") ++Profiles=(Name="IgnoreOnlyPawn",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Projectile")),HelpMessage="WorldDynamic object that ignores Pawn and Vehicle. All other channels will be set to default.") ++Profiles=(Name="OverlapOnlyPawn",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Projectile")),HelpMessage="WorldDynamic object that overlaps Pawn, Camera, and Vehicle. All other channels will be set to default. ") ++Profiles=(Name="Pawn",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="Pawn object. Can be used for capsule of any playerable character or AI. ") ++Profiles=(Name="Spectator",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore)),HelpMessage="Pawn object that ignores all other actors except WorldStatic.") ++Profiles=(Name="CharacterMesh",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="CharacterMesh",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Projectile",Response=ECR_Overlap)),HelpMessage="Pawn object that is used for Character Mesh. All other channels will be set to default.") +Profiles=(Name="PhysicsActor",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="PhysicsBody",CustomResponses=,HelpMessage="Simulating actors") +Profiles=(Name="Destructible",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Destructible",CustomResponses=,HelpMessage="Destructible actors") +Profiles=(Name="InvisibleWall",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldStatic object that is invisible.") +Profiles=(Name="InvisibleWallDynamic",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that is invisible.") -+Profiles=(Name="Trigger",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that is used for trigger. All other channels will be set to default.") ++Profiles=(Name="Trigger",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that is used for trigger. All other channels will be set to default.") +Profiles=(Name="Ragdoll",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="PhysicsBody",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Simulating Skeletal Mesh Component. All other channels will be set to default.") +Profiles=(Name="Vehicle",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Vehicle",CustomResponses=,HelpMessage="Vehicle object that blocks Vehicle, WorldStatic, and WorldDynamic. All other channels will be set to default.") -+Profiles=(Name="UI",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility"),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ") ++Profiles=(Name="UI",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ") +Profiles=(Name="ProjectileCollision",CollisionEnabled=QueryOnly,bCanModify=True,ObjectTypeName="Projectile",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore),(Channel="CharacterMesh",Response=ECR_Overlap)),HelpMessage="Needs description") +Profiles=(Name="ProjectileAssistance",CollisionEnabled=QueryOnly,bCanModify=True,ObjectTypeName="Projectile",CustomResponses=((Channel="WorldStatic",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore),(Channel="CharacterMesh",Response=ECR_Overlap)),HelpMessage="Needs description") +DefaultChannelResponses=(Channel=ECC_GameTraceChannel1,DefaultResponse=ECR_Ignore,bTraceType=False,bStaticObject=False,Name="CharacterMesh") +DefaultChannelResponses=(Channel=ECC_GameTraceChannel2,DefaultResponse=ECR_Ignore,bTraceType=False,bStaticObject=False,Name="Projectile") -+EditProfiles=(Name="Pawn",CustomResponses=((Channel="Camera",Response=ECR_Ignore),(Channel="Projectile",Response=ECR_Ignore))) -+EditProfiles=(Name="CharacterMesh",CustomResponses=((Channel="Camera",Response=ECR_Ignore),(Channel="Projectile",Response=ECR_Overlap))) ++DefaultChannelResponses=(Channel=ECC_GameTraceChannel3,DefaultResponse=ECR_Ignore,bTraceType=True,bStaticObject=False,Name="TraceCustom") ++EditProfiles=(Name="Pawn",CustomResponses=((Channel="Camera",Response=ECR_Ignore),(Channel="Projectile",Response=ECR_Ignore),(Channel="TraceCustom"))) ++EditProfiles=(Name="CharacterMesh",CustomResponses=((Channel="Camera",Response=ECR_Ignore),(Channel="Projectile",Response=ECR_Overlap),(Channel="TraceCustom",Response=ECR_Ignore))) +EditProfiles=(Name="BlockAll",CustomResponses=((Channel="Projectile"))) +EditProfiles=(Name="OverlapAll",CustomResponses=((Channel="Projectile",Response=ECR_Overlap))) +EditProfiles=(Name="BlockAllDynamic",CustomResponses=((Channel="Projectile"))) +EditProfiles=(Name="OverlapAllDynamic",CustomResponses=((Channel="Projectile",Response=ECR_Overlap))) +EditProfiles=(Name="IgnoreOnlyPawn",CustomResponses=((Channel="Projectile"))) +EditProfiles=(Name="OverlapOnlyPawn",CustomResponses=((Channel="Projectile"))) ++EditProfiles=(Name="Spectator",CustomResponses=((Channel="TraceCustom",Response=ECR_Ignore))) -ProfileRedirects=(OldName="BlockingVolume",NewName="InvisibleWall") -ProfileRedirects=(OldName="InterpActor",NewName="IgnoreOnlyPawn") -ProfileRedirects=(OldName="StaticMeshComponent",NewName="BlockAllDynamic") @@ -135,4 +137,5 @@ ManualIPAddress= +CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic") +CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle") +CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn") ++CollisionChannelRedirects=(OldName="Test",NewName="TraceCustom") diff --git a/Plugins/Cog/Source/CogDebug/Public/CogDebug.h b/Plugins/Cog/Source/CogDebug/Public/CogDebug.h index e0dbc5b..7126c5e 100644 --- a/Plugins/Cog/Source/CogDebug/Public/CogDebug.h +++ b/Plugins/Cog/Source/CogDebug/Public/CogDebug.h @@ -110,7 +110,7 @@ struct FCogDebugSettings TEnumAsByte GizmoGroundRaycastChannel = ECollisionChannel::ECC_WorldStatic; UPROPERTY(Config) - float GizmoGroundRaycastCircleRadius = 10.f; + float GizmoGroundRaycastCircleRadius = 5.0f; UPROPERTY(Config) FColor GizmoAxisColorsZHighX = FColor(255, 50, 50, 255); diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CollisionTester.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CollisionTester.cpp index 3d29dd5..8915ca8 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CollisionTester.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CollisionTester.cpp @@ -35,6 +35,75 @@ void FCogEngineWindow_CollisionTester::ResetConfig() Config->Reset(); } +//-------------------------------------------------------------------------------------------------------------------------- +bool RenderCollisionProfileChannels(const UCollisionProfile& CollisionProfileChannels, int32& Channels, const TArray& ChannelsConfig) +{ + bool Result = false; + + for (const FCogCollisionChannel& ChannelConfig : ChannelsConfig) + { + const ECollisionChannel Channel = ChannelConfig.Channel.GetValue(); + ImGui::PushID(Channel); + + ImColor Color = FCogImguiHelper::ToImColor(ChannelConfig.Color); + ImGui::ColorEdit4("Color", (float*)&Color.Value, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel); + ImGui::SameLine(); + + bool IsCollisionActive = (Channels & ECC_TO_BITFIELD(Channel)) > 0; + const FName ChannelName = CollisionProfileChannels.ReturnChannelNameFromContainerIndex(Channel); + if (ImGui::Checkbox(TCHAR_TO_ANSI(*ChannelName.ToString()), &IsCollisionActive)) + { + Result = true; + + if (IsCollisionActive) + { + Channels |= ECC_TO_BITFIELD(Channel); + } + else + { + Channels &= ~ECC_TO_BITFIELD(Channel); + } + } + + ImGui::PopID(); + } + + return Result; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool RenderComboCollisionChannel(const char* Label, const UCollisionProfile& CollisionProfile, ECollisionChannel& SelectedChannel, const TArray& ChannelsConfig) +{ + const FName SelectedChannelName = CollisionProfile.ReturnChannelNameFromContainerIndex(SelectedChannel); + + bool Result = false; + if (ImGui::BeginCombo(Label, TCHAR_TO_ANSI(*SelectedChannelName.ToString()), ImGuiComboFlags_HeightLarge)) + { + for (const FCogCollisionChannel& ChannelConfig : ChannelsConfig) + { + const ECollisionChannel Channel = ChannelConfig.Channel.GetValue(); + ImGui::PushID(Channel); + + const FName ChannelName = CollisionProfile.ReturnChannelNameFromContainerIndex(Channel); + + ImColor Color = FCogImguiHelper::ToImColor(ChannelConfig.Color); + ImGui::ColorEdit4("Color", (float*)&Color.Value, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel); + ImGui::SameLine(); + + if (ImGui::Selectable(TCHAR_TO_ANSI(*ChannelName.ToString()))) + { + SelectedChannel = Channel; + Result = true; + } + + ImGui::PopID(); + } + ImGui::EndCombo(); + } + + return Result; +} + //-------------------------------------------------------------------------------------------------------------------------- void FCogEngineWindow_CollisionTester::RenderContent() { @@ -82,6 +151,9 @@ void FCogEngineWindow_CollisionTester::RenderContent() FCogWindowWidgets::SetNextItemToShortWidth(); FCogWindowWidgets::ComboboxEnum("Type", Config->Type); + FCogWindowWidgets::SetNextItemToShortWidth(); + FCogWindowWidgets::ComboboxEnum("Mode", Config->Mode); + FCogWindowWidgets::SetNextItemToShortWidth(); FCogWindowWidgets::ComboboxEnum("By", Config->By); @@ -92,7 +164,7 @@ void FCogEngineWindow_CollisionTester::RenderContent() { FCogWindowWidgets::SetNextItemToShortWidth(); ECollisionChannel Channel = Config->Channel.GetValue(); - if (FCogWindowWidgets::ComboCollisionChannel("Channel", Channel)) + if (RenderComboCollisionChannel("Channel", *CollisionProfile, Channel, Asset->Channels)) { Config->Channel = Channel; } @@ -103,7 +175,7 @@ void FCogEngineWindow_CollisionTester::RenderContent() else if (Config->By == ECogEngine_CollisionQueryBy::Profile) { const FCollisionResponseTemplate* SelectedProfile = CollisionProfile->GetProfileByIndex(Config->ProfileIndex); - FName SelectedProfileName = SelectedProfile != nullptr ? SelectedProfile->Name : FName("Custom"); + const FName SelectedProfileName = SelectedProfile != nullptr ? SelectedProfile->Name : FName("Custom"); FCogWindowWidgets::SetNextItemToShortWidth(); if (ImGui::BeginCombo("Profile", TCHAR_TO_ANSI(*SelectedProfileName.ToString()), ImGuiComboFlags_HeightLargest)) @@ -121,7 +193,7 @@ void FCogEngineWindow_CollisionTester::RenderContent() { for (int j = 0; j < ECC_MAX; ++j) { - ECollisionResponse Response = Profile->ResponseToChannels.GetResponse((ECollisionChannel)j); + const ECollisionResponse Response = Profile->ResponseToChannels.GetResponse((ECollisionChannel)j); if (Response != ECR_Ignore) { Config->ObjectTypesToQuery |= ECC_TO_BITFIELD(j); @@ -132,52 +204,13 @@ void FCogEngineWindow_CollisionTester::RenderContent() } ImGui::EndCombo(); } - ImGui::Separator(); - - //------------------------------------------------- - // Query Filtering - //------------------------------------------------- - for (int ChannelIndex = 0; ChannelIndex < (int32)ECC_MAX; ++ChannelIndex) - { - const FChannel& Channel = Channels[ChannelIndex]; - if (Channel.IsValid == false) - { - continue; - } - - ImGui::PushID(ChannelIndex); - - ImColor Color = FCogImguiHelper::ToImColor(Channel.Color); - ImGui::ColorEdit4("Color", (float*)&Color.Value, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel); - ImGui::SameLine(); - - bool IsCollisionActive = (Config->ObjectTypesToQuery & ECC_TO_BITFIELD(ChannelIndex)) > 0; - const FName ChannelName = CollisionProfile->ReturnChannelNameFromContainerIndex(ChannelIndex); - if (ImGui::Checkbox(TCHAR_TO_ANSI(*ChannelName.ToString()), &IsCollisionActive)) - { - if (IsCollisionActive) - { - Config->ObjectTypesToQuery |= ECC_TO_BITFIELD(ChannelIndex); - Config->ProfileIndex = INDEX_NONE; - } - else - { - Config->ObjectTypesToQuery &= ~ECC_TO_BITFIELD(ChannelIndex); - Config->ProfileIndex = INDEX_NONE; - } - } - - ImGui::PopID(); - } } - ImGui::Checkbox("Multi", &Config->MultiHits); ImGui::Checkbox("Complex", &Config->TraceComplex); //------------------------------------------------- // Shape //------------------------------------------------- - ImGui::Separator(); if (Config->Type != ECogEngine_CollisionQueryType::LineTrace) { @@ -186,32 +219,49 @@ void FCogEngineWindow_CollisionTester::RenderContent() switch (Config->Shape) { - case ECogEngine_CollisionQueryShape::Sphere: - { - FCogWindowWidgets::SetNextItemToShortWidth(); - FCogImguiHelper::DragDouble("Sphere Radius", &Config->ShapeExtent.X, 0.1f, 0, FLT_MAX, "%.1f"); - break; - } + case ECogEngine_CollisionQueryShape::Sphere: + { + FCogWindowWidgets::SetNextItemToShortWidth(); + FCogImguiHelper::DragDouble("Sphere Radius", &Config->ShapeExtent.X, 0.1f, 0, FLT_MAX, "%.1f"); + break; + } - case ECogEngine_CollisionQueryShape::Box: - { - FCogWindowWidgets::SetNextItemToShortWidth(); - FCogImguiHelper::DragFVector("Box Extent", Config->ShapeExtent, 0.1f, 0, FLT_MAX, "%.1f"); - break; - } + case ECogEngine_CollisionQueryShape::Box: + { + FCogWindowWidgets::SetNextItemToShortWidth(); + FCogImguiHelper::DragFVector("Box Extent", Config->ShapeExtent, 0.1f, 0, FLT_MAX, "%.1f"); + break; + } - case ECogEngine_CollisionQueryShape::Capsule: - { - FCogWindowWidgets::SetNextItemToShortWidth(); - FCogImguiHelper::DragDouble("Capsule Radius", &Config->ShapeExtent.X, 0.1f, 0, FLT_MAX, "%.1f"); + case ECogEngine_CollisionQueryShape::Capsule: + { + FCogWindowWidgets::SetNextItemToShortWidth(); + FCogImguiHelper::DragDouble("Capsule Radius", &Config->ShapeExtent.X, 0.1f, 0, FLT_MAX, "%.1f"); - FCogWindowWidgets::SetNextItemToShortWidth(); - FCogImguiHelper::DragDouble("Capsule Half Height", &Config->ShapeExtent.Z, 0.1f, 0, FLT_MAX, "%.1f"); - break; - } + FCogWindowWidgets::SetNextItemToShortWidth(); + FCogImguiHelper::DragDouble("Capsule Half Height", &Config->ShapeExtent.Z, 0.1f, 0, FLT_MAX, "%.1f"); + break; + } } } + ImGui::Separator(); + + //------------------------------------------------- + // Channels + //------------------------------------------------- + if (Config->By == ECogEngine_CollisionQueryBy::Profile) + { + ImGui::BeginDisabled(); + RenderCollisionProfileChannels(*CollisionProfile, Config->ObjectTypesToQuery, Asset->Channels); + ImGui::EndDisabled(); + } + else if (Config->By == ECogEngine_CollisionQueryBy::ObjectType) + { + RenderCollisionProfileChannels(*CollisionProfile, Config->ObjectTypesToQuery, Asset->Channels); + } + + Query(); } @@ -236,7 +286,10 @@ void FCogEngineWindow_CollisionTester::Query() static const FName TraceTag(TEXT("FCogWindow_Collision")); - FCollisionQueryParams QueryParams(TraceTag, SCENE_QUERY_STAT_ONLY(CogHitDetection), Config->TraceComplex); + const FCollisionQueryParams QueryParams(TraceTag, SCENE_QUERY_STAT_ONLY(CogHitDetection), Config->TraceComplex); + + const FCollisionResponseTemplate* Profile = UCollisionProfile::Get()->GetProfileByIndex(Config->ProfileIndex); + const FName ProfileName = Profile != nullptr ? Profile->Name : FName(); FCollisionShape QueryShape; @@ -257,25 +310,25 @@ void FCogEngineWindow_CollisionTester::Query() { switch (Config->By) { - case ECogEngine_CollisionQueryBy::Channel: - { - HasHits = GetWorld()->OverlapMultiByChannel(Overlaps, QueryStart, QueryRotation, (ECollisionChannel)Config->Channel, QueryShape, QueryParams); - break; - } + case ECogEngine_CollisionQueryBy::Channel: + { + HasHits = GetWorld()->OverlapMultiByChannel(Overlaps, QueryStart, QueryRotation, Config->Channel, QueryShape, QueryParams); + break; + } - case ECogEngine_CollisionQueryBy::ObjectType: - { - FCollisionObjectQueryParams QueryObjectParams; - QueryObjectParams.ObjectTypesToQuery = Config->ObjectTypesToQuery; - HasHits = GetWorld()->OverlapMultiByObjectType(Overlaps, QueryStart, QueryRotation, QueryObjectParams, QueryShape, QueryParams); - break; - } + case ECogEngine_CollisionQueryBy::ObjectType: + { + FCollisionObjectQueryParams QueryObjectParams; + QueryObjectParams.ObjectTypesToQuery = Config->ObjectTypesToQuery; + HasHits = GetWorld()->OverlapMultiByObjectType(Overlaps, QueryStart, QueryRotation, QueryObjectParams, QueryShape, QueryParams); + break; + } - case ECogEngine_CollisionQueryBy::Profile: - { - HasHits = GetWorld()->OverlapMultiByProfile(Overlaps, QueryStart, QueryRotation, Config->Profile, QueryShape, QueryParams); - break; - } + case ECogEngine_CollisionQueryBy::Profile: + { + HasHits = GetWorld()->OverlapMultiByProfile(Overlaps, QueryStart, QueryRotation, ProfileName, QueryShape, QueryParams); + break; + } } break; @@ -285,62 +338,93 @@ void FCogEngineWindow_CollisionTester::Query() { switch (Config->By) { - case ECogEngine_CollisionQueryBy::Channel: + case ECogEngine_CollisionQueryBy::Channel: + { + switch (Config->Mode) { - if (Config->MultiHits) + case ECogEngine_CollisionQueryMode::Single: + { + FHitResult Hit; + HasHits = GetWorld()->LineTraceSingleByChannel(Hit, QueryStart, QueryEnd, Config->Channel, QueryParams); + if (HasHits) { - HasHits = GetWorld()->LineTraceMultiByChannel(Hits, QueryStart, QueryEnd, (ECollisionChannel)Config->Channel, QueryParams); - } - else - { - FHitResult Hit; - HasHits = GetWorld()->LineTraceSingleByChannel(Hit, QueryStart, QueryEnd, (ECollisionChannel)Config->Channel, QueryParams); - if (HasHits) - { - Hits.Add(Hit); - } + Hits.Add(Hit); } break; } - - case ECogEngine_CollisionQueryBy::ObjectType: + case ECogEngine_CollisionQueryMode::Multi: { - FCollisionObjectQueryParams QueryObjectParams; - QueryObjectParams.ObjectTypesToQuery = Config->ObjectTypesToQuery; + HasHits = GetWorld()->LineTraceMultiByChannel(Hits, QueryStart, QueryEnd, Config->Channel, QueryParams); + break; + } + case ECogEngine_CollisionQueryMode::Test: + { + HasHits = GetWorld()->LineTraceTestByChannel(QueryStart, QueryEnd, Config->Channel, QueryParams); + break; + } + } - if (Config->MultiHits) + break; + } + + case ECogEngine_CollisionQueryBy::ObjectType: + { + FCollisionObjectQueryParams QueryObjectParams; + QueryObjectParams.ObjectTypesToQuery = Config->ObjectTypesToQuery; + + switch (Config->Mode) + { + case ECogEngine_CollisionQueryMode::Single: + { + FHitResult Hit; + HasHits = GetWorld()->LineTraceSingleByObjectType(Hit, QueryStart, QueryEnd, QueryObjectParams, QueryParams); + if (HasHits) { - HasHits = GetWorld()->LineTraceMultiByObjectType(Hits, QueryStart, QueryEnd, QueryObjectParams, QueryParams); - } - else - { - FHitResult Hit; - HasHits = GetWorld()->LineTraceSingleByObjectType(Hit, QueryStart, QueryEnd, QueryObjectParams, QueryParams); - if (HasHits) - { - Hits.Add(Hit); - } + Hits.Add(Hit); } break; } - - case ECogEngine_CollisionQueryBy::Profile: + case ECogEngine_CollisionQueryMode::Multi: { - if (Config->MultiHits) + HasHits = GetWorld()->LineTraceMultiByObjectType(Hits, QueryStart, QueryEnd, QueryObjectParams, QueryParams); + break; + } + case ECogEngine_CollisionQueryMode::Test: + { + HasHits = GetWorld()->LineTraceTestByObjectType(QueryStart, QueryEnd, QueryObjectParams, QueryParams); + break; + } + } + break; + } + + case ECogEngine_CollisionQueryBy::Profile: + { + switch (Config->Mode) + { + case ECogEngine_CollisionQueryMode::Single: + { + FHitResult Hit; + HasHits = GetWorld()->LineTraceSingleByProfile(Hit, QueryStart, QueryEnd, ProfileName, QueryParams); + if (HasHits) { - GetWorld()->LineTraceMultiByProfile(Hits, QueryStart, QueryEnd, Config->Profile, QueryParams); - } - else - { - FHitResult Hit; - HasHits = GetWorld()->LineTraceSingleByProfile(Hit, QueryStart, QueryEnd, Config->Profile, QueryParams); - if (HasHits) - { - Hits.Add(Hit); - } + Hits.Add(Hit); } break; } + case ECogEngine_CollisionQueryMode::Multi: + { + HasHits = GetWorld()->LineTraceMultiByProfile(Hits, QueryStart, QueryEnd, ProfileName, QueryParams); + break; + } + case ECogEngine_CollisionQueryMode::Test: + { + HasHits = GetWorld()->LineTraceTestByProfile(QueryStart, QueryEnd, ProfileName, QueryParams); + break; + } + } + break; + } } break; } @@ -351,59 +435,87 @@ void FCogEngineWindow_CollisionTester::Query() { case ECogEngine_CollisionQueryBy::Channel: { - if (Config->MultiHits) + switch (Config->Mode) { - HasHits = GetWorld()->SweepMultiByChannel(Hits, QueryStart, QueryEnd, QueryRotation, (ECollisionChannel)Config->Channel, QueryShape, QueryParams); - } - else + case ECogEngine_CollisionQueryMode::Single: { FHitResult Hit; - HasHits = GetWorld()->SweepSingleByChannel(Hit, QueryStart, QueryEnd, QueryRotation, (ECollisionChannel)Config->Channel, QueryShape, QueryParams); + HasHits = GetWorld()->SweepSingleByChannel(Hit, QueryStart, QueryEnd, QueryRotation, Config->Channel, QueryShape, QueryParams); if (HasHits) { Hits.Add(Hit); } + break; + } + case ECogEngine_CollisionQueryMode::Multi: + { + HasHits = GetWorld()->SweepMultiByChannel(Hits, QueryStart, QueryEnd, QueryRotation, Config->Channel, QueryShape, QueryParams); + break; + } + case ECogEngine_CollisionQueryMode::Test: + { + HasHits = GetWorld()->SweepTestByChannel(QueryStart, QueryEnd, QueryRotation, Config->Channel, QueryShape, QueryParams); + break; + } } break; } case ECogEngine_CollisionQueryBy::ObjectType: { - if (Config->MultiHits) - { - FCollisionObjectQueryParams QueryObjectParams; - QueryObjectParams.ObjectTypesToQuery = Config->ObjectTypesToQuery; - HasHits = GetWorld()->SweepMultiByObjectType(Hits, QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams); - } - else - { - FCollisionObjectQueryParams QueryObjectParams; - QueryObjectParams.ObjectTypesToQuery = Config->ObjectTypesToQuery; + FCollisionObjectQueryParams QueryObjectParams; + QueryObjectParams.ObjectTypesToQuery = Config->ObjectTypesToQuery; + switch (Config->Mode) + { + case ECogEngine_CollisionQueryMode::Single: + { FHitResult Hit; HasHits = GetWorld()->SweepSingleByObjectType(Hit, QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams); if (HasHits) { Hits.Add(Hit); } + break; + } + case ECogEngine_CollisionQueryMode::Multi: + { + HasHits = GetWorld()->SweepMultiByObjectType(Hits, QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams); + break; + } + case ECogEngine_CollisionQueryMode::Test: + { + HasHits = GetWorld()->SweepTestByObjectType(QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams); + break; + } } break; } case ECogEngine_CollisionQueryBy::Profile: { - if (Config->MultiHits) + switch (Config->Mode) { - HasHits = GetWorld()->SweepMultiByProfile(Hits, QueryStart, QueryEnd, QueryRotation, Config->Profile, QueryShape, QueryParams); - } - else + case ECogEngine_CollisionQueryMode::Single: { FHitResult Hit; - HasHits = GetWorld()->SweepSingleByProfile(Hit, QueryStart, QueryEnd, QueryRotation, Config->Profile, QueryShape, QueryParams); + HasHits = GetWorld()->SweepSingleByProfile(Hit, QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams); if (HasHits) { Hits.Add(Hit); } + break; + } + case ECogEngine_CollisionQueryMode::Multi: + { + HasHits = GetWorld()->SweepMultiByProfile(Hits, QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams); + break; + } + case ECogEngine_CollisionQueryMode::Test: + { + HasHits = GetWorld()->SweepTestByProfile(QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams); + break; + } } break; } @@ -413,7 +525,6 @@ void FCogEngineWindow_CollisionTester::Query() } const FColor Color = HasHits ? FLinearColor(Config->HitColor).ToFColor(true) : FLinearColor(Config->NoHitColor).ToFColor(true); - const bool bUseTrace = Config->Type == ECogEngine_CollisionQueryType::LineTrace || Config->Type == ECogEngine_CollisionQueryType::Sweep; if (bUseTrace) { diff --git a/Plugins/Cog/Source/CogEngine/Public/CogEngineDataAsset.h b/Plugins/Cog/Source/CogEngine/Public/CogEngineDataAsset.h index a53e4c9..5fc6933 100644 --- a/Plugins/Cog/Source/CogEngine/Public/CogEngineDataAsset.h +++ b/Plugins/Cog/Source/CogEngine/Public/CogEngineDataAsset.h @@ -12,7 +12,7 @@ struct COGENGINE_API FCogCollisionChannel GENERATED_BODY() UPROPERTY(EditAnywhere) - TEnumAsByte Channel = ECollisionChannel::ECC_WorldStatic; + TEnumAsByte Channel = ECC_WorldStatic; UPROPERTY(EditAnywhere) FLinearColor Color = FLinearColor(0.5f, 0.5f, 0.5f, 1.0f); diff --git a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_CollisionTester.h b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_CollisionTester.h index 9af2da4..4aa99a9 100644 --- a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_CollisionTester.h +++ b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_CollisionTester.h @@ -23,10 +23,11 @@ enum class ECogEngine_CollisionQueryType : uint8 //-------------------------------------------------------------------------------------------------------------------------- UENUM() -enum class ECogEngine_CollisionQueryCount : uint8 +enum class ECogEngine_CollisionQueryMode : uint8 { Single, Multi, + Test, }; //-------------------------------------------------------------------------------------------------------------------------- @@ -62,7 +63,6 @@ public: protected: virtual void ResetConfig() override; - void DoWork(const UCollisionProfile* CollisionProfile); virtual void RenderHelp() override; @@ -125,24 +125,21 @@ public: UPROPERTY(Config) ECogEngine_CollisionQueryType Type; + UPROPERTY(Config) + ECogEngine_CollisionQueryMode Mode; + UPROPERTY(Config) ECogEngine_CollisionQueryBy By; UPROPERTY(Config) ECogEngine_CollisionQueryShape Shape; - UPROPERTY(Config) - bool MultiHits; - UPROPERTY(Config) bool TraceComplex; UPROPERTY(Config) int32 ObjectTypesToQuery; - UPROPERTY(Config) - FName Profile; - UPROPERTY(Config) TEnumAsByte Channel; @@ -199,8 +196,8 @@ public: Type = ECogEngine_CollisionQueryType::LineTrace; By = ECogEngine_CollisionQueryBy::Channel; + Mode = ECogEngine_CollisionQueryMode::Multi; Channel = ECC_WorldStatic; - MultiHits = false; TraceComplex = false; Shape = ECogEngine_CollisionQueryShape::Sphere; ShapeExtent = FVector(50.0f, 50.0f, 50.0f); diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp index 8c41b15..79897e9 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp @@ -646,5 +646,44 @@ bool FCogWindowWidgets::ComboCollisionChannel(const char* Label, ECollisionChann ImGui::EndCombo(); } + return Result; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogWindowWidgets::CollisionProfileChannel(const UCollisionProfile& CollisionProfile, const int32 ChannelIndex, int32& Channels) +{ + bool Result = false; + + bool IsCollisionActive = (Channels & ECC_TO_BITFIELD(ChannelIndex)) > 0; + const FName ChannelName = CollisionProfile.ReturnChannelNameFromContainerIndex(ChannelIndex); + if (ImGui::Checkbox(TCHAR_TO_ANSI(*ChannelName.ToString()), &IsCollisionActive)) + { + Result = true; + + if (IsCollisionActive) + { + Channels |= ECC_TO_BITFIELD(ChannelIndex); + } + else + { + Channels &= ~ECC_TO_BITFIELD(ChannelIndex); + } + } + + return Result; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogWindowWidgets::CollisionProfileChannels(const UCollisionProfile& CollisionProfile, int32& Channels) +{ + bool Result = false; + + for (int32 ChannelIndex = 0; ChannelIndex < (int32)ECC_MAX; ++ChannelIndex) + { + ImGui::PushID(ChannelIndex); + Result |= CollisionProfileChannel(CollisionProfile, ChannelIndex, Channels); + ImGui::PopID(); + } + return Result; } \ No newline at end of file diff --git a/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h b/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h index c167ab7..f15622a 100644 --- a/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h +++ b/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h @@ -82,6 +82,9 @@ public: static bool ComboCollisionChannel(const char* Label, ECollisionChannel& Channel); + static bool CollisionProfileChannel(const UCollisionProfile& CollisionProfile, int32 ChannelIndex, int32& Channels); + + static bool CollisionProfileChannels(const UCollisionProfile& CollisionProfile, int32& Channels); };