14 Commits

Author SHA1 Message Date
bd9543faed Commit to save work 2025-05-08 16:18:14 -04:00
1575eb776b Commit to save work 2025-05-08 16:17:54 -04:00
874850fd2b Merge branch 'main' into Noah_UI_Updates_050325
# Conflicts:
#	Content/GameBP/UI/Common/WB_MenuTitle.uasset
#	Content/GameBP/UI/Settings/WB_CaptureSettings.uasset
#	Content/GameBP/UI/WB_GameWidget.uasset
#	Content/Map/Test_Level.umap
#	Plugins/LuckyMujoco/Binaries/Win64/UnrealEditor-LuckyMujoco.pdb
2025-05-08 12:13:30 -04:00
2cf0e50d13 UI pass 10
- Random scene generation
2025-05-07 16:42:51 -04:00
8649d11f2d UI pass 9
- Fun with physics
2025-05-07 05:19:46 -04:00
1da65b2117 UI pass 8
- Updates to light settings
2025-05-07 05:12:11 -04:00
009e01c373 UI pass 7
- added random object generation system
2025-05-07 04:38:43 -04:00
d602e635a3 UI pass 6 added click on object select, cleaned up lighting, added random options, etc
NEEDS TO BE CLEANED UP
2025-05-06 17:15:30 -04:00
c9810f0022 Updates to UI pass 6 (WIP) 2025-05-06 08:04:38 -04:00
544c9b4a8d Updates to UI pass 5 (WIP) 2025-05-05 11:19:54 -04:00
7f71da01a3 Updates to UI pass 4 2025-05-04 19:20:19 -04:00
d29935e93c Updates to UI pass 3 (WIP)
- Added drag and drop functionality
- Created necessary widgets for drag and drop
2025-05-04 11:57:26 -04:00
1160442f1f Updates to UI pass 2 (WIP)
- Added Camera spawn with params
- Connected camera editing
2025-05-03 21:57:06 -04:00
06a860f845 UI First pass (WIP)
- Added camera add menu
- Added camera settings widget
- Added FOV, Distance, Location, Rotation options
2025-05-03 17:07:17 -04:00
46 changed files with 631 additions and 2 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Content/Meshes/Lego.uasset Normal file

Binary file not shown.

View File

@ -16,11 +16,14 @@
#include "Subsystem/UISubsystem.h"
#include "Engine/World.h"
#include "Engine/Engine.h"
#include "Net/Core/Connection/NetConnectionFaultRecoveryBase.h"
void ULuckyRobotsGameInstance::Init()
{
Super::Init();
ParseIncomingStartParams();
// Set fullscreen mode on startup
DoResolutionChange(true);
@ -296,6 +299,9 @@ TArray<FSelectableItemData> ULuckyRobotsGameInstance::GetSelectableItemList(EIte
case EItemCategory::Bathroom:
SelectedDataTable = BathroomDataTable;
break;
case EItemCategory::TinyObjects:
SelectedDataTable = TinyObjectsDataTable;
break;
default:
break;
}
@ -717,3 +723,61 @@ EUnrealBuildType ULuckyRobotsGameInstance::CheckBuildConfiguration() const
}
#endif
}
void ULuckyRobotsGameInstance::ParseIncomingStartParams()
{
FString inheadless = FString();
if (FParse::Value(FCommandLine::Get(), TEXT("Headless="), inheadless))
{
if (Headless == TEXT("true"))
{
Params.bAutoSetup = true;
FString inscene = FString();
if (FParse::Value(FCommandLine::Get(), TEXT("Scene="), inscene))
{
UE_LOG(LogTemp, Warning, TEXT("Scene to load: %s"), *inscene);
Params.SceneName = Scene;
}
FString inrobottype = FString();
if (FParse::Value(FCommandLine::Get(), TEXT("Surface="), inrobottype))
{
UE_LOG(LogTemp, Warning, TEXT("Robot to Load: %s"), *inrobottype);
Params.RobotType = inrobottype;
}
FString intask;
if (FParse::Value(FCommandLine::Get(), TEXT("Surface="), intask))
{
UE_LOG(LogTemp, Warning, TEXT("Task to do: %s"), *intask);
Params.Task = intask;
}
WaitForAutoSetup();
}
}
}
//Will refactor
void ULuckyRobotsGameInstance::WaitForAutoSetup()
{
if (GetWorld())
{
AutoSetUpScene();
}
else
{
FTimerHandle TimerHandle;
if (UWorld* World = GEngine->GetWorldFromContextObjectChecked(this))
{
World->GetTimerManager().SetTimer(TimerHandle, this, &ULuckyRobotsGameInstance::WaitForAutoSetup, 0.25f, false);
}
}
}
void ULuckyRobotsGameInstance::AutoSetUpScene()
{
UGameplayStatics::OpenLevel(GetWorld(), FName(Params.SceneName));
}

