diff --git a/OSC/Source/OSC/Private/Common/OscDataElemStruct.h b/OSC/Source/OSC/Private/Common/OscDataElemStruct.h index c871d46..ffdfaf8 100644 --- a/OSC/Source/OSC/Private/Common/OscDataElemStruct.h +++ b/OSC/Source/OSC/Private/Common/OscDataElemStruct.h @@ -92,14 +92,9 @@ struct FOscDataElemStruct void SetString(FName value) { -#if OSC_ENGINE_VERSION < 40500 - static_assert(sizeof(value) <= sizeof(Data), "Too short to hold the string value."); - Data = *reinterpret_cast(&value); -#else static_assert(sizeof(FMinimalName) <= sizeof(Data), "Too short to hold the string value."); const auto mininal = NameToMinimalName(value); Data = *reinterpret_cast(&mininal); -#endif Type = STRING; check(value == AsStringValue()); } @@ -107,11 +102,7 @@ struct FOscDataElemStruct FName AsStringValue() const { check(IsString()); -#if OSC_ENGINE_VERSION < 40500 - return *reinterpret_cast(&Data); -#else return MinimalNameToName(*reinterpret_cast(&Data)); -#endif } bool IsString() const diff --git a/OSC/Source/OSC/Private/Common/OscFunctionLibrary.cpp b/OSC/Source/OSC/Private/Common/OscFunctionLibrary.cpp index 7528e4c..8b40634 100644 --- a/OSC/Source/OSC/Private/Common/OscFunctionLibrary.cpp +++ b/OSC/Source/OSC/Private/Common/OscFunctionLibrary.cpp @@ -4,11 +4,6 @@ #include "oscpack/osc/OscOutboundPacketStream.h" -UOscFunctionLibrary::UOscFunctionLibrary(const class FPostConstructInitializeProperties& PCIP) - : Super(PCIP) -{ -} - template static inline void PopValueImpl(const TArray & input, TArray & output, T & Value) diff --git a/OSC/Source/OSC/Private/Common/OscFunctionLibrary.h b/OSC/Source/OSC/Private/Common/OscFunctionLibrary.h index 1e533a0..759c23d 100644 --- a/OSC/Source/OSC/Private/Common/OscFunctionLibrary.h +++ b/OSC/Source/OSC/Private/Common/OscFunctionLibrary.h @@ -7,7 +7,9 @@ UCLASS() class UOscFunctionLibrary : public UBlueprintFunctionLibrary { - GENERATED_UCLASS_BODY() + GENERATED_BODY() + +public: /// Get the next value from an OSC message as a boolean. UFUNCTION(BlueprintPure, Category=OSC) diff --git a/OSC/Source/OSC/Private/Osc.h b/OSC/Source/OSC/Private/Osc.h index 02a5cf9..ad0037c 100644 --- a/OSC/Source/OSC/Private/Osc.h +++ b/OSC/Source/OSC/Private/Osc.h @@ -2,7 +2,7 @@ // Target engine version. Used to enable compatibility code. -#define OSC_ENGINE_VERSION 40700 +#define OSC_ENGINE_VERSION 40800 #ifndef OSC_EDITOR_BUILD #error OSC_EDITOR_BUILD must be set by the OSC.Build.cs diff --git a/OSC/Source/OSC/Private/OscModule.cpp b/OSC/Source/OSC/Private/OscModule.cpp index 924fb79..86f3c7c 100644 --- a/OSC/Source/OSC/Private/OscModule.cpp +++ b/OSC/Source/OSC/Private/OscModule.cpp @@ -32,24 +32,9 @@ public: HandleSettingsSaved(); // register settings -#if OSC_ENGINE_VERSION < 40600 - auto settingsModule = ISettingsModule::Get(); -#else auto settingsModule = FModuleManager::GetModulePtr("Settings"); -#endif if(settingsModule) { -#if OSC_ENGINE_VERSION < 40600 - FSettingsSectionDelegates settingsDelegates; - settingsDelegates.ModifiedDelegate = FOnSettingsSectionModified::CreateRaw(this, &FOscModule::HandleSettingsSaved); - - auto settings = GetMutableDefault(); - settingsModule->RegisterSettings("Project", "Plugins", "OSC", - LOCTEXT("OscSettingsName", "OSC"), - LOCTEXT("OscSettingsDescription", "Configure the OSC plug-in."), - settings, - settingsDelegates); -#else auto settingsSection = settingsModule->RegisterSettings("Project", "Plugins", "OSC", LOCTEXT("OscSettingsName", "OSC"), LOCTEXT("OscSettingsDescription", "Configure the OSC plug-in."), @@ -60,7 +45,6 @@ public: { settingsSection->OnModified().BindRaw(this, &FOscModule::HandleSettingsSaved); } -#endif } else { diff --git a/OSC/Source/OSC/Private/OscPrivatePCH.h b/OSC/Source/OSC/Private/OscPrivatePCH.h index b7efac3..058e940 100644 --- a/OSC/Source/OSC/Private/OscPrivatePCH.h +++ b/OSC/Source/OSC/Private/OscPrivatePCH.h @@ -2,14 +2,9 @@ #include "Osc.h" -#if OSC_ENGINE_VERSION < 40600 -#include "Core.h" -#include "Settings.h" -#else #include "Engine.h" #include "ISettingsModule.h" #include "ISettingsSection.h" -#endif #include "ModuleManager.h" #include "Sockets.h" diff --git a/OSC/Source/OSC/Private/OscSettings.cpp b/OSC/Source/OSC/Private/OscSettings.cpp index e9e4be9..f301894 100644 --- a/OSC/Source/OSC/Private/OscSettings.cpp +++ b/OSC/Source/OSC/Private/OscSettings.cpp @@ -4,14 +4,19 @@ #include "OscDispatcher.h" -UOscSettings::UOscSettings( const class FPostConstructInitializeProperties& PCIP ) - : Super(PCIP), - ReceiveFrom("8000"), +UOscSettings::UOscSettings() + : ReceiveFrom("8000"), _sendSocket(FUdpSocketBuilder(TEXT("OscSender")).Build()) { SendTargets.Add(TEXT("127.0.0.1:8000")); } +UOscSettings::UOscSettings(FVTableHelper & helper) + : _sendSocket(FUdpSocketBuilder(TEXT("OscSender")).Build()) +{ + // Does not need to be a valid object. +} + void UOscSettings::UpdateSendAddresses() { FString addressStr, portStr; diff --git a/OSC/Source/OSC/Private/OscSettings.h b/OSC/Source/OSC/Private/OscSettings.h index 01237eb..4df1f0a 100644 --- a/OSC/Source/OSC/Private/OscSettings.h +++ b/OSC/Source/OSC/Private/OscSettings.h @@ -11,10 +11,16 @@ class UOscDispatcher; UCLASS(config=Engine) class UOscSettings : public UObject { - GENERATED_UCLASS_BODY() + GENERATED_BODY() public: + /// Default constructor + UOscSettings(); + + /// Hot reload constructor + UOscSettings(FVTableHelper & helper); + /** * Specify the [address:]port to listen to. * diff --git a/OSC/Source/OSC/Private/Receive/OscDispatcher.cpp b/OSC/Source/OSC/Private/Receive/OscDispatcher.cpp index 0e80123..5381206 100644 --- a/OSC/Source/OSC/Private/Receive/OscDispatcher.cpp +++ b/OSC/Source/OSC/Private/Receive/OscDispatcher.cpp @@ -5,15 +5,20 @@ #include "oscpack/osc/OscReceivedElements.h" -UOscDispatcher::UOscDispatcher(const class FPostConstructInitializeProperties& PCIP) -: Super(PCIP), - _listening(FIPv4Address(0), 0), +UOscDispatcher::UOscDispatcher() +: _listening(FIPv4Address(0), 0), _socket(nullptr), _socketReceiver(nullptr), _pendingMessages(1024) // arbitrary max message count per frame { } +UOscDispatcher::UOscDispatcher(FVTableHelper & helper) +: _pendingMessages(0) +{ + // Does not need to be a valid object. +} + UOscDispatcher * UOscDispatcher::Get() { return UOscDispatcher::StaticClass()->GetDefaultObject(); @@ -173,11 +178,7 @@ void UOscDispatcher::Callback(const FArrayReaderPtr& data, const FIPv4Endpoint&) { FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( FSimpleDelegateGraphTask::FDelegate::CreateUObject(this, &UOscDispatcher::CallbackMainThread), -#if OSC_ENGINE_VERSION < 40500 - TEXT("OscDispatcherProcessMessages"), -#else TStatId(), -#endif nullptr, ENamedThreads::GameThread); } diff --git a/OSC/Source/OSC/Private/Receive/OscDispatcher.h b/OSC/Source/OSC/Private/Receive/OscDispatcher.h index 1dd7ad1..e2ae7b1 100644 --- a/OSC/Source/OSC/Private/Receive/OscDispatcher.h +++ b/OSC/Source/OSC/Private/Receive/OscDispatcher.h @@ -12,14 +12,19 @@ class FUdpSocketReceiver; UCLASS() class UOscDispatcher : public UObject { - GENERATED_UCLASS_BODY() + GENERATED_BODY() - friend class OscModule; + friend class FOscModule; void Listen(FIPv4Address address, uint32_t port); void Stop(); public: + /// Default constructor + UOscDispatcher(); + + /// Hot reload constructor + UOscDispatcher(FVTableHelper & helper); /// Get the unique instance /// diff --git a/OSC/Source/OSC/Private/Receive/OscReceiverActor.cpp b/OSC/Source/OSC/Private/Receive/OscReceiverActor.cpp index c0bc500..558fdf7 100644 --- a/OSC/Source/OSC/Private/Receive/OscReceiverActor.cpp +++ b/OSC/Source/OSC/Private/Receive/OscReceiverActor.cpp @@ -3,9 +3,8 @@ #include "OscDispatcher.h" -AOscReceiverActor::AOscReceiverActor(const class FPostConstructInitializeProperties& PCIP) - : Super(PCIP), - _listener(this) +AOscReceiverActor::AOscReceiverActor() + : _listener(this) { auto instance = UOscDispatcher::Get(); if (instance && !HasAnyFlags(RF_ClassDefaultObject)) @@ -14,6 +13,12 @@ AOscReceiverActor::AOscReceiverActor(const class FPostConstructInitializePropert } } +AOscReceiverActor::AOscReceiverActor(FVTableHelper & helper) + : _listener(this) +{ + // Does not need to be a valid object. +} + void AOscReceiverActor::BeginDestroy() { auto instance = UOscDispatcher::Get(); diff --git a/OSC/Source/OSC/Private/Receive/OscReceiverActor.h b/OSC/Source/OSC/Private/Receive/OscReceiverActor.h index dbc3652..5fdf6f4 100644 --- a/OSC/Source/OSC/Private/Receive/OscReceiverActor.h +++ b/OSC/Source/OSC/Private/Receive/OscReceiverActor.h @@ -9,7 +9,9 @@ UCLASS(ClassGroup=OSC) class AOscReceiverActor : public AActor { - GENERATED_UCLASS_BODY() + GENERATED_BODY() + +public: UPROPERTY(EditAnywhere, Category=OSC) FString AddressFilter; @@ -18,6 +20,12 @@ class AOscReceiverActor : public AActor void OnOscReceived(const FName & Address, const TArray & Data); public: + + AOscReceiverActor(); + + /// Hot reload constructor + AOscReceiverActor(FVTableHelper & helper); + const FString & GetAddressFilter() const { return AddressFilter; diff --git a/OSC/Source/OSC/Private/Receive/OscReceiverComponent.cpp b/OSC/Source/OSC/Private/Receive/OscReceiverComponent.cpp index e6aae69..28b5a0c 100644 --- a/OSC/Source/OSC/Private/Receive/OscReceiverComponent.cpp +++ b/OSC/Source/OSC/Private/Receive/OscReceiverComponent.cpp @@ -3,13 +3,18 @@ #include "OscDispatcher.h" -UOscReceiverComponent::UOscReceiverComponent(const class FPostConstructInitializeProperties& PCIP) - : Super(PCIP), - _listener(this) +UOscReceiverComponent::UOscReceiverComponent() + : _listener(this) { } +UOscReceiverComponent::UOscReceiverComponent(FVTableHelper & helper) + : _listener(this) +{ + // Does not need to be a valid object. +} + void UOscReceiverComponent::OnRegister() { Super::OnRegister(); diff --git a/OSC/Source/OSC/Private/Receive/OscReceiverComponent.h b/OSC/Source/OSC/Private/Receive/OscReceiverComponent.h index caadc11..5bc133b 100644 --- a/OSC/Source/OSC/Private/Receive/OscReceiverComponent.h +++ b/OSC/Source/OSC/Private/Receive/OscReceiverComponent.h @@ -13,7 +13,9 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FComponentOscReceivedSignature, con UCLASS(ClassGroup=OSC, meta = (BlueprintSpawnableComponent)) class UOscReceiverComponent : public UActorComponent { - GENERATED_UCLASS_BODY() + GENERATED_BODY() + +public: UPROPERTY(EditAnywhere, Category=OSC) FString AddressFilter; @@ -22,6 +24,12 @@ class UOscReceiverComponent : public UActorComponent FComponentOscReceivedSignature OnOscReceived; public: + + UOscReceiverComponent(); + + /// Hot reload constructor + UOscReceiverComponent(FVTableHelper & helper); + const FString & GetAddressFilter() const { return AddressFilter; diff --git a/README.md b/README.md index ba76089..d39ac93 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,16 @@ OSC plugin for Unreal Engine 4 Blueprints Integration =========== -Put the "OSC" folder in a "Plugins" folder in the project root. +Install Visual Studio 2013 on Windows (Community edition works) or XCode on MaxOSX. -e.g. "/MyProject/Plugins/OSC" +Create a "C++" project, or convert a "Blueprint" project to "C++" ********************** + +Create a "Plugins" directory in the project root (near the "Content" directory) and put the "OSC" folder of the plugin in it. +(e.g. "/MyProject/Plugins/OSC") + +Run the "*.uproject" file: the plugin is compiled automatically. + +Alternatively, right-clic the "*.uproject" to generate Visual Studio or XCode project files. Usage @@ -35,8 +42,16 @@ Use the PushFloat/Int/Bool/String functions, or standard array functions, to bui Use the SendOsc function to send the OSC message + - Inputs: + +List the messages that should be UE4 inputs (like a game controller). A new input is created for each message. + +Bind OSC inputs to UE4 action in the usual "Input" project settings. + + Engine version ===== -Tested on UE 4.4, UE 4.5 (Windows, MacOSX) -Set the OSC_ENGINE_VERSION value (in Source/OSC/Private/Osc.h) to compile for a specific engine version. +Get the right branch for your engine version: "default" for the latest version, "before4.8" for 4.4, ..., 4.7, etc. + +Optionally, set the OSC_ENGINE_VERSION value (in Source/OSC/Private/Osc.h) to compile for a specific engine version.