DrifterFun

One need not hope in order to undertake, nor succeed in order to persevere.

Carsim->Airsim(1)

2018-05-15


最近一直特别忙,三个事情基本上是碰在在一起了,这就是所谓的祸不单行吧。临近考试本来就特别多的大作业和考试复习,再加上项目里面的一大堆事情,以及自己毫无进展的研究工作可以说是非常闹心了。

最近一直在做项目的事情,概括起来基本上是需要将CarSim里面的动力学模型建立到AirSim里面去。最初接到这个事情的时候本来内心是特别烦躁的,因为自己甚至根本不知道需要怎么样子去做才能够将他们放到一起。直到我在github上询问了之后,得到了解答才稍微心情好一些。

这几天一直顺着这个思路在往下推进。其中得到了一些比较有用的东西,可能觉得需要记录一下,免得自己给忘记了。人老了……

首先需要明确的一点是有关UnrealEngine的插件设计哲学。在UE4中插件的设计哲学是:所有的插件能且只能依赖引擎。这一点是自然且符合规范的。然而由于这个哲学,却给我带来了很多麻烦,因为我需要在AirSim这个插件中使用CarSim插件,所以我的应用和哲学是相抵触的。这几天一直在查找资料,终于在Wiki看到了如下资料(原来UE4还是给开发者留下了一道小门的)现在将它摘抄如下,以免日后忘记:

Step1:Plugin must export the proper classes:

The first step is required of the plugin writer, you must properly export the classes you want other people to be able to use, here is example from my RamaSaveSystem Plugin:

#pragma once
 
#include "RamaSaveComponent.h"
#include "RamaSaveEngine.h"
 
#include "RamaSaveLibrary.generated.h"
 
UCLASS()
class RAMASAVESYSTEM_API URamaSaveLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
public:
 
	static ARamaSaveEngine* GetOrCreateRamaEngine(UWorld* World);

The part I am trying to emphasize is this:

class RAMASAVESYSTEM_API URamaSaveLibrary

By using the macro RAMASAVESYSTEM_API, UE4 generates all the code for properly exporting this class as a class that other projects can “see into”, call functions from, and even inherit from as a subclass! (do a search for “__declspec(dllexport)” for more info).

UE4 generates the macro automatically, so for your plugin it would be YOURPLUGIN_API and you dont have to declare that anywhere. (Correction: A Plugin is a collection of Modules. The Auto-Generated export is for YOURMODULE_API. Which is declared within your plugin.)

Because plugins are .dlls, you can export functionality from that dll for others to call into via the macro that UE4 generates for you automatically.

In the same way you can inherit from AActor in a precompiled UE4 engine version (without compiling a custom engine), so you can enable people to inherit from your plugin classes by properly exporting them as shown above.

Step 2: Build.cs:

The user of the plugin’s code has to include the plugin in their build cs, so your build cs will end up looking something like this:

PublicDependencyModuleNames.AddRange(new string[] { 
	"Core", 
	"CoreUObject", 
	"Engine", 
	"InputCore",
 
	"UMG", "Slate", "SlateCore", 
 
	"AIModule",
 
	"PhysX", "APEX",
 
	//Rama Plugins  
	"RamaSaveSystem"   //<~~~~~~
});

Step 3: #include like you do with UE4 engine classes

Now that you’ve added the plugin to your build cs, you can #include whichever properly exported class files you want!

#include "RamaSaveLibrary.h"

Now you can inherit from these included plugin classes, or extend them to create your own custom subclasses of base plugin classes without having to modify the source code at all, which is very handy for when the plugin author updates their source code!