Player-Sided Effect Spawning System

Hello!
I’m new to the workshop and I have basic programming knowledge. I’ve been looking for a way to spawn effects at different locations that only the event player would be able to see and interact with. In short, I want every player to have their own effects spawn at different locations.

If this can be done, I’d be very thankful to anyone who could help me out.

You can use player variables for this. Also, what do you mean by “interact with” them? There are a lot of ways to interact with effects, some more or less difficult to implement.

The information you gave me isn’t enough to be 100% certain on what you want exactly. But maybe you can get started with this:

You do want a different location for each player, right? You could for example define all 12 locations in an array:

rule 1 - ongoing global

condition:
- none

action:
- set global variable at index(effectLocations, 0, *position of the effect for player 0 in team 1*)
- set global variable at index(effectLocations, 1, *position of the effect for player 1 in team 1*)
- set global variable at index(effectLocations, 2, *position of the effect for player 2 in team 1*)
- ...
- set global variable at index(effectLocations, 10, *position of the effect for player 4 in team 2*)
- set global variable at index(effectLocations, 11, *position of the effect for player 5 in team 2*)

Now you have an array of the positions of the effects. The next rule you need is to initialize each player:

rule 2 - ongoing each player

condition:
- has spawned(event player) == true

action:
- if(compare(team of(event player), ==, team1))
- set player variable(event player, effectPosition, value in array(global variable(effectLocations), slot of(event player)))
- else()
- set player variable(event player, effectPosition, value in array(global variable(effectLocations), add(slot of(event player), 6)))
- end()
- create effect(event player, ring, red, player variable(event player, effectPosition), 1, visible to position and radius)
- set player variable(event player, effectID, last created entity)

This rule creates the effect for each player. At first, the “if” action decides wether the player is in team 1 or team 2. As I have put all the positions in only 1 array, I use the indices 0-5 for team 1 and 6-11 for team 2.
Next, the position of the effect of the player gets stored in a player variable, so I can reference it easier later.
Then the effect gets created. It is a red ring with radius 1. As I have set the visibility to “event player”, it is visible to the event player only.
Finally I set the player variable “effectID” to “last created entity”. This is the ID of the last created effect. It is useful to store it in a variable, so it is possible to destroy a specific effect later.

The next rule handles the interaction with the effect:

rule 3 - ongoing each player

condition:
- is button held(event player, interact) == true
- distance between(event player, player variable(event player, effectPosition)) <= 1

action:
- wait(0.25)
- *do something*

The first condition checks for the button input. As the “interact” button is only used for symmetras teleporter, it is a good choice here.
The second condition checks wether the distance between the event player and his effect is smaller than the radius of the effect. This means the player is inside the red ring.
The first action inside the rule is a wait action, to prevent rapidly pressing the interact button to retrigger the event. This has been useful in my experience.
After this you can do whatever you want to happen when interacting with the effect.

I hope this will help you getting started and if you have further questions, just ask :slight_smile:

2 Likes

Thank you so much for your detailed response! Despite my question being unclear as you said, it’s exactly what I wanted to achieve.

I’ve also managed to add multiple effects that spawn at random positions!

The only thing I’m trying to achieve as of now is to avoid letting more than one effect spawn at the same position. Do you know how I could make that work?

1 Like

After you have chosen the random position, you remove it from the array:

- set player variable(event player, effectPosition, random value in array(global variable(effectLocations)))
- modify global variable(effectLocations, remove from array, player variable(event player, effectPosition))

If you want to readd the position to the array later, you can use:

- modify global variable(effectLocations, append to array, player variable(event player, effectPosition))
1 Like

That’s genius… I didn’t think of it that way. Thank you so much for your help!

Btw, I’m working on another deathmatch project right now. I’m trying to create an HUD effect at the “Top” under the score bars that appear when the deathmatch begins. So far I’ve only figured out how to make it appear between the time remaining and the score bars.

Do you know how I could make it appear there by any chance?

1 Like

You can’t reposition HUD texts. You can put them left, right, top and change their order, but thats it.
You could use an inworld text instead. As the position you use the eye position of the event player, add the facing direction and then a couple of other vectors to move it exactly to where you want:

create in-world text(event player, ..., add(add(add(eye position(event player), multiply(facing direction of(event player), 0.5)), multiply(world vector of(left, event player, rotation)), 0.05), multiply(normalize(cross product(facing direction of(event player), world vector of(left, event player, rotation))), 0.05)), ...)

The numbers that get multiplied with the vectors are just example numbers here. With these numbers you can control the length of the vectors. You need to experiment a little bit with them to place the text exactly where you want.

The directions you can use are:

  • the facing direction. Decrease the multiplier to place it closer to the event players screen. If you use a negative number you can place it behind the event player (wich makes it offscreen, but I formally mentioned it)
  • world vector of(left, event player, rotation) / world vector of(right, event player, rotation). To move the text slightly to the left or right.
  • normalize(cross product(facing direction of(event player), world vector of(left, event player, rotation))). This is the “up” vector but relative to the facing of the player. If you would just use “world vector of(up)” here it would always be the same direction, independent of the vertical facing of the event player.
    If you want to slightly move the text down instead, you can use a negative multiplier.

I copied the rule but the text goes berserk if any screen shake is applied.

Yes thats the disadvantage.