Compare commits

..

2 Commits

Author SHA1 Message Date
0ad6c21aa7 Mujoco.class.component 2025-04-25 23:32:32 +03:00
0ebe0cbfc0 volume error 2025-04-25 17:14:15 +03:00
40 changed files with 493 additions and 493 deletions

Binary file not shown.

View File

@ -1,7 +0,0 @@
{
"BuildId": "37670630",
"Modules":
{
"LuckyDataTransfer": "UnrealEditor-LuckyDataTransfer.dll"
}
}

View File

@ -1,23 +0,0 @@
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "LuckyDataTransfer",
"Description": "Lucky data transfer that transfers data with great luck.",
"Category": "Other",
"CreatedBy": "Noah Bowers",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"CanContainContent": true,
"IsBetaVersion": false,
"IsExperimentalVersion": false,
"Installed": false,
"Modules": [
{
"Name": "LuckyDataTransfer",
"Type": "Runtime",
"LoadingPhase": "Default"
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,57 +0,0 @@
// Copyright Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class LuckyDataTransfer : ModuleRules
{
public LuckyDataTransfer(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PublicIncludePaths.AddRange(
new string[] {
// ... add public include paths required here ...
}
);
PrivateIncludePaths.AddRange(
new string[] {
// ... add other private include paths required here ...
}
);
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
"WebSockets",
"Json",
"JsonUtilities",
"ImageWriteQueue"
// ... add other public dependencies that you statically link with here ...
}
);
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"Engine",
"Slate",
"SlateCore", "ImageWriteQueue",
// ... add private dependencies that you statically link with here ...
}
);
DynamicallyLoadedModuleNames.AddRange(
new string[]
{
// ... add any modules that your module loads dynamically here ...
}
);
}
}

View File

@ -1,20 +0,0 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "LuckyDataTransfer.h"
#define LOCTEXT_NAMESPACE "FLuckyDataTransferModule"
void FLuckyDataTransferModule::StartupModule()
{
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
}
void FLuckyDataTransferModule::ShutdownModule()
{
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
// we call this function before unloading the module.
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FLuckyDataTransferModule, LuckyDataTransfer)

View File

