Download

iterate actors?

hello

for the past month ive been ‘trying’ to get into ue4 c++, so far all i have learned is 10,000 ways to make a project not compile and very little else.

how do you iterate over all the actors in the world of a specific class from an AActor based class?
from here


for (TActorIterator<ASomeActor> ActorItr(GetWorld()); ActorItr; ++ActorItr)
	{
		//...
	}

throws an error about TActorIterator
if i
#include “EngineUtils.h”
i get errors about viewport and stuff

how do you do it?

thanks

1 Like

I use TObjectIterator instead; it’s supposedly faster and less picky.


	
for (TObjectIterator<MyClass> Itr; Itr; ++Itr)
{
	if (Itr->IsA(MyClass::StaticClass()))
	{
		return *Itr;
	} 
	else
	{
		continue;
	}
}


no i cant get that to work either, any class i try
Error 1 error C2065: ‘AnyClassITry’ : undeclared identifier
Error 2 error C2923: ‘TObjectIterator’ : ‘AnyClassITry’ is not a valid template type argument for parameter ‘T’

could you show an example how to get erm… lets say Pawns for instance
note this is in an actor based class
thanks

4.6 preview if thats of any consequence.

Okay, let’s say you want to get an array of all the pawns in your world.

PawnFinder.h:



#pragma once

#include "GameFramework/Actor.h"
#include "PawnFinder.generated.h"

UCLASS()
class MYPROJECT_API UPawnFinder : public AActor
{
	GENERATED_BODY()

	UFUNCTION()
		TArray<APawn> GetPawns();
}


PawnFinder.cpp:



#include "MyProject.h"
#include "PawnFinder.h"

TArray<APawn> UPawnFinder::GetPawns()
{
	TArray<APawn> pawns;
	
	for (TObjectIterator<APawn> Itr; Itr; ++Itr)
	{
		if (Itr->IsA(APawn::StaticClass()))
		{
			pawns.Add(Itr);
		}
	}
	return pawns;
}


That should work, but may throw some errors based on pointers, probably. See if this compiles and let me know about any errors you get - I’m not great at knowing which objects require references yet, heh.

Also if you’re trying to get a specific derived class that you made, you’ll have to include it in your header like

#include “CustomClass.h”

otherwise the compiler won’t know that class exists!

hmmm…

103 errors
surely it shouldn’t be this hard to get actors in the world

edit:
it works!
you were right
#include “GameFramework/Pawn.h”

thanks Jared :slight_smile:

haha, welcome to C++!

What kinds of errors do you have?

oh the usual completely random unrelated errors.
its not c++ im having trouble with, its the ‘Unreal’ flavoring that throws me every time

cheers

word, it’s a trip. Here’s to getting the hang of it!

1 Like

gosh blimey
it works for pawn but not my own pawn class


Error	1	error C2065: 'C_CarPawn' : undeclared identifier	C:\UE4Projects\C_Car 4.6\Source\C_Car\Private\Gravity_Actor.cpp	11	1	C_Car
Error	2	error C2923: 'TObjectIterator' : 'C_CarPawn' is not a valid template type argument for parameter 'T'	C:\UE4Projects\C_Car 4.6\Source\C_Car\Private\Gravity_Actor.cpp	11	1	C_Car
Error	3	error C2133: 'Itr' : unknown size	C:\UE4Projects\C_Car 4.6\Source\C_Car\Private\Gravity_Actor.cpp	11	1	C_Car
Error	4	error C2512: 'TObjectIterator' : no appropriate default constructor available	C:\UE4Projects\C_Car 4.6\Source\C_Car\Private\Gravity_Actor.cpp	11	1	C_Car
Error	5	error C2451: conditional expression of type 'TObjectIterator' is illegal	C:\UE4Projects\C_Car 4.6\Source\C_Car\Private\Gravity_Actor.cpp	11	1	C_Car
Error	6	error C2678: binary '++' : no operator found which takes a left-hand operand of type 'TObjectIterator' (or there is no acceptable conversion)	C:\UE4Projects\C_Car 4.6\Source\C_Car\Private\Gravity_Actor.cpp	11	1	C_Car
Error	7	error C2678: binary '->' : no operator found which takes a left-hand operand of type 'TObjectIterator' (or there is no acceptable conversion)	C:\UE4Projects\C_Car 4.6\Source\C_Car\Private\Gravity_Actor.cpp	13	1	C_Car
Error	8	error C2039: 'IsA' : is not a member of 'TObjectIterator'	C:\UE4Projects\C_Car 4.6\Source\C_Car\Private\Gravity_Actor.cpp	13	1	C_Car
Error	9	error C2653: 'C_CarPawn' : is not a class or namespace name	C:\UE4Projects\C_Car 4.6\Source\C_Car\Private\Gravity_Actor.cpp	13	1	C_Car


any ideas?

edit;
never mind, forgot to add the ‘A’ before the class
argh this unreal stuff is a mess

Without seeing the code it’s hard to say. Did you #include the header for your CarPawn?

I can’t tell you how many times that’s tripped me up. Not to mention it’s ugly!