View File

@ -0,0 +1,26 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Gameplay/LuckyLightTool.h"
// Sets default values
ALuckyLightTool::ALuckyLightTool()
{
// 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;
}
// Called when the game starts or when spawned
void ALuckyLightTool::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ALuckyLightTool::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}

View File

@ -0,0 +1,31 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Gameplay/LuckyObjectBase.h"
// Sets default values
ALuckyObjectBase::ALuckyObjectBase()
{
Mesh = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
RootComponent = Mesh;
Mesh->SetSimulatePhysics(true);
// 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;
}
// Called when the game starts or when spawned
void ALuckyObjectBase::BeginPlay()
{
Super::BeginPlay();
Mesh->AddImpulse(FVector(0, 0, 100));
}
// Called every frame
void ALuckyObjectBase::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}

View File

@ -0,0 +1,54 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Subsystem/LuckySceneSubsystem.h"
#include "Core/LuckyRobotsGameInstance.h"
#include "Kismet/GameplayStatics.h"
#include "Subsystem/UISubsystem.h"
ULuckySceneSubsystem::ULuckySceneSubsystem()
{
}
void ULuckySceneSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
Super::Initialize(Collection);
}
void ULuckySceneSubsystem::Deinitialize()
{
Super::Deinitialize();
}
void ULuckySceneSubsystem::OnWorldBeginPlay(UWorld& InWorld)
{
Super::OnWorldBeginPlay(InWorld);
UE_LOG(LogTemp, Warning, TEXT("ULuckySceneSubsystem::OnWorldBeginPlay"));
if (ULuckyRobotsGameInstance* gi = Cast<ULuckyRobotsGameInstance>(GetWorld()->GetGameInstance()))
{
//if (gi->Params.bAutoSetup)
//{
if (UUISubsystem* UISubsystem = GetWorld()->GetGameInstance()->GetSubsystem<UUISubsystem>())
{
TArray<AActor*> FoundActors;
UGameplayStatics::GetAllActorsWithTag(this, "Surface", FoundActors);
if (IsValid(FoundActors[0])) UISubsystem->ClickedOnSurface = FoundActors[0];
UE_LOG(LogTemp, Warning, TEXT("Surface is valid: %s"), *UISubsystem->ClickedOnSurface->GetName());
for (auto Row : gi->TinyObjectsDataTable)
{
UISubsystem->SimObjects.Add(Row.Mesh);
}
UISubsystem->GenerateRandomObjects();
}
//}
}
}

View File