@ -1,153 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "LuckyDataTransferSubsystem.h"
#include "JsonUtilities.h"
#include "JsonObjectConverter.h"
#include "WebSocketsModule.h"
#include "Slate/SceneViewport.h"
ULuckyDataTransferSubsystem::ULuckyDataTransferSubsystem()
{
}
void ULuckyDataTransferSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
Super::Initialize(Collection);
}
void ULuckyDataTransferSubsystem::Deinitialize()
{
Super::Deinitialize();
if (Socket.IsValid() && Socket->IsConnected())
{
Socket->Close();
}
}
void ULuckyDataTransferSubsystem::Internal_OpenWebsocket(const FString& URL, const FString& Protocol)
{
const FString NewUrl = URL.IsEmpty() ? TEXT("ws://127.0.0.1:3000/ws") : URL;
const FString NewProtocol = Protocol.IsEmpty() ? TEXT("ws") : Protocol;
UE_LOG(LogTemp, Warning, TEXT("Opening WebSocket URL: %s"), *NewUrl);
if (!FModuleManager::Get().IsModuleLoaded("WebSockets"))
{
FModuleManager::Get().LoadModule("WebSockets");
}
Socket = FWebSocketsModule::Get().CreateWebSocket(NewUrl);
Socket->Connect();
//Set up callbacks
Socket->OnConnectionError().AddUObject(this, &ULuckyDataTransferSubsystem::Callback_OnConnectionError);
Socket->OnConnected().AddUObject(this, &ULuckyDataTransferSubsystem::Callback_OnConnected);
Socket->OnMessage().AddUObject(this, &ULuckyDataTransferSubsystem::Callback_OnMessage);
}
//Callbacks
void ULuckyDataTransferSubsystem::Callback_OnConnected()
{
if (OnSocketReady.IsBound())
{
OnSocketReady.Broadcast(true);
UE_LOG(LogTemp, VeryVerbose, TEXT("WebSocket connected successfully"));
}
}
void ULuckyDataTransferSubsystem::Callback_OnConnectionError(const FString& Error)
{
UE_LOG(LogTemp, VeryVerbose, TEXT("Websocket connection error: %s"), *Error)
}
void ULuckyDataTransferSubsystem::Callback_OnMessage(const FString& Message)
{
if (!Message.IsEmpty())
{
CommandReady(InterpretData(Message));
return;
}
UE_LOG(LogTemp, Warning, TEXT("The message received from the websocket is invalid"));
}
void ULuckyDataTransferSubsystem::Internal_OnMessageSent(const FString& Message)
{
}
void ULuckyDataTransferSubsystem::Callback_OnConnectionClosed()
{
}
//Blueprint Exposed Implementation
void ULuckyDataTransferSubsystem::ConnectToWebsocket(const FString& URL, const FString& Protocol)
{
Internal_OpenWebsocket(URL, Protocol);
}
void ULuckyDataTransferSubsystem::SendMessage(const FString& Message)
{
if (Socket.IsValid() && Socket->IsConnected())
{
Socket->Send(Message);
return;
}
UE_LOG(LogTemp, Warning, TEXT("WebSocket outgoing message failed"));
}
FPayload ULuckyDataTransferSubsystem::InterpretData(const FString& Message)
{
FPayload Payload = FPayload();
if (!Message.IsEmpty())
{
TSharedPtr<FJsonObject> JsonObj;
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Message);
if (FJsonSerializer::Deserialize(Reader, JsonObj) && JsonObj.IsValid())
{
for (auto& Elem : JsonObj->Values)
{
FCommand Command = FCommand();
Command.Key = FString(Elem.Key);
Command.Value = Elem.Value->AsNumber();
Payload.Commands.Add(Command);
}
}
}
return Payload;
}
void ULuckyDataTransferSubsystem::CommandReady(const FPayload& Payload)
{
if (OnCommandReady.IsBound())
{
OnCommandReady.Broadcast(Payload);
}
}
//Blueprint Callable function - Use CreateJsonPayload_Observation in C++
bool ULuckyDataTransferSubsystem::MakeObservationPayload(const FObservationPayload& Data)
{
return CreateJsonPayload_Observation(Data);
}
bool ULuckyDataTransferSubsystem::CreateJsonPayload_Observation(const FObservationPayload& Data)
{
bool bSuccess = false;
ObservationPayloadString = FString();
if (!Data.ObservationState.IsEmpty())
{
FJsonObjectConverter::UStructToJsonObjectString(Data, ObservationPayloadString);
UE_LOG(LogTemp, Warning, TEXT("Payload observation: %s"), *ObservationPayloadString);
bSuccess = true;
}
return bSuccess;
}

View File

@ -1,14 +0,0 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Modules/ModuleManager.h"
class FLuckyDataTransferModule : public IModuleInterface
{
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};

View File

