This repository has been archived by the owner on May 3, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 28
/
RandomNotes.txt
95 lines (55 loc) · 5.97 KB
/
RandomNotes.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# Developer Notes
## Bare Minimum
This is a [UE4 Plugin](https://docs.unrealengine.com/latest/INT/Programming/Plugins/index.html). We are making a game plugin and we want the game to statically link against our PSMove module so the game can use (or inherit from) our provided classes.
If desired, [there is a tool](https://github.com/karolz/PluginCreator) that automates the creation of a minimal plugin. A minimal plugin is constructed as follows:
First, we define our plugin's module(s) and list them in the plugin descriptor: `PSMovePlugin.uplugin`. We only have one module: `PSMove`. Next, we create a Source/<ModuleName> folder for each of our modules.
In each module folder we have its <ModuleName>.Build.cs that describes how to build it. There we define the include directories and the libraries (and other modules) we will link.
Somewhere in the module's code we need to call `IMPLEMENT_MODULE(<ModuleImplementation>, <ModuleName>), which is an alias to DLLEXPORT the initialization of this module. This is typically done in <ModuleName>/Private/F<ModuleName>.cpp, which is the definition for a class (declared in Private/F<ModuleName>.h) that implements the [module interface](https://docs.unrealengine.com/latest/INT/API/Runtime/Core/Modules/IModuleInterface/index.html) (declared in Public/I<ModuleName>.h).
That is the bare minimum for a UE4 plugin.
## Adding functionality
The desired end result is an in-game class that can use Blueprints to access the psmove's position, orientation, buttons, and can send vibration commands (and leds? Those are managed by psmove_tracker).
The FPSMove (i.e., module singleton), upon startup, initializes the FPSMoveWorker passing pointers to the module's MyPosition and MyOrientation members.
The FPSMoveWorker's PSMoveWorkerInit function constructs a static FPSMoveWorker instance (relaying pointers to MyPosition and MyOrientation).
Upon construction of the FPSMoveWorker instance, MyPosition and MyOrientation pointers are copied to local member pointers WorkerPosition and WorkerOrientation. Then the worker Thread is created, the PSMove controllers are connected and the tracker is initialized.
The worker Thread automatically Init() and Run(). On each iteration of the thread loop
1. the tracker is updated (i.e., image pulled and orb(s) found), then for each controller
2. The orb position is updated and assigned to the WorkerPosition-> variables.
3. The controller is polled.
4. The controller orientation quaternion is obtained and assigned to the WorkerOrientation->.
5. The buttons are polled (but we don’t use them currently).
Because WorkerOrientation and WorkerPosition are just pointers to the module's data, we have updated the value in the module, accessible via the module singleton.
The PSMoveComponent, on each TickComponent, copies the module singleton ModulePosition and ModuleOrientation into its own member variables Position, Orientation. These variables can be used in game.
I would prefer to use TThreadSafeSharedPtr:
1. The module has a sharedptr member variable for each of Position and Orientation.
2. The worker has similar member variables.
3. On module construction, the sharedptrs are assigned MakeShareable(new FVector());
4. Still on module construction, the worker shared pointers copy the module shared pointer.
5. Any class that wants access to the Position and Orientation can copy the module's shared pointer.
I tried doing this but then I didn't know how to access the shared pointer in blueprints, and then how to dereference it in blueprints.
Next, we need a way for the module to trigger events to let the game know that something happened. Event messaging is typically complicated, and UE4 is no exception.
## Other notes
### Interfaces
Interfaces can be Blueprint interfaces as well as defined in C++. We need C++ because we are accessing a C++ library (i.e., the psmoveapi). See the [UE4 Wiki tutorial on C++ interfaces](https://wiki.unrealengine.com/Interfaces_in_C%2B%2B). Also [here](https://answers.unrealengine.com/questions/152680/interface-in-c-can-you-pass-variables-between-obje.html).
#### Defining an interface in C++
See Source/Public/PSMoveEventInterface.h and Souce/Private/PSMoveEventInterface.cpp
In our interface header we declare static member variables and static functions.
#### Implementing an interface in C++
(Multiply-) Inherit from the interface in a C++ class. Here I do that in Source/Classes/PSMoveComponent.h
There needs to be a mechanism to communicate between our module's functionality and the created class. As far as I can tell, there are two ways to do this, and neither of them are very well documented:
1. UE4's delegate system
2. Interfaces
### UE4's delegate system
I have not worked much with [UE4's delegate system](https://docs.unrealengine.com/latest/INT/Programming/UnrealArchitecture/Delegates/index.html), though I hope to try it eventually.
#### Defining an interface in Blueprints
We are not doing this here, though it is [well documented](https://docs.unrealengine.com/latest/INT/Engine/Blueprints/UserGuide/Types/Interface/index.html).
#### Implementing an interface in Blueprint
This is probably the [best-documented part of interfaces](https://docs.unrealengine.com/latest/INT/Engine/Blueprints/UserGuide/Types/Interface/UsingInterfaces/index.html).
This class is decorated with the
[UINTERFACE macro](https://docs.unrealengine.com/latest/INT/Programming/UnrealArchitecture/Reference/Interfaces/index.html)
and inherits from .
This is the class that will be consumed by the game.
Side Note:
In some cases (I'm not sure, [but when a UObject is involved anyway](https://answers.unrealengine.com/questions/2649/how-exactly-do-game-plugins-work.html))
it will be necessary to use [MYMODULE_API -style interface](http://adamitskiy.wix.com/daniel#!ue4-programming-api-fundamentals/c1f6q).
We then inherit from the interface within the plugin's private implementation.
The game can now consume the plugin through the interface.