@ -2,4 +2,228 @@
#include "Subsystem/UISubsystem.h"
#include "Blueprint/UserWidget.h"
#include "Components/LightComponent.h"
#include "Core/LuckyRobotsGameInstance.h"
#include "Engine/DirectionalLight.h"
#include "Gameplay/LuckyObjectBase.h"
#include "Kismet/GameplayStatics.h"
#include "Kismet/KismetMathLibrary.h"
UUserWidget* UUISubsystem::OpenSettingsMenu(TSubclassOf<UUserWidget> InWidget)
{
if (CurrentSettings) CurrentSettings->RemoveFromParent();
CurrentSettings = CreateWidget<UUserWidget>(GetWorld(), InWidget, "Settings");
CurrentSettings->AddToViewport();
return CurrentSettings;
}
AActor* UUISubsystem::ClickOnActor()
{
AActor* outActor = nullptr;
if (APlayerController* PC = UGameplayStatics::GetPlayerController(GetWorld(), 0))
{
float MouseX = 0.f;
float MouseY = 0.f;
if (PC->GetMousePosition(MouseX, MouseY))
{
FVector WorldLocation = FVector();
FVector WorldDirection = FVector();
if (PC->DeprojectScreenPositionToWorld(MouseX, MouseY, WorldLocation, WorldDirection))
{
FHitResult HitResult;
FVector TraceStart = WorldLocation;
FVector TraceEnd = TraceStart + (WorldDirection * 10000.0f);
FCollisionQueryParams Params;
FCollisionObjectQueryParams ObjectParams;
Params.AddIgnoredActor(PC);
//Replace with robot base class
if (IsValid(Robot)) Params.AddIgnoredActor(Robot);
if (UISelectionType == EUISelectionType::Target) ObjectParams.AddObjectTypesToQuery(ECC_WorldDynamic);
if (UISelectionType == EUISelectionType::Surface) ObjectParams.AddObjectTypesToQuery(ECC_WorldStatic);
bool bHit = GetWorld()->LineTraceSingleByObjectType(
HitResult,
TraceStart,
TraceEnd,
ObjectParams,
Params
);
//Leave in for debug trace
//DrawDebugLine(GetWorld(), TraceStart, TraceEnd, FColor::Green, false, 100.f, 0, 1.0f);
if (HitResult.GetActor()) UE_LOG(LogTemp, Warning, TEXT("Hit Actor Name: %s"), *HitResult.GetActor()->GetName());
outActor = HitResult.GetActor();
}
}
}
return outActor;
}
FVector UUISubsystem::ClickToWorldVector()
{
FVector outVector = FVector();
if (APlayerController* PC = UGameplayStatics::GetPlayerController(GetWorld(), 0))
{
float MouseX = 0.f;
float MouseY = 0.f;
if (PC->GetMousePosition(MouseX, MouseY))
{
FVector WorldLocation = FVector();
FVector WorldDirection = FVector();
if (PC->DeprojectScreenPositionToWorld(MouseX, MouseY, WorldLocation, WorldDirection))
{
FHitResult HitResult;
FVector TraceStart = WorldLocation;
FVector TraceEnd = TraceStart + (WorldDirection * 10000.0f);
FCollisionQueryParams Params;
FCollisionObjectQueryParams ObjectParams;
Params.AddIgnoredActor(PC);
//Replace with robot base class
if (IsValid(Robot)) Params.AddIgnoredActor(Robot);
ObjectParams.AddObjectTypesToQuery(ECC_WorldStatic);
bool bHit = GetWorld()->LineTraceSingleByObjectType(
HitResult,
TraceStart,
TraceEnd,
ObjectParams,
Params
);
//Leave in for debug trace
//DrawDebugLine(GetWorld(), TraceStart, TraceEnd, FColor::Green, false, 100.f, 0, 1.0f);
UE_LOG(LogTemp, Warning, TEXT("Vector Chosen: %s"), *HitResult.Location.ToString());
outVector = HitResult.Location;
DropZoneLocation = outVector;
}
}
}
return outVector;
}
void UUISubsystem::GenerateRandomObjects()
{
UE_LOG(LogTemp, Warning, TEXT("GeneratingRandomObjects"));
if (ClickedOnSurface != nullptr)
{
for (auto& Actor: SpawnedObjects)
{
if (IsValid(Actor)) Actor->Destroy();
}
int32 NumObjects = SimObjects.Num();
FVector Origin = FVector();
FVector Extent = FVector();
ClickedOnSurface->GetActorBounds(false, Origin, Extent);
TArray<FVector> Points;
int32 MaxAttempts = NumObjects * 10;
int32 Attempts = 0;
while (Points.Num() < NumObjects && Attempts < MaxAttempts)
{
FVector Candidate = Origin + FVector(
FMath::FRandRange(-Extent.X + 10.f, Extent.X - 10.f),
FMath::FRandRange(-Extent.Y + 10.f, Extent.Y - 10.f),
Extent.Z
);
bool bTooClose = false;
for (const FVector& Other : Points)
{
if (FVector::DistSquared(Candidate, Other) < FMath::Square(Extent.Y / 5))
{
bTooClose = true;
break;
}
}
if (!bTooClose)
{
Points.Add(Candidate);
}
Attempts++;
}
int32 Index = 0;
for (auto& Point : Points)
{
FActorSpawnParameters SpawnParams;
ALuckyObjectBase* Object = GetWorld()->SpawnActor<ALuckyObjectBase>(ALuckyObjectBase::StaticClass(), Point, FRotator(0.f, UKismetMathLibrary::RandomFloatInRange(0.f, 359.f), 0.f), SpawnParams);
SpawnedObjects.Add(Object);
if (UStaticMesh* Mesh = SimObjects[Index].LoadSynchronous())
{
Object->Mesh->SetStaticMesh(Mesh);
}
Index++;
}
}
}
void UUISubsystem::SetUpScene()
{
ULuckyRobotsGameInstance* GameInstance = Cast<ULuckyRobotsGameInstance>(GetGameInstance());
if (GameInstance && ClickedOnSurface)
{
FTrainingQueuedGoal Goal = FTrainingQueuedGoal();
TArray<FSelectableItemData> SelectableItemList = GameInstance->GetSelectableItemList(EItemCategory::TinyObjects);
SimObjects.Empty();
for (auto SelectableItem : SelectableItemList)
{
SimObjects.Add(SelectableItem.Mesh.LoadSynchronous());
}
GenerateRandomObjects();
Goal.TargetObject = SpawnedObjects[0];
FVector Origin = FVector();
FVector Extent = FVector();
ClickedOnSurface->GetActorBounds(false, Origin, Extent, false);
FVector RandomPoint = Origin + FVector(
FMath::FRandRange(Extent.X, Extent.X),
FMath::FRandRange(Extent.Y, Extent.Y),
Extent.Z
);
Goal.DropZoneLocation = RandomPoint;
if (ADirectionalLight* Light = Cast<ADirectionalLight>(UGameplayStatics::GetActorOfClass(GetWorld(), ADirectionalLight::StaticClass())))
{
Light->GetLightComponent()->SetIntensity(UKismetMathLibrary::RandomFloatInRange(2.f, 12.f));
Light->GetLightComponent()->SetUseTemperature(true);
Light->GetLightComponent()->SetTemperature(UKismetMathLibrary::RandomFloatInRange(2500.f, 12000.f));
}
}
}