@ -1,113 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "IWebSocket.h"
//#include "LuckyWriteThread.h"
#include "ObservationData.h"
#include "Subsystems/WorldSubsystem.h"
#include "LuckyDataTransferSubsystem.generated.h"
/**
*
*/
USTRUCT(BlueprintType)
struct FCommand
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly, Category = "Command")
FString Key = FString();
UPROPERTY(BlueprintReadOnly, Category = "Command")
float Value = 0.f;
};
USTRUCT(BlueprintType)
struct FPayload
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly, Category = "Command")
TArray<FCommand> Commands;
UPROPERTY(BlueprintReadOnly, Category = "Command")
int32 Index = 0;
};
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCommandReady, const FPayload&, Payload);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSocketReady, bool, bSuccessful);
UCLASS()
class LUCKYDATATRANSFER_API ULuckyDataTransferSubsystem : public UWorldSubsystem
{
GENERATED_BODY()
public:
ULuckyDataTransferSubsystem();
virtual void Initialize(FSubsystemCollectionBase& Collection);
virtual void Deinitialize();
TSharedPtr<IWebSocket> Socket;
//internal references
void Internal_OpenWebsocket(const FString& URL, const FString& Protocol);
FPayload InterpretData(const FString& Message);
UPROPERTY(BlueprintAssignable)
FCommandReady OnCommandReady;
UPROPERTY(BlueprintAssignable)
FSocketReady OnSocketReady;
//Callbacks
UFUNCTION()
void Callback_OnConnected();
UFUNCTION()
void Callback_OnConnectionError(const FString& Error);
UFUNCTION()
void Callback_OnMessage(const FString& Message);
UFUNCTION()
void Internal_OnMessageSent(const FString& Message);
UFUNCTION()
void Callback_OnConnectionClosed();
//Exposed Blueprint Functions
UFUNCTION(BlueprintCallable, Category = "Websocket")
void ConnectToWebsocket(const FString& URL, const FString& Protocol);
UFUNCTION(BlueprintCallable, Category = "Websocket")
void SendMessage(const FString& Message);
UFUNCTION()
void CommandReady(const FPayload& Payload);
//---Observations (Sent to server from Unreal)--------------//
//Feature Data declarations
UPROPERTY(BlueprintReadWrite, Category = "Observation")
FString ObservationPayloadString = FString();
//Internal Functions
bool CreateJsonPayload_Observation(const FObservationPayload& Data);
//Blueprint Callable Functions
UFUNCTION(BlueprintCallable, Category = "Websocket")
bool MakeObservationPayload(const FObservationPayload& Data);
//---------------------------------------------------------//
protected:
//LuckyWriteThread* WriteThread = nullptr;
};

View File

@ -1,80 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "HAL/Runnable.h"
#include "ObservationData.generated.h"
/**
*
*/
USTRUCT(BlueprintType)
struct FImageShape
{
GENERATED_USTRUCT_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Observation")
float image_width = 640.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Observation")
float image_height = 480.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Observation")
int32 channel = 3;
};
USTRUCT(BlueprintType)
struct FObservationCameraInfo
{
GENERATED_USTRUCT_BODY()
public:
UPROPERTY(BlueprintReadWrite, Category = "Observation")
TMap<FString, FString> info = {
{"video_fps", "30"},
{"video_codec", "mp4v"},
{"video_pix_fmt", "yuv420p"},
{"video_is_depth_map", "false"},
{"has_audio", "false"}
};
};
USTRUCT(BlueprintType)
struct FObservationCameraObject
{
GENERATED_USTRUCT_BODY()
public:
UPROPERTY(BlueprintReadWrite, Category = "Observation")
FString cameraName = TEXT("front_camera");
UPROPERTY(BlueprintReadWrite, Category = "Observation")
FString dtype = TEXT("image");
UPROPERTY(BlueprintReadWrite, Category = "Observation")
FImageShape shape = FImageShape();
UPROPERTY(BlueprintReadWrite, Category = "Observation")
FString filePath = FString();
};
USTRUCT(BlueprintType)
struct FObservationPayload
{
GENERATED_USTRUCT_BODY()
public:
UPROPERTY(BlueprintReadWrite, Category = "Observation")
FString timeStamp = FString();
UPROPERTY(BlueprintReadWrite, Category = "Observation")
FString id = FString();
UPROPERTY(BlueprintReadWrite, Category = "Observation")
TMap<FString, float> ObservationState;
UPROPERTY(BlueprintReadWrite, Category = "Observation")
TArray<FObservationCameraObject> ObservationCameras;
};

View File

