What you doing is not instantiation but only deceleration. But variable of type with * symbol is a pointer, it points something in memory, in technical sense it a integer varable containing memory address. Just declare it won’t magically make it point to the object, same as integer it will have value 0 aka nullptr.
You need to set pointer either by instantiation or getting the pointer from diffrence sources (like get functions) if they already been created. Normally in C++ you would use new
operator to create a instance, in general it is operator to dynamically allocate variable, including integer and float varables. But in UE4 you not really gonna use that, as UE4 got special function to create objects and you rarely (there are some advance cases) create integer and float pointers.
To instantiate Actor you use function in UWorld called SpawnActor and oyu get UWorld instance using in any actor:
someName = ()->SpawnActor<A>();
or
someName = Cast<A>(()->SpawnActor(A::StaticClass()));
SpawnActor has special template argument (look example 1), which allows auto casting (you don’t need to cast return varable) and automaticlly fill UClass* function argument (which oyu can see i used in argument 2)
If SpawnActor fails to spawn, it will print reason in the log and return nullptr
To instantiate UObject oyu use NewObject, similar as Spawn actor, but this time you need to define outer object which in most cases are object you creating object in
someName = NewObject<A>(this);
But what im saying so far is just creation of object, UE4 is big and it create many objects in it’s lifetime and your world is big and each time you palce actor on the level you already creating instance of it so you dont need to create new ones, you need to get one or make newly create object to send pointer to it self somewhere else.
For example AGameMode is a core of the game code that exist in span of whole level (unlike UGameInstance which exist in spawn of entire game), it is always create by UE4 automaticly and to access it instance you need to call function in UWorld called GetAuthGameMode():
AMyGameMode* MyGameMode = ()->GetAuthGameMode();
As oyu can see this function also have template argument that do automatic casting, it will return nullptr if game mode class is not the one that you requested.
If you make single player game, you can get APlayerController same way:
If you used blueprint, you can see the exact same pattern here… yes, because blue pins and link are equivalent of object pointers in C++ and it uses mostly same functions.
Getting actor on level is a lot more tricky, if there is importent actor for a game mode oyu making, in general practice actor should send it’s pointer to GameMode where other actors can access it. For example you make some football game and oyu got ball ABall* placed in the level on BeginPlay of the ball you set varable Ball in gamemode AMyGameMode* :
()->GetAuthGameMode()->Ball = this;
this
is pointer to instance of class that function is currently executing in, so object it self can tell where they are in memory. Now you can access game mode anywhere and access Ball from nearly anywhere in the code
Other way is search for a actor, you should use it as last resort as it’s most expensive way to do it… and yes it the same thing you use in blueprint, GetAllActorsOfClass:
TArray<AActor> Actors;
UGameplayStatics::GetAllActorsOfClass((),ABall::StaticClass(), Actors);
//Knowing we have only one ball on the level we just gonna grab first item of array
ABall* Ball
//checking if array is not empty before getting it
if(Actors.Num() > 0) Ball = Actors[0];
But this function was designed for blueprints that does not support iterators which oyu can use C++ and are a lot better as you can break search loop once you find actor you looking for:
A lot easier way is to make actor pointer EditAnywhere
, or more optimally EditInstanceOnly
:
UPROPERTY(EditInstanceOnly, Category="Related Actors")
ABall* Ball;
And when you place an actor having this variable on the level you can set this variable in property editor, this allows to easily link actors together without need for them to register themselves or search or each other.
Also remeber if you declere pointer to UObject or AActor (which is also UObject) in class you need to place UPROPERTY(), this will make varbale visible for the engine and it will monitor object referencing for GC, it will also automaticly set property to nullptr
if object gets destroyed, something that does not happen automatically. If object pointer won’t be nullptr when it’s destroyed, you got so called invalid pointer, pointing to invalid memory address which either points to trash data in memory or nonallocated memory and accessing it will cause a imminent crash. You Would need to use expensive IsValid() function which checks if pointer is pointing to valid created UObject that engine tracks.