Game actors in array are not following instructions in For Each Loop. (Activate and Deactivate Issues)

Hi, I am a bit new to UE, but am working on a game where you attract objects to you. That part works pretty good.

I have a small platform that activates a power-up that allows the player to attract things from further away for a small amount of time.

Here is the collectable.

There are two collision spheres. Normally, the player interacts with the Sphere collider, but upon getting the power up platform, the Sphere is deactivated and SphereBIG is activated. The only difference is the scale.

The power-up platform’s blueprint goes like this.

I am using the Cast All Actors node so that the “potlicker”–I know, it’s a fun name–power-up can talk to all the “collectable” objects in the level at the same time. The Collectable objects never get spawned in after the level starts. They are all placed by hand.

It looks like stepping on the Potlicker platform does cause the script to iterate through all of the Collectable objects, but it seems like the spheres are not being turned on and off as instructed.

THe way it should work is that when the player overlap (step on) the platform, it deactivates the collision box on the platform, then gets all the actors in the “Collectable” class. After deactivating Sphere and activating Sphere BIG on all of the objects, it then turns off the collider on the platform , waits for a number of seconds as a sort of “cool down” then, reactivates Sphere and deactivates Sphere BIG. … but it doesn’t seem to be doing that.

When I step on the platform, Sphere BIG does not seem to be active and Sphere doesn’t seem to deactivate either.

Am I missing something?

Thanks.

I haven’t looked at your code in detail, but I must confess, I don’t know what the purpose of those (de)-activate nodes is.

They don’t work for me either, best to choose another method, probably based on player distance.

The screenshot is too small to figure out what is really going on unless you’re an CSI agent. This bit looks quite dodgy at a glance:

You’re accessing the last element from the loop after the loop completed its interaction. Taking into account that GetAll fetches actors, there is no way of knowing what this does.

If you want to affect all actors after the Delay again, you will need to start new loop.

Hi Clockwork, thanks for the reply. (I’ve actually seen you mentioned in the Unreal streams for your helpful replies).

The Deactivate is to turn large collider (Sphere BIG) off. It’s pretty much a switch.

When the player ativates the powerup, all of the Collectable objects should switch from their normal collider to the large collider.

Everynone, lol sorry about that.

But you do have a great point. Pulling the attributes from the loop after the loop ended means that they aren’t being used… so I’d actually have to run TWO ForEach loops. One to start, and then one to change the object back… That seems costly, but I honestly can’t think of another way to keep in communication with the Collectable objects.

Even if I don’t use Activate/Deactivate to turn things on and off, I still have to get things on the collectable.

Maybe it would be wiser in the long run to define something on the player that pulls the objects closer. instead of depending on each object to do it.

Bu

Precisely.

There is the picture, in better quality.

Wouldn’t doing ForEach loops like that be costly?

This

only exist during the loop. But you using it here

after the loop…

Ah okay. I am now trying this… but as you mentioned, Activate/Deactivate doesn’t seem to be working.

Here is the platform the player steps on.


(NOTE: I realize that number at the top left is coving it, but that is the Box Collider. I may change it out later to a better fitting one.)

I changed it to a Trigger thinking that things would work differently, but nope. The “box” collider is what the player is overlapping with and I don’t want the player to be able to interact with it during the “cooldown” delay node. So I am trying to disable it. Maybe I should just go back to changing collisions states.

Like I say, those nodes don’t work, and it’s not a good way to do it anyway… :wink:

A much easier way is for the player to just tell the blueprint to move toward them and give them a distance.

You can do it with event dispatchers. The objects listen to the player. The player can make one call, and all the objects know the distance and if they need to move.

When the player steps on the plinth, you can make a new call with a greater distance.

To give it a cooldown period, you can just set a timer, and not make the call again until the timer has run out.

This is about dispatchers:

I have to dash now, but could help you with it later if you get stuck…

In the player

in the blueprint

Tell me if it’s a bit much, and I’ll show you a way with just the blueprints and for loops.