View File

@ -19,7 +19,7 @@ void UAllRandomUserWidget::NativeConstruct()
UISubsystem->OnAllRandomMenuStateChanged.AddDynamic(this, &UAllRandomUserWidget::DoAllRandomMenuStateChanged);
}
DoUpdateItemList(EItemCategory::Furniture);
DoUpdateItemList(EItemCategory::TinyObjects);
}
void UAllRandomUserWidget::DoAllRandomMenuStateChanged(bool open)
@ -60,5 +60,5 @@ void UAllRandomUserWidget::DoUpdateItemList(EItemCategory ItemCategory)
void UAllRandomUserWidget::DoOpen()
{
DoUpdateItemList(EItemCategory::Furniture);
DoUpdateItemList(EItemCategory::TinyObjects);
}

View File

@ -10,6 +10,25 @@
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnMessageDispatched, const FString&, Message);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnRandomMeshesUpdated);
USTRUCT(BlueprintType)
struct FSceneSetupParameters
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool bAutoSetup = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FString SceneName = FString();
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FString RobotType = FString();
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FString Task = FString();
};
class USIOJsonValue;
class UGameUserWidget;
/**
@ -45,6 +64,9 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Config")
UDataTable* BathroomDataTable;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Config")
UDataTable* TinyObjectsDataTable;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Config")
TSubclassOf<AActor> TargetSelectorClass;
@ -331,4 +353,24 @@ public:
UFUNCTION(BlueprintPure)
EUnrealBuildType CheckBuildConfiguration() const;
UFUNCTION(BlueprintCallable)
void AutoSetUpScene();
UPROPERTY()
FString Headless = FString();
UPROPERTY()
FString Scene = FString();
UPROPERTY()
FString Objects = FString();
UPROPERTY()
FString NumObjects = FString();
UPROPERTY()
FSceneSetupParameters Params = FSceneSetupParameters();
void ParseIncomingStartParams();
void WaitForAutoSetup();
};

View File

@ -0,0 +1,25 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "LuckyLightTool.generated.h"
UCLASS()
class LUCKYWORLDV2_API ALuckyLightTool : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ALuckyLightTool();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};

View File

@ -0,0 +1,28 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "LuckyObjectBase.generated.h"
UCLASS()
class LUCKYWORLDV2_API ALuckyObjectBase : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ALuckyObjectBase();
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "LuckyObjectBase")
UStaticMeshComponent* Mesh = nullptr;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};

View File

@ -202,6 +202,7 @@ enum class EBathroom : uint8
UENUM(BlueprintType)
enum class EItemCategory : uint8
{
TinyObjects UMETA(DisplayName = "Tiny Objects"),
Furniture UMETA(DisplayName = "Furniture"),
Decoration UMETA(DisplayName = "Decoration"),
Kitchenware UMETA(DisplayName = "Kitchenware"),

View File

@ -0,0 +1,30 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Subsystems/WorldSubsystem.h"
#include "LuckySceneSubsystem.generated.h"
/**
*
*/
UCLASS()
class LUCKYWORLDV2_API ULuckySceneSubsystem : public UWorldSubsystem
{
GENERATED_BODY()
public:
ULuckySceneSubsystem();
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual void Deinitialize() override;
virtual void OnWorldBeginPlay(UWorld& InWorld) override;
};

