GetObject

You give an ElementID to this node and you have the object back. It include a cast node but will return your object even if you don’t set the class, it’s just an integrated cast.
if you allow it to generate object it will return your object even if it is not loaded in the world, it will prior return the real object (without deserialize it).

A previous save must have been done for this to work, else we don’t know what to return. There is a workaround for this, we’ll see how in the tutorial about instances.

Generated objects are internaly stored in a UPROPERTY, these won’t be garbage collected until EndGetObject.
Currently the only way to serialize a generated object is the EndGetObject node, all other attempt will simply be ignored (we want to change this behaviour).
You can make your own macro with less options if you prefere.

This allow you to direct get a deepObject in the element.
– [0] Will get you back the first DeepObject of the rootElement.
– [1,3,0] Will return the deepObject 0 of the deepObject 3 of the deepObject 1 of the root Element.

ArrayObject is see as a deepElement, you access objects in your array as if these were deepObjects of the ArrayObject.
ChildActorComponent is like ArrayObject but have only one deepObject : 0.
ArrayObject can contain childActorComponents but not ArrayObject currently.

Only the given path is handle, if you entered [0,4,3,1], only these objects are generated/deserialized, if your interaction will modfify a “brother” of the last one, you should get one level shallower [0,4,3]. This allow you to optimise your GetObject in a complex Element.

The DeepPath isn’t took into account in the maxDepth. Objects in the path will always be handles.

Exemples :
– (-1) All deepObjects are handle.
– 0, Only object in the deepPath are generated (the returned object is include in the Path). No deepObject of the returned object will be handle.
– 1 deepPath (returned included) and all his deepObjects are handle.
– 2 deepPath, all his deepObject, and all deepDeepObjects are…etc

Situation :

You have a class BP_MyActor.
It have one deepObject.
– [0] is a BP_myRotateComponent wich have a “Rotate()” function.

You have this Element :
The root Element is a BP_MyElement actor, it have two deepObjects :
– [0] is a childActorcomponent
– [1] is an AnotherActor.

It was saved in the folowing state :
– The childActorComponent’s class was BP_MyActor.
– The AnotherActor was an actor in the world.

Exemple 1
– TryCastTo : childActorComponent.
– DeepObjectList : [0]
– MaxDeepth : [-1].
You’ll have back the childActorComponent of MyElement, with an actorClass of BP_MyActor, this actor and all his deep objects are generated/deserialized.

AnotherActor is not handle.

Exemple 2
– TryCastTo : childActorComponent.
– DeepObjectList : [0]
– MaxDeepth : [1].
Return the childActorComponent of MyElement, with an actorClass of BP_MyActor, this actor is handle but not his myRotateComponent deepObject because the maxDeep was reached.

AnotherActor is not handle.

Exemple 3
– TryCastTo : Actor.
– DeepObjectList : [1]
– MaxDeepth : [-1].
Return AnotherActor, if My_Element need to be generated, it don’t mean that AnotherActor will be, DtArchive will try to resolve the actor and found it in world, it will only generate it if :
– It does not exist in wolrd or at a different fullPath (soft ref is used in this case).
– It contain saved data.

ChildActorComponent is not handle.

This node is currently needed after each use of a getObject node even if no objects was generated, this will be changed in later update but from now it must be called.
This node is the only way to serialize generated objects. If you only read data in the object, no need to serialize. You can use The EndGetObjectM macro if you prefere. You can make your own with less options.

In BP_Lever_C1, GetValueFromDoor() use the M version while Interact() use the normal version, you can take a look at difference.

There is a door and a lever, each are in his own level, at start all levels are loaded.
If you go in and out of a collider, the level is unloaded.

We want that :
– The lever change the state of the door
– A click on the door change his state and the change is reflected on the lever.
– All work in all cases :
– Both objects spawn together. We don’t know the order of spawn and the order of beginPlay.
– Both objects are in the world in play mode.
– One or other level is not loaded, it must work.
– Only one object saved : the Door

If you experiment a little, you’ll see some problems.
If you deserialize a game session in the editor that won’t work… other problem can occure where nothing will work until you re serialise in editor. Problems are about using soft references and going to and from PIE, in a game build that should work.

UE handle case where a soft ref is pointing on an object in editor, the ref is automatiquely changed to his value in game but the reverse isn’t handle.

In next tutorial you’ll do some change for make all this work anytime.

This GetObject node will maybe change how you used UE until now.
Because you can access object at low cost (very low if object is loaded, else it will depend if datas are cached or if file need to be loaded).
Something common for BP users is to store vars that need distant access in an actor that is unique in persistant level, storing the state of a door just near what was said to an NPC. If you’re doing this i’m sure you know it’s bad for maintenance and flexibility.

Unitl now you’ll store things where they have to, the state of a door in the door, what was said to an NPC in the NPC, and you can get it from player, from an other NPC, everywhere without to worry if the object is loaded or not.

SetDoorFromIsOpen() (begin play and construction) update the state of the door instantly and call SetLeverPosition().
ChangeState() will change the value of IsOpen, Set Tick Enable for smooth update, Serialize and call SetLeverPosition().
SetLeverPosition (in door) will be the only thing that will update the lever, even when generated by the GetObject node.

We stored the identifier of the door as hash in public editable variable. Blueprint is commented, you can take a look at the GetObject node, it’s a little huge because it have advanced options but easy to use.

We already talked about that but if you do the following thing :
– Not serialize anything in editor (or delete archives if already serialized).
– Play, go in the door’s box.
– Go near the lever at a place where the door is not loaded.
– try activate the lever.
It won’t work because the door have no data and cannot be get. The door must have a saved state if not loaded in the world.
We will se how to handle these cases in Instance’s tutorial.

– We plane to make the getObject/EndGetObject nodes more user friendly, we currently don’t know how it will be exactly.
– Some kind of “alias” for access deepObject from a name where currently an array of indexes.