x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

std::map doesn't copy to play in editor PIE / TMap

I'm trying to make a navigation graph from edges. At the moment, my class is set up like this:

  1. I have an actor set up to create the std::map, and to tick in both the editor and during play.

  2. In its OnConstruction method I have it call a Test() function.

  3. This adds 4 AVASFVVolume actors to the world, and adds edges to the std::map representing the connections between them.

When I am in the editor, the tick function draws the connections in the world (with DrawDebugLine) as I expect. However, when in PIE the debug lines do not get drawn, and a UE_LOG shows that the size of the map is 0.

I'm using an std::map with Key as a tuple (using the boost library) defining the two connected nodes and the map's Value being the cost of the connection (using this as a tutorial: https://www.youtube.com/watch?v=9-rliekgoAk).

In VolumeNavigator.h I have:

 typedef boost::tuple<AVASFVVolume*, AVASFVVolume*> EdgeTuple;
 
 struct EdgeStruct : public EdgeTuple
     {
         EdgeStruct(const EdgeTuple& tuple) : EdgeTuple{ tuple } {}
         AVASFVVolume* volumeA() const { return get<0>(); }
         AVASFVVolume* volumeB() const { return get<1>(); }
     };
     
 std::map<EdgeStruct, float> edgeMap;

When an edge is made between two nodes, I am incrementing an int32 as well to denote the size of the std::map. This value gets copied (?) correctly when switching to PIE. But it seems that the std::map doesn't? Is that because I'm using std::map instead of TMap?

Editor: alt text

PIE: alt text

If that's the case, has anyone had success in using TMap with a tuple as the key? Switching just the type of my edgeMap causes a lot of compilation errors.

Product Version: UE 4.10
Tags:
more ▼

asked Mar 28 '16 at 02:13 PM in C++ Programming

avatar image

Jayae
52 12 18 25

(comments are locked)
10|2000 characters needed characters left

1 answer: sort voted first

Two things. The constructor for actors isn't always called when the game starts. It might be called when the actor is serialized. You want to put your thing in PostInitializeComponents or maybe BeginPlay

Second, Yes you should switch it to a TMap. You should try to use the unreal types as much as possible. They have wrappers for almost every stl type that you'd need, except they have added functionality specifically to support engine features.

more ▼

answered Mar 28 '16 at 04:03 PM

avatar image

mrooney
698 40 31 123

avatar image Jayae Apr 05 '16 at 05:59 PM

I've modified my code so that now I use a TMap instead of std::map, and managed to remove the dependency on the boost library for tuples as well.

I'm still having the problem though that the TMap with a struct Key, which has pointers to two AActors is not copying into 'PIE' or simulation mode.

I've set my VolumeNavigator class to tick in both editor and play mode, and in the tick function to try and draw debug lines between every two AActors in the struct. But the debug lines only draw in editor mode and not in play mode. A UE_LOG confirms the .Num() of the TMap is 0 during play.

Why might that be?

avatar image mrooney Apr 05 '16 at 06:18 PM

Where are you filling the map?

avatar image Jayae Apr 06 '16 at 10:45 AM

Thanks for replying!

At a high level, I'm trying to connect actors together in a TMap to represent a connected graph of volumes (for an alternative AI navigation idea)

I made a few changes yesterday,

When my first actor spawns, in its BeginPlay function it calls my function Test().

Test adds 4 actors to the world, and fills the TMap. The custom struct is a list of 2 actors and looks like this: struct edgeStruct { AVASFVVolume* edgeTuple[2];

         AVASFVVolume* volumeA() const { return edgeTuple[0]; }
         AVASFVVolume* volumeB() const { return edgeTuple[1]; }
 
         bool operator==(const edgeStruct& other) const
         {
             return (edgeTuple[0] == other.edgeTuple[0]) && (edgeTuple[1] == other.edgeTuple[1]);
         }
 
         friend FORCEINLINE uint32 GetTypeHash(const edgeStruct& edge)
         {
             return FCrc::MemCrc_DEPRECATED(&edge, sizeof(edgeStruct));
         }
     };

The first actor is set to tick in both the editor and during PIE and to log the .Num of the TMap to show me how many elements are in it.

When I drag the actor into the world, Test() doesn't get called and so I get a log that there are 0 elements. When I hit play, the actors get created and added to the TMap as expected, and the log shows there are elements in the TMap and the tick function can draw debug lines between the actors. As soon as I stop the game though the tick log shows 0 elements and the debug lines are no longer drawn.

Ideally, I would like the secondary actors to be created once the first actor is dragged into the level in the editor, for the TMap to be filled at that time, and for the TMap and actors to remain when the level is played.

avatar image mrooney Apr 06 '16 at 02:29 PM

Ideally, I would like the secondary actors to be created once the first actor is dragged into the level in the editor, for the TMap to be filled at that time, and for the TMap and actors to remain when the level is played.

Hmmm. That's tricky. Essentially what you want is for an actor instance to spawn other actor instances when you add it to your level. I'm not certain of a good way to do that. I'm sure it's possible, but I'm not sure of the best way.

If you look in Actor.h/.cpp and look at everything that's wrapped with the WITH_EDITOR define, you should get an idea of some things that might point you in the right direction. I think what I've done in the past for similar situations is to add the other actors separately and then just add them as references to the first actor.

edit: Might be worth trying the forums too.

avatar image Jayae Apr 06 '16 at 02:36 PM

Thanks for the tips!

(comments are locked)
10|2000 characters needed characters left
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question