right so now i can get the pawns in the world but how do i call something on it?
sorry it seems like i need help with every single line of code atm lol

if (Itr->IsA(AC_CarPawn::StaticClass()))
{
//got one now do something with it
Itr->SomeFunction(); //doesnt work

ive had a look at casting but i cant get that to work either, probably doing it wrong
AC_CarPawn* CarP = Cast<AC_CarPawn>(Itr);
CarP->dosomething();

I’m surprised -> doesn’t work, that should return a pointer to the object. You could try GetObject()

-> does work, not for what im trying to do though. maybe i should start a new thread
im trying to add force

Itr->GetMesh()->Addforce(Direction);

errors


Error	1	error C2027: use of undefined type 'USkeletalMeshComponent'	C:\UE4Projects\C_Car 4.6\Source\C_Car\Private\Gravity_Actor.cpp	24	1	C_Car
Error	2	error C2227: left of '->Addforce' must point to class/struct/union/generic type	C:\UE4Projects\C_Car 4.6\Source\C_Car\Private\Gravity_Actor.cpp	24	1	C_Car


an alternative would be to use APawn::GetGravityDirection()
but it doesnt seem to allow me to override it

thanks for all the help so far, really appreciate it

I haven’t used physics extensively yet in C++ but the errors make it sound like you’re missing an include for something, but I’m not 100% sure what since SkeletalMeshComponent doesn’t have its own header.

thanks for pointing me in the right direction, i tried to include skeletalmeshcomponent before without success.

for anyone else, heres what you need to do it

#include “Components/SkeletalMeshComponent.h”
Itr->Mesh->GetBodyInstance()->AddForce(Direction);

thanks again :slight_smile:

well, it compiles but doesnt work. will it get blueprints extending this class?

i put this in and it gets nothing, not even a straight class


if (GEngine)
			{
				GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, Itr->GetName());  //never shows anything
			}

Give this a try.
Include EngineUtils.h in your project header.


for (TActorIterator<AStaticMeshActor> ActorItr(GetWorld()); ActorItr; ++ActorItr)
	{
		ClientMessage(ActorItr->GetName());
		ClientMessage(ActorItr->GetActorLocation().ToString());
	}

Thank you to Rama for the full tutorial on the subject. :smiley:
Iterators: Object & Actor Iterators, Optional Class Scope For Faster Search

WCode

thanks WCode, thats where i started, and it still doesnt work :frowning:
heres the whole code, incase ive done something silly
.h


#pragma once

#include "GameFramework/Actor.h"
#include "Gravity_Actor.generated.h"

/**
 * 
 */
UCLASS()
class C_CAR_API AGravity_Actor : public AActor
{
	GENERATED_BODY()

		UPROPERTY(Category = Gravity, EditDefaultsOnly)
		float Strength;

	
	virtual void Tick(float Delta) override;
	
};

.cpp


#include "C_Car.h"
#include "C_CarPawn.h"
#include "Components/SkeletalMeshComponent.h"
#include "PhysicsEngine/BodyInstance.h"
#include "Engine.h"
#include "EngineUtils.h"
#include "Gravity_Actor.h"


void AGravity_Actor::Tick(float Delta)
{
	//itterate through all physics actors and addforce -980 * actor mass towards here
	/*for (TObjectIterator<AC_CarPawn> Itr; Itr; ++Itr)
	{
		if (Itr->IsA(AC_CarPawn::StaticClass()))
		{
			// Determine direction vector using Dir = B - A
			FVector CarLocation = Itr->GetActorLocation();
			FVector MyLocation = GetActorLocation();
			FVector Direction = MyLocation - CarLocation;
			// Normalize the direction to a unit vector.
			Direction.Normalize();
			Direction *= Strength * Itr->GetMesh()->GetBodyInstance()->GetBodyMass();

			if (GEngine)
			{
				GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, Itr->GetName());//shows nothing
			}

			Itr->GetMesh()->SetSimulatePhysics(true);
			Itr->GetMesh()->AddForce(Direction);//GetBodyInstance()->//no effect
		}

	}*/

	for (TActorIterator<AC_CarPawn> ActorItr(GetWorld()); ActorItr; ++ActorItr)
	{
		if (GEngine)
		{
			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, ActorItr->GetName());//shows nothing
		}

		// Determine direction vector using Dir = B - A
		FVector CarLocation = ActorItr->GetActorLocation();
		FVector MyLocation = GetActorLocation();
		FVector Direction = MyLocation - CarLocation;
		// Normalize the direction to a unit vector.
		Direction.Normalize();
		Direction *= Strength * ActorItr->GetMesh()->GetBodyInstance()->GetBodyMass();

		ActorItr->GetMesh()->AddForce(Direction);////no effect
                //ActorItr->GetMesh()->GetBodyInstance()->AddForce(Direction);//no effect
	}
}

thanks

edit:
hmm just seen this
https://docs.unrealengine.com/latest/INT/API/Runtime/Engine/Engine/FTickFunction/

edit2:
yes!!!
success, didnt know you had to enable tick

PrimaryActorTick.bCanEverTick = true;