I’ll give this a shot! Thanks. Wow the event dispatcher sounds SUPER useful! I’ll give that a try.

The current way that things are attracted is with a timeline node controlled in the collectable script.

This is from the Collectable object.

So I might be able to get the location and do something similar in the player… or maybe I can send events to the Collectable… I’ll give it a shot and write back.

I’ve actually gotten a ton of help from viewing other topics on this forum, so I’ll try to keep details of what I’m doing here for future use as well.

You’re on the right track, good stuff.

Basically, you send an event to all listening attractables in one go. You could send the player location and they figure out how far they are from the player. Or you could send a distance, and they figure out if they are < that distance from the player.

If so, they can start the timeline.

You can also setup exactly the same sort of thing for ‘stop attracting’, piece of pie after the first part.

When the attraction rate is greater, you can pass the rate also, and use that to change the play rate of the timeline. Etc…

Any probs, just reply to this and I’ll take a look.

BTW, to get the parameter working on the main dispatcher ( it wants a signature ), just create a function in the player and give it the same sort of parameter. You can then look that up in the signature list… :slight_smile:

Thanks! I just realized that the Collectables are already getting the player position and comparing it to their’s for the timeline to work.

As a bit of amusement for myself, I just told the timeline to trigger on BeginPlay and all the Collectables from everywhere got pulled to the player, so I should be able to just compare and use a subtract vector… or maybe a Distance To within the Collectable blueprint?

Although the Player doesn’t exist until the game starts.

They only need to calculate when they’re triggered.

Then they can say:

Hm I see. The question is when should the Collectable be triggered? Originally, it was triggered on collision of the Sphere Collider, But it if’s waiting to be overlapped, that means the player has to come near it anyway.

So I could only imagine the Collectable cubes calculating the location on all of the frames.

A similar scenario arrises if I use a Distance To node from within the player.

I can only imagine something is always checking the distance constantly. Am I missing something?

This is what the dispatcher is for. The dispatcher says ‘attract now’, and the collectables take a look at how far they are from the player. They only start moving if they’re within a certain distance.

If the distance is good, they start the timeline.

Tell me if you’re not clear and I’ll put some code together.

Hm, I still don’t think I’m getting it. I understand what the logic is suppose to do. But how will the power-up platform know when the player steps on it? Stepping on it is what activates the powerup to pull things from further away.

I was thinking I could have the platform send a message to the player which would then send an event to all of the Collectables, but it seemed like I had to do too many work-arounds. I wish I could just send a message from one actor to another with Event Dispatch, but it looks I’d still have to cast which gets challenging when it comes to communicating between actors. Is there no simple way to communicate between actors? Getting all the actors in a specific class is the only way I’m aware of to use something from all actors of one type or controlling something that’s not currently in the world.

I have found a different solution though thanks to your help.

This is from the Platform you step on to activate the powerup.


I’m still getting all of the class actors for Collectable, but I am now chaning the amount of distance.

Here is what’s happening in the COllectable object.

I feel like this is a really dirty way to do it, but the Collectables are just checking all of the time and if they are between a specific number I set as a variable a d the distance, they come towards the player and the other stuff from above happens.

I know I didn’t do exactly what you were suggesting and this may not be best practices, but this project is more of a learning experience of how to use blueprints in general as this is my very first time ever using UE to this capacity and also it’s a game jam so I am starting to run short on time.

Thank you again for you help! That goes for everyone here. I have learned a lot about Blueprints just from doing this.

I’ll setup some code for the AllActors method and post it in a little while.

Don’t worry about the dispatcher, it’s just a slightly more efficient way of doing it, but doesn’t matter for now…

Thanks!

Yeah it looks really handy and I’m sure I’ll be using it later.

Ok. This is the code in the attractable object:

By default, I set Attracting to false and Distance to 800.

In the player, I have

So I can press O to start or stop the attraction.

And what I want, is when I step on the pad, I get to attract stuff from further away, but only for 2 seconds, and I can’t start it again until that 2 seconds has run out:

That’s it, the whole thing

attract

1 Like