@ -1,14 +1,88 @@
#include "Components/MujocoActuatorComponent.h" #include "Components/MujocoActuatorComponent.h"
#include "Components/MujocoClassComponent.h"
UMujocoActuatorComponent::UMujocoActuatorComponent() UMujocoActuatorComponent::UMujocoActuatorComponent()
{ {
PrimaryComponentTick.bCanEverTick = false; PrimaryComponentTick.bCanEverTick = false;
ClassComponent = nullptr;
}
void UMujocoActuatorComponent::BeginPlay()
{
Super::BeginPlay();
// Try to find class component in owner if not set
if (!ClassComponent)
{
if (AActor* Owner = GetOwner())
{
ClassComponent = Owner->FindComponentByClass<UMujocoClassComponent>();
}
}
}
void UMujocoActuatorComponent::OnRegister()
{
Super::OnRegister();
// Try to find class component in owner during component registration
if (!ClassComponent)
{
if (AActor* Owner = GetOwner())
{
ClassComponent = Owner->FindComponentByClass<UMujocoClassComponent>();
}
}
}
void UMujocoActuatorComponent::SetClassComponent(UMujocoClassComponent* NewClassComponent)
{
if (NewClassComponent != ClassComponent)
{
// Remove from old class component if exists
if (ClassComponent)
{
ClassComponent->RemoveAssociatedComponent(this);
}
ClassComponent = NewClassComponent;
// Add to new class component if valid
if (ClassComponent)
{
ClassComponent->AddAssociatedComponent(this);
}
}
}
FString UMujocoActuatorComponent::GetClassParameter(const FString& ParamName) const
{
if (ClassComponent && ClassComponent->ClassData.Parameters.Contains(ParamName))
{
return *ClassComponent->ClassData.Parameters.Find(ParamName);
}
return FString();
}
bool UMujocoActuatorComponent::HasClassComponent() const
{
return ClassComponent != nullptr;
} }
#if WITH_EDITORONLY_DATA #if WITH_EDITORONLY_DATA
void UMujocoActuatorComponent::OnComponentCreated() void UMujocoActuatorComponent::OnComponentCreated()
{ {
Super::OnComponentCreated(); Super::OnComponentCreated();
// Try to find class component in owner during creation
if (!ClassComponent)
{
if (AActor* Owner = GetOwner())
{
ClassComponent = Owner->FindComponentByClass<UMujocoClassComponent>();
}
}
if (GEngine && GetWorld()) if (GEngine && GetWorld())
{ {
FString UniqueName = GenerateUniqueName(GetWorld(), this, GetName()); FString UniqueName = GenerateUniqueName(GetWorld(), this, GetName());
@ -19,6 +93,18 @@ void UMujocoActuatorComponent::OnComponentCreated()
void UMujocoActuatorComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) void UMujocoActuatorComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{ {
Super::PostEditChangeProperty(PropertyChangedEvent); Super::PostEditChangeProperty(PropertyChangedEvent);
const FName PropertyName = (PropertyChangedEvent.Property != nullptr) ? PropertyChangedEvent.Property->GetFName() : NAME_None;
if (PropertyName == GET_MEMBER_NAME_CHECKED(UMujocoActuatorComponent, ClassComponent))
{
// Update associations when class component is changed in editor
if (ClassComponent)
{
ClassComponent->AddAssociatedComponent(this);
}
}
if (GEngine && GetWorld()) if (GEngine && GetWorld())
{ {
FString UniqueName = GenerateUniqueName(GetWorld(), this, GetName()); FString UniqueName = GenerateUniqueName(GetWorld(), this, GetName());

View File

@ -0,0 +1,130 @@
#include "Components/MujocoClassComponent.h"
#include "Components/MujocoJointComponent.h"
#include "Components/MujocoActuatorComponent.h"
UMujocoClassComponent::UMujocoClassComponent()
{
PrimaryComponentTick.bCanEverTick = false;
JointComponent = nullptr;
ActuatorComponent = nullptr;
}
void UMujocoClassComponent::AddAssociatedComponent(UActorComponent* Component)
{
if (Component)
{
AssociatedComponents.AddUnique(Component);
// Also update single references if applicable
if (UMujocoJointComponent* JointComp = Cast<UMujocoJointComponent>(Component))
{
SetJointComponent(JointComp);
}
else if (UMujocoActuatorComponent* ActuatorComp = Cast<UMujocoActuatorComponent>(Component))
{
SetActuatorComponent(ActuatorComp);
}
}
}
void UMujocoClassComponent::RemoveAssociatedComponent(UActorComponent* Component)
{
if (Component)
{
AssociatedComponents.Remove(Component);
// Also update single references if applicable
if (UMujocoJointComponent* JointComp = Cast<UMujocoJointComponent>(Component))
{
if (JointComponent == JointComp)
{
JointComponent = nullptr;
}
}
else if (UMujocoActuatorComponent* ActuatorComp = Cast<UMujocoActuatorComponent>(Component))
{
if (ActuatorComponent == ActuatorComp)
{
ActuatorComponent = nullptr;
}
}
}
}
void UMujocoClassComponent::SetClassParameter(const FString& ParamName, const FString& ParamValue)
{
ClassData.Parameters.Add(ParamName, ParamValue);
}
void UMujocoClassComponent::SetJointComponent(UMujocoJointComponent* NewJointComponent)
{
if (NewJointComponent != JointComponent)
{
// Remove old joint if exists
if (JointComponent)
{
RemoveAssociatedComponent(JointComponent);
}
JointComponent = NewJointComponent;
ClassData.ClassType = EMujocoClassType::Joint;
// Add to associated components if valid
if (JointComponent)
{
AssociatedComponents.AddUnique(JointComponent);
JointComponent->SetClassComponent(this);
}
}
}
void UMujocoClassComponent::SetActuatorComponent(UMujocoActuatorComponent* NewActuatorComponent)
{
if (NewActuatorComponent != ActuatorComponent)
{
// Remove old actuator if exists
if (ActuatorComponent)
{
RemoveAssociatedComponent(ActuatorComponent);
}
ActuatorComponent = NewActuatorComponent;
ClassData.ClassType = EMujocoClassType::Actuator;
// Add to associated components if valid
if (ActuatorComponent)
{
AssociatedComponents.AddUnique(ActuatorComponent);
ActuatorComponent->SetClassComponent(this);
}
}
}
#if WITH_EDITORONLY_DATA
void UMujocoClassComponent::OnComponentCreated()
{
Super::OnComponentCreated();
}
void UMujocoClassComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
const FName PropertyName = (PropertyChangedEvent.Property != nullptr) ? PropertyChangedEvent.Property->GetFName() : NAME_None;
if (PropertyName == GET_MEMBER_NAME_CHECKED(UMujocoClassComponent, JointComponent))
{
if (JointComponent)
{
SetJointComponent(JointComponent);
}
}
else if (PropertyName == GET_MEMBER_NAME_CHECKED(UMujocoClassComponent, ActuatorComponent))
{
if (ActuatorComponent)
{
SetActuatorComponent(ActuatorComponent);
}
}
}
#endif

View File

@ -1,15 +1,89 @@
#include "Components/MujocoJointComponent.h" #include "Components/MujocoJointComponent.h"
#include "Components/MujocoBodyComponent.h" #include "Components/MujocoBodyComponent.h"
#include "Components/MujocoClassComponent.h"
UMujocoJointComponent::UMujocoJointComponent() UMujocoJointComponent::UMujocoJointComponent()
{ {
PrimaryComponentTick.bCanEverTick = false; PrimaryComponentTick.bCanEverTick = false;
ClassComponent = nullptr;
}
void UMujocoJointComponent::BeginPlay()
{
Super::BeginPlay();
// Try to find class component in owner if not set
if (!ClassComponent)
{
if (AActor* Owner = GetOwner())
{
ClassComponent = Owner->FindComponentByClass<UMujocoClassComponent>();
}
}
}
void UMujocoJointComponent::OnRegister()
{
Super::OnRegister();
// Try to find class component in owner during component registration
if (!ClassComponent)
{
if (AActor* Owner = GetOwner())
{
ClassComponent = Owner->FindComponentByClass<UMujocoClassComponent>();
}
}
}
void UMujocoJointComponent::SetClassComponent(UMujocoClassComponent* NewClassComponent)
{
if (NewClassComponent != ClassComponent)
{
// Remove from old class component if exists
if (ClassComponent)
{
ClassComponent->RemoveAssociatedComponent(this);
}
ClassComponent = NewClassComponent;
// Add to new class component if valid
if (ClassComponent)
{
ClassComponent->AddAssociatedComponent(this);
}
}
}
FString UMujocoJointComponent::GetClassParameter(const FString& ParamName) const
{
if (ClassComponent && ClassComponent->ClassData.Parameters.Contains(ParamName))
{
return *ClassComponent->ClassData.Parameters.Find(ParamName);
}
return FString();
}
bool UMujocoJointComponent::HasClassComponent() const
{
return ClassComponent != nullptr;
} }
#if WITH_EDITORONLY_DATA #if WITH_EDITORONLY_DATA
void UMujocoJointComponent::OnComponentCreated() void UMujocoJointComponent::OnComponentCreated()
{ {
Super::OnComponentCreated(); Super::OnComponentCreated();
// Try to find class component in owner during creation
if (!ClassComponent)
{
if (AActor* Owner = GetOwner())
{
ClassComponent = Owner->FindComponentByClass<UMujocoClassComponent>();
}
}
if (GEngine && GetWorld()) if (GEngine && GetWorld())
{ {
if (UMujocoBodyComponent* ParentBody = Cast<UMujocoBodyComponent>(GetAttachParent())) if (UMujocoBodyComponent* ParentBody = Cast<UMujocoBodyComponent>(GetAttachParent()))
@ -29,6 +103,18 @@ void UMujocoJointComponent::OnComponentCreated()
void UMujocoJointComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) void UMujocoJointComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{ {
Super::PostEditChangeProperty(PropertyChangedEvent); Super::PostEditChangeProperty(PropertyChangedEvent);
const FName PropertyName = (PropertyChangedEvent.Property != nullptr) ? PropertyChangedEvent.Property->GetFName() : NAME_None;
if (PropertyName == GET_MEMBER_NAME_CHECKED(UMujocoJointComponent, ClassComponent))
{
// Update associations when class component is changed in editor
if (ClassComponent)
{
ClassComponent->AddAssociatedComponent(this);
}
}
if (GEngine && GetWorld()) if (GEngine && GetWorld())
{ {
FString UniqueName = GenerateUniqueName(GetWorld(), this, GetName()); FString UniqueName = GenerateUniqueName(GetWorld(), this, GetName());

View File

@ -4,6 +4,7 @@
#include "Enums/MujocoEnums.h" #include "Enums/MujocoEnums.h"
#include "Structs/MujocoActuator.h" #include "Structs/MujocoActuator.h"
#include "Misc/UniqueNamedComponent.h" #include "Misc/UniqueNamedComponent.h"
#include "Components/MujocoClassComponent.h"
#include "MujocoActuatorComponent.generated.h" #include "MujocoActuatorComponent.generated.h"
UCLASS(Blueprintable, ClassGroup = (Rendering, Common), hidecategories = (Object, Activation, "Components|Activation"), ShowCategories = (Mobility), editinlinenew, meta = (BlueprintSpawnableComponent)) UCLASS(Blueprintable, ClassGroup = (Rendering, Common), hidecategories = (Object, Activation, "Components|Activation"), ShowCategories = (Mobility), editinlinenew, meta = (BlueprintSpawnableComponent))
@ -20,8 +21,30 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mujoco") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mujoco")
FMujocoActuatorV2 Actuator; FMujocoActuatorV2 Actuator;
// Reference to the class component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mujoco", meta = (AllowPrivateAccess = "true"))
TObjectPtr<UMujocoClassComponent> ClassComponent;
// Function to set class component
UFUNCTION(BlueprintCallable, Category = "Mujoco")
void SetClassComponent(UMujocoClassComponent* NewClassComponent);
// Function to get class parameters
UFUNCTION(BlueprintCallable, Category = "Mujoco")
FString GetClassParameter(const FString& ParamName) const;
// Function to check if has class component
UFUNCTION(BlueprintCallable, Category = "Mujoco")
bool HasClassComponent() const;
#if WITH_EDITORONLY_DATA #if WITH_EDITORONLY_DATA
virtual void OnComponentCreated() override; virtual void OnComponentCreated() override;
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif #endif
protected:
virtual void BeginPlay() override;
// Called when the game starts or when spawned
virtual void OnRegister() override;
}; };

View File

@ -0,0 +1,94 @@
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Enums/MujocoEnums.h"
#include "Misc/UniqueNamedComponent.h"
#include "MujocoClassComponent.generated.h"
UENUM(BlueprintType)
enum class EMujocoClassType : uint8
{
None UMETA(DisplayName = "None"),
Joint UMETA(DisplayName = "Joint"),
Actuator UMETA(DisplayName = "Actuator")
};
USTRUCT(BlueprintType)
struct FMujocoClassData
{
GENERATED_BODY()
// Class name for the Mujoco element
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mujoco")
FString ClassName;
// Type of the class
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mujoco")
EMujocoClassType ClassType = EMujocoClassType::None;
// Additional class-specific parameters can be added here
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mujoco")
TMap<FString, FString> Parameters;
};
UCLASS(Blueprintable, ClassGroup = (Mujoco), meta = (BlueprintSpawnableComponent))
class LUCKYMUJOCO_API UMujocoClassComponent : public UActorComponent, public TUniqueNamedComponent
{
GENERATED_BODY()
public:
UMujocoClassComponent();
UPROPERTY(Transient, VisibleAnywhere, Category = "Mujoco")
int32 MujocoID = -1;
// Class data for the Mujoco element
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mujoco")
FMujocoClassData ClassData;
// Reference to associated components (joints, actuators, etc.)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mujoco")
TArray<UActorComponent*> AssociatedComponents;
// Single reference to a joint component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mujoco")
TObjectPtr<class UMujocoJointComponent> JointComponent;
// Single reference to an actuator component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mujoco")
TObjectPtr<class UMujocoActuatorComponent> ActuatorComponent;
#if WITH_EDITORONLY_DATA
virtual void OnComponentCreated() override;
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
// Function to add associated components
UFUNCTION(BlueprintCallable, Category = "Mujoco")
void AddAssociatedComponent(UActorComponent* Component);
// Function to remove associated components
UFUNCTION(BlueprintCallable, Category = "Mujoco")
void RemoveAssociatedComponent(UActorComponent* Component);
// Function to set class parameters
UFUNCTION(BlueprintCallable, Category = "Mujoco")
void SetClassParameter(const FString& ParamName, const FString& ParamValue);
// Function to set single joint component
UFUNCTION(BlueprintCallable, Category = "Mujoco")
void SetJointComponent(class UMujocoJointComponent* NewJointComponent);
// Function to set single actuator component
UFUNCTION(BlueprintCallable, Category = "Mujoco")
void SetActuatorComponent(class UMujocoActuatorComponent* NewActuatorComponent);
// Function to get single joint component
UFUNCTION(BlueprintCallable, Category = "Mujoco")
class UMujocoJointComponent* GetJointComponent() const { return JointComponent; }
// Function to get single actuator component
UFUNCTION(BlueprintCallable, Category = "Mujoco")
class UMujocoActuatorComponent* GetActuatorComponent() const { return ActuatorComponent; }
};

View File

@ -5,6 +5,7 @@
#include "Components/SceneComponent.h" #include "Components/SceneComponent.h"
#include "Structs/MujocoJoint.h" #include "Structs/MujocoJoint.h"
#include "Misc/UniqueNamedComponent.h" #include "Misc/UniqueNamedComponent.h"
#include "Components/MujocoClassComponent.h"
#include "MujocoJointComponent.generated.h" #include "MujocoJointComponent.generated.h"
UCLASS(Blueprintable, ClassGroup = (Rendering, Common), hidecategories = (Object, Activation, "Components|Activation"), editinlinenew, meta = (BlueprintSpawnableComponent)) UCLASS(Blueprintable, ClassGroup = (Rendering, Common), hidecategories = (Object, Activation, "Components|Activation"), editinlinenew, meta = (BlueprintSpawnableComponent))
@ -21,8 +22,30 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mujoco") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mujoco")
FMujocoJoint Joint; FMujocoJoint Joint;
// Reference to the class component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mujoco", meta = (AllowPrivateAccess = "true"))
TObjectPtr<UMujocoClassComponent> ClassComponent;
// Function to set class component
UFUNCTION(BlueprintCallable, Category = "Mujoco")
void SetClassComponent(UMujocoClassComponent* NewClassComponent);
// Function to get class parameters
UFUNCTION(BlueprintCallable, Category = "Mujoco")
FString GetClassParameter(const FString& ParamName) const;
// Function to check if has class component
UFUNCTION(BlueprintCallable, Category = "Mujoco")
bool HasClassComponent() const;
#if WITH_EDITORONLY_DATA #if WITH_EDITORONLY_DATA
virtual void OnComponentCreated() override; virtual void OnComponentCreated() override;
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif #endif
protected:
virtual void BeginPlay() override;
// Called when the game starts or when spawned
virtual void OnRegister() override;
}; };

View File

@ -1,4 +1,4 @@
// Fill out your copyright notice in the Description page of Project Settings. // Fill out your copyright notice in the Description page of Project Settings.
#include "Core/LuckyRobotsGameInstance.h" #include "Core/LuckyRobotsGameInstance.h"
@ -663,6 +663,30 @@ void ULuckyRobotsGameInstance::SetLuckyRobot(FString RobotName)
UE_LOG(LogTemp, Error, TEXT("Invalid robot name: %s"), *RobotName); UE_LOG(LogTemp, Error, TEXT("Invalid robot name: %s"), *RobotName);
} }
} }
void ULuckyRobotsGameInstance::LuckyLevelOpen(FString LevelName)
{
if (LevelName.IsEmpty())
{
UE_LOG(LogTemp, Warning, TEXT("Level name is empty!"));
return;
}
// Level opening logic
if (UWorld* World = GetWorld())
{
FName LevelFName(*LevelName);
if (FPackageName::DoesPackageExist(LevelName))
{
UGameplayStatics::OpenLevel(World, FName(*LevelName));
UE_LOG(LogTemp, Log, TEXT("Opening level: %s"), *LevelName);
}
else
{
UE_LOG(LogTemp, Error, TEXT("Level '%s' does not exist!"), *LevelName);
}
}
}
void ULuckyRobotsGameInstance::LuckyRobots() void ULuckyRobotsGameInstance::LuckyRobots()
{ {
UEnum* EnumPtr = StaticEnum<ERobotsName>(); UEnum* EnumPtr = StaticEnum<ERobotsName>();
@ -674,7 +698,7 @@ void ULuckyRobotsGameInstance::LuckyRobots()
Name = Name.Replace(TEXT("ERobotsName::"), TEXT("")); Name = Name.Replace(TEXT("ERobotsName::"), TEXT(""));
GameUserWidget->DoLogItemAdd("Robot:", Name, ELogItemType::Consol); GameUserWidget->DoLogItemAdd("Robot:", Name, ELogItemType::Consol);
UE_LOG(LogTemp, Display, TEXT("Robot: %s"), *Name); UE_LOG(LogTemp, Display, TEXT("Robot: %s"), *Name);
if (GEngine) if (EUnrealBuildType::Development == CheckBuildConfiguration())
{ {
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, FString::Printf(TEXT("Robot selected: %s"), *Name)); GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, FString::Printf(TEXT("Robot selected: %s"), *Name));
} }

View File

@ -327,7 +327,8 @@ public:
void SetLuckyRobot(FString RobotName); void SetLuckyRobot(FString RobotName);
UFUNCTION(exec) UFUNCTION(exec)
void LuckyRobots(); void LuckyRobots();
UFUNCTION(Exec)
void LuckyLevelOpen(FString LevelName);
UFUNCTION(BlueprintPure) UFUNCTION(BlueprintPure)
EUnrealBuildType CheckBuildConfiguration() const; EUnrealBuildType CheckBuildConfiguration() const;