View File

@ -4,6 +4,9 @@
#include "CoreMinimal.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "Blueprint/UserWidget.h"
#include "Components/VerticalBox.h"
#include "Components/ListView.h"
#include "UISubsystem.generated.h"
@ -18,6 +21,40 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAllRandomMenuStateChanged, bool,
/**
*
*/
USTRUCT(BlueprintType)
struct FTrainingQueuedGoal
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite)
FString Name = FString();
UPROPERTY(BlueprintReadWrite)
UObject* TargetObject = nullptr;
UPROPERTY(BlueprintReadWrite)
FVector TargetLocation = FVector();
UPROPERTY(BlueprintReadWrite)
UObject* DropZoneObject = nullptr;
UPROPERTY(BlueprintReadWrite)
FVector DropZoneLocation = FVector();
UPROPERTY(BlueprintReadWrite)
int32 GoalIndex = 0;
};
UENUM(BlueprintType)
enum class EUISelectionType : uint8
{
Target UMETA(DisplayName = "Target"),
Surface UMETA(DisplayName = "Surface"),
DropZone UMETA(DisplayName = "DropZone")
};
UCLASS()
class LUCKYWORLDV2_API UUISubsystem : public UGameInstanceSubsystem
{
@ -44,4 +81,71 @@ public:
UPROPERTY(BlueprintCallable, BlueprintAssignable)
FOnAllRandomMenuStateChanged OnAllRandomMenuStateChanged;
UPROPERTY(BlueprintReadWrite)
UVerticalBox* GoalList = nullptr;
UPROPERTY(BlueprintReadWrite)
UVerticalBox* CameraList = nullptr;
UPROPERTY(BlueprintReadWrite)
UVerticalBox* ObjectsList = nullptr;
UPROPERTY(BlueprintReadWrite)
UVerticalBox* LightsList = nullptr;
UPROPERTY(BlueprintReadWrite)
EUISelectionType UISelectionType;
UPROPERTY(BlueprintReadWrite)
UUserWidget* CurrentSettings = nullptr;
UPROPERTY(BlueprintReadWrite)
TArray<FTrainingQueuedGoal> QueuedGoals = TArray<FTrainingQueuedGoal>();
UFUNCTION(BlueprintCallable)
UUserWidget* OpenSettingsMenu(TSubclassOf<UUserWidget> InWidget);
UPROPERTY(BlueprintReadWrite)
FString LastSelectedObject = FString();
UPROPERTY(BlueprintReadWrite)
AActor* ClickedOnTarget = nullptr;
UPROPERTY(BlueprintReadWrite)
AActor* ClickedOnSurface = nullptr;
UPROPERTY(BlueprintReadWrite)
AActor* ClickedOnDropZone = nullptr;
UPROPERTY(BlueprintReadWrite)
FVector DropZoneLocation = FVector();
UPROPERTY(BlueprintReadWrite)
TArray<FString> ObjectsToSpawn = TArray<FString>();
UPROPERTY(BlueprintReadWrite)
TArray<TSoftObjectPtr<UStaticMesh>> SimObjects = TArray<TSoftObjectPtr<UStaticMesh>>();
UPROPERTY(BlueprintReadWrite)
TArray<AActor*> SpawnedObjects = TArray<AActor*>();
UPROPERTY(BlueprintReadWrite)
bool bIsTargetObject = false;
UPROPERTY(BlueprintReadWrite)
AActor* Robot = nullptr;
UFUNCTION(BlueprintCallable)
AActor* ClickOnActor();
UFUNCTION(BlueprintCallable)
FVector ClickToWorldVector();
UFUNCTION(BlueprintCallable)
void GenerateRandomObjects();
UFUNCTION(BlueprintCallable)
void SetUpScene();
};