Access Variables From Another Actor C++

Hey, new to UE4 and learning how to reference. I am trying to access variables from another actor in my scene. The calling actor is TheBuildingCharacter and the Actor being called is BuildingController. It has some public variables holding info about the current building the character is in and I want to access those. In the Character cpp I have the following code to find the Controller actor:

void ATheBuildingCharacter::PrintAllStaticMeshActorsLocations()
{

for (TActorIterator<AStaticMeshActor> ActorItr(()); ActorItr; ++ActorItr)
{
	if (ActorItr->GetName() == "BuildingController")
	{
		BControllerActor = ActorItr->GetAttachedActors;
		BControllerClass = ActorItr->GetActorClass()->GetDefaultObject<ABuildingController>;
	}
}

}

Not sure if I’m going about this right, I’ve gleaned this code from searching google and these forums. Is this correct so far and how do I then find the variables I am looking for? An example variable in the Controller header is:

public:
int16 BFloorNum;

Any help would be greatly appreciated. Thanks!

yes you can have things like this, but the problem is you have to iterated through all the actor. i think more efficient way to do this. is through some event. hit event, overlap event or something like that. with that things. you can have exactly the actor that you wanted to referenced. and also if you use the TActorIterator. to get the value we usually use *ActorItr (get the pointer)

Thanks for the reply. Very good point on not having to iterate through everyone. I’ll try to find a way around that.I changed the code to look for an object by name(still with an iterator) and I get the class through that. I think I found the class I was looking for but for some reason the values returned are all wrong. For instance the BScale value I find is 335855616 instead of 200. Any clue why this might be? BScale is a int16 from the header I have referenced. The current code is as follows:

for (TObjectIterator<UObject> Itr; Itr; ++Itr)
	{
		if (Itr->GetName() == "BuildingController")
		{
			MyObj = Itr->GetName();
			BController = Itr->GetClass()->GetDefaultObject<ABuildingController>();
		}
		
	}
	if (BController)
	{
	CurrentFloor = BController->BHeight;
	PlayerLocation = GetActorLocation();
	if (PlayerLocation.Z > BController->BHeight)
	{
		CurrentFloor = BController->BFloorNum;
	}
	else if (PlayerLocation.Z < BController->BBaseFloorY)
	{
		CurrentFloor = 1;
	}
	else
	{
		CurrentFloor = PlayerLocation.Z / (BController->BFloorHeight - BController->BBaseFloorY);
	}
	GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Green, TEXT("  FloorNum: ")+ MyObj + FString::FromInt(CurrentFloor));
	}

This is last resort, if you really lost contact with object and searching is only way of getting it. Generally you should keep related object in varables, as they are created or have things changed in them or when some specific event happen, this let you create network of object relations which from it you can access anything from anywhere.

For example you got Party class that manages party, party needs to hold information about there members, so when PlayerController ask to join that party via some function call, you make it so it past it self to it via argument, party class then add PlayerController to some array of members and it calls PlayerController via some function that he been added to party and includes it self as argument in that call, PlayerController acknowledges that it joined part and set party object in to pointer in itself so it know in which party it is. Parties overall could be managed in GameMode and GameMode could have array of them so you can list them and present to player and GameMode you can access from UWorld which you can access from any actor via ().

You case it’s pretty easy, as mirsabayu hints, you can use overlap events to detect what actors going in and out of box component for example. When Pawn is coming in and it a Pawn with your Pawn class which will have varable have event function OnEnteredBuilding(*ABuildingController Building), ABuildingController on it’s overlap event will check is it comaptible (your class with that function) pawn using IsA() function, the you cast to your class and call Other->OnEnteredBuilding(this) (“Other” overlap actor argument varbale which you should have on overlap event, “this” is object which code is being executed right now). OnEnteredBuilding function in pawn will set variable ABuildingController* InBuilding so pawn knows where it is and if you gonna deal with this pawn somewhere else you know in which building it is and from that variable it is.

Go explore API refrence:

Search for classes and explore there functions and varables and use them, start with AActor to see what you can do with all actors:

most importent for you will be those 2 delegates, overlap events where actor enter and leaves collision of actor:

Delegate is event in which you can bind function in to and they are being called when event happens, they usally listed as varables in API refrence. It’s hard to read them in API refrence right now because it does not tell you what kind of functions you need to create, best way right now is to search there structure type like “FActorEndOverlapSignature” in GitHub and first reult should give you decleration of delegate.

https://github.com/EpicGames/UnrealEngine/blob/311e18ff369078e192a83f27834b45bdb288168a/Engine/Source/Runtime/Engine/Classes/GameFramework/Actor.h#L26

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam( FActorBeginOverlapSignature, AActor*, OtherActor );

So it tells as function need to have 1 argument AActor* with the name OtherActor (but it can be any name, C++ compiler don’t check them anyway, argument types are more importent). So in your ABuildingController you declere function, in header file:

void OnActorEntersBuilding(AActor* OtherActor);

and in .cpp something like this:

void ABuildingController::OnActorEnteredBuilding(AActor* OtherActor) {
       if(OtherActor->IsA(AMyAwesomePawnThatCanEnterBuilding::StaticClass()) { //we check if it our pawn
               ((AMyAwesomePawnThatCanEnterBuilding*)OtherActor)->OnEnteredBuilding(this);
       }
}

And on BeginPlay of ABuildingController bind the event doing this:

OnActorBeginOverlap.AddDynamic(this,&ABuildingController::OnActorEnteredBuilding);

first argument is object that will be called on event and 2nd is function pointer to function we want to delegate to call

And Pawn function OnEnteredBuilding(ABuildingController*) will set varable InBuilding, on End Overlap event you set that varable to nullptr as he leaves the building

Now that simple breath example, btw it will only work if those BuildingController won’t overlap themselfs or else it might mess up that varable in pawn (it enters building, which has another building, but if it leaves one building will be null). You should figure yourself what is best for your game, so you should learn how to use assets that engine gives you to build such system. Again go explore API reference, learn about classes and functions and varbales in them, all classes in engine are made same way as your classes, so look how they constructed and try to mimic same style.

Sry that this post is kind of messy ^^’ wanted for you to show you how you should approach it

You accessing CBO a deafult object, not object you want to access, also don’t need any class checking as long as you type in object class in iterator:

 for (TObjectIterator<ABuildingController> Itr; Itr; ++Itr)
     {
             MyObj = Itr->GetName();
             BController = Itr*; //* operator return the current object same as -> operator let you call functions in it
         break; //We find what we need isn't so break the iteration loop
     }

I still think you do this in really buggy way :stuck_out_tongue:

Wow that was really good info there. Thanks for writing all that. I will have to study all of that now to figure out how to implement it. Thanks a lot!