Trying to dynamically spawn actors using data from remote file (CSV/XML/etc)

I’ll start off by saying I have no experience with UE, but I do have some experience with C++ (and a decent amount of coding experience in general). My coworker has some experience with UE, but very little coding experience. Since this problem seems to be a combination of UE’s GUI and coding, we’re stuck as we both lack understanding of the other side.

We are attempting to build a VR tour using photospheres. He’s been able to create the photospheres and apply the panoramas manually, but we have over 2500 panoramas (with more being added all the time), and doing them manually would be a nightmare (not to mention it would make the program take up a ridiculous amount of disk space). So we want to load the information from a remote server (he’s been able to load a panorama from a url, so far, but now we’re stuck).
This is the information we need to pull from the server and build the photosphere with:

The panorama (its starting rotation and the angle north).

The “hotspots” (links to other panoramas that include their angular position relative to the camera). I was thinking it would be best to spawn button actors for the hotspots, but I’m open to suggestions.

As a programmer, my thought is to build a photosphere class (not sure if that’s the right term for UE, but basically an actor template) and create an instance of said class when the user visits a photosphere. Assuming the hotspots will be actors, we would also need a class for them, and destroy/create them as we jump between panoramas.

The walls we’ve hit are how to:
Create custom actor templates from which actors can be instantiated

What format to use for the data. (I’m personally thinking XML because we have no set number of hotspots and they all have a pan, a tilt, and a destination attached to them. I think it would be tricky to send that over as a CSV and keep the comma-separated lists straight (making sure “pan1,pan2,pan3”,“tilt1,tilt2,tilt3”,“dest1,dest2,dest3” end up as 3 hotspots with the same information). We CAN do this, as we have before, but I’d like to keep this as simple as possible.

How to get that data into UE and spawn the actors?
Can anyone provide some resources like tutorials for us to look at? We’ve spent days looking through documentation and help forums and we just can’t get our foot in the door. We appreciate any help you can provide to get us started on the right track.

C++ for UE is not terrible different from standard C++. The biggest difference is you’re not doing your own memory management; other than that the only differences are the macros used to expose your code to the Editor and Blueprints (BP).

AActor is a class, just like a normal C++ class, and you can create classes inheriting from it as you normally would:

class AMyChildActor : public AActor
{
 //... actor stuff ...
};

In order to inform the Editor and Blueprints of your new class, you use a few macros:

UCLASS(BlueprintType, Blueprintable, Category = "My Category|My Sub-Category")
class AMyChildActor : public AActor
{
    GENERATED_BODY()
//...actor stuff ...
};

When you create properties and methods in your actor, you use the UPROPERTY and UFUNCTION macros:

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float MyFloat;


UFUNCTION(BlueprintPure, Category = "Getters and Setters")
float GetMyFloat();

Any properties you need to use in your actor that aren’t of a type recognized by Blueprints can still be used; either my omitting the UPROPERTY macro (and then you have to do any memory management required) or by exposing the type to Blueprints yourself.

Similarly, and methods that return types or use arguments of types that aren’t exposed to Blueprints, you can either expose the type or omit the UFUNCTION macro (in which case your Blueprint scripts won’t be able to access that method).

Non-AActor objects are based on the UObject class, but otherwise are declared exactly as AActors.

 UCLASS(BlueprintType, Blueprintable, Category = "My Category|My Sub-Category")
 class UMyChildObject : public UObject
 {
     GENERATED_BODY()
 //...object stuff ...
 };

You also can create structs (USTRUCT) and enums (UENUM) and have their properties and values available in BP.

UENUM(Blueprintable, BlueprintType, Category = "My Category|My Sub-Category")
enum class EMyEnumType : uint8
{
	NONE			UMETA(DisplayName = "None     "),
	NORMAL			UMETA(DisplayName = "Normal   ")
};



USTRUCT(Blueprintable, BlueprintType, Category = "My Category|My Sub-Category")
struct FMyStruct
{

	GENERATED_USTRUCT_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
	float MyFloat;

        //Structs should have a default constructor
        FMyStruct(float MyNewFloat = 0.0f)
            :
            MyFloat(MyNewFloat)
        {}

};

The names for your different types need the appropriate prefix; e.g. AActors use ‘A’, UObjects use ‘O’, UStructs use ‘F’ and UEnums use ‘E’

This should get you up to speed:

A new, community-hosted Unreal Engine Wiki - Announcements - Unreal Engine Forums4-_Creating_a_Battery_in_C%2B%2B


AActors are spawned using SpawnActor; there are a few footprints for that:

//Any AActor can retrieve its internal reference to the game world with "GetWorld()"
//which retrieves a UWorld object pointer

FActorSpawnParameters SpawnParams = FActorSpawnParameters();
    SpawnParams.Name = TEXT("NewActorName");
    SpawnParams.Template = NULL;
    SpawnParams.Owner = this;
    SpawnParams.Instigator = this;
    SpawnParams.OverrideLevel = NULL;

AMyChildActor* MyNewChild = GetWorld()->SpawnActor<AMyChildActor>(SpawnParams);

UObjects don’t require a UWorld reference, so they can be spawned from anywhere using NewObject:

UMyChildObject* MyObject = NewObject<UMyChildObject>();

UStructs are created using the defined constructor(s)

FMyStruct NewStruct = FMyStruct();

UEnum values are assigned using namespace syntax:

EMyEnum EnumVal = EMyEnum::NORMAL;

To address your specific implementation, you may want to look into using UDataTables to keep your data; or maybe just for data import. This would require using CSV, but you can easily export from a spreadsheet file that you actually use to create and manipulate your data; but is converted to USTRUCT automatically on import.

You can create custom USTRUCTs describing your hotspots, each row in your CSV table would describe a single hotspot, and then you can pull data from the imported table as a USTRUCT; which can then be placed in an array within your Photosphere actor.

The trick with this is that, I believe, the table(s) would have to be imported from the CSV before use and compiled as a UE4 asset file; but there’s nothing stopping you from compiling those assets and then delivering them from the server (they’d probably be faster to retrieve from the server anyway).

There’s a lot of ways to do what you’re trying, though, so I’d suggest getting familiar with the basics of UE4 architecture, and then going from there.

Hope this helps.