Reputation: 51
I have an enemy spawner that spawns up to 10 enemies at a time. I want that when a player collects an item the value in a script that is on all the spawning enemies will change. Let's say that their speed is equal to 5, I want to do that after the player picks up a potion the speed will change to 3. I thought about creating an array of the scripts and then changing the value in each one using a loop, like that:
public class PlayerController : MonoBehaviour
{
public EnemyController[] enemCon;
void Start()
{
enemCon = FindObjectsOfType<EnemyController>();
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag=="Potion")
{
for (int i=0; i<enemCon.Length;i++)
{
enemCon[i].speed = 3;
}
}
}
}
public class EnemyController : MonoBehaviour
{
public int speed=5;
}
But to do so I need to put the scripts in the inspector. The problem is that the enemies are being created during the game and so I cant use them in the inspector beforehand.
Is there a way to do such a thing?
Upvotes: 2
Views: 191
Reputation: 1
I think there are two main ideas how you can do that.
(If(pickedUp = "potion"))
and would have a reference to your enemy-spawner and loop over the list and set the speed of each enemy (GameObject.GetComponent<EnemyController>().getSpeed() = 3)
.void OnTriggerEnter2D(Collider2D other)
{
if (other.tag=="Potion"){
//the loop
}
}
I hope that helps and summarizes the two other posts.
Upvotes: 0
Reputation: 4711
Use a static variable for the speed.
A static variable will exist once across the entire application, and can be accessed through the Type in which it is declared. This approach is valid when you need a single variable accessible from everywhere.
Simply change you speed variable to static.
public class EnemyController : MonoBehaviour
{
public static int speed=5;
}
Now all enemies will have the same exact speed, and the speed can be changed easily.
EnemyController.speed = 3;
Upvotes: 1
Reputation: 447
Architecturally correct solution: you need a Player, a Spawner, an Event and a Rule entities. Player and Spawner are emitting events: OnPickUp(item)
and OnSpawn(entity)
. A Rule is a thing that describes on a high level how your game should behave in regards of particular mechanic. Following your example, you need a rule that modifies existing enemies (increase speed) and every next one that will be spawned after the Player picks up certain object (or a certain number of objects). So, the Rule in this case must:
OnPickUp
event and count particular objects,OnSpawn
event and store references to spawned enemies,From this point the logic is pretty obvious: now you'll have different objects with their own responsibilities and no one of them is not trying to do what it is not supposed to (like the Player counting pickups and changing monster's power).
With that structure (or similar) you'll easily expand the logic of your game, adding new rules. In Unity it's easier to store such persistent things as Rules as ScriptableObjects to be able to copy, modify and reference them on scene or in prefabs.
Upvotes: 0
Reputation: 1
Maybe try finding enemies every time the player picks up a potion. FindObjectsByType
allows to not sort them so it's faster, but FindObjectsOfType
would work too.
public class PlayerController : MonoBehaviour
{
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag=="Potion")
{
EnemyController[] enemCon = FindObjectsByType<EnemyController>(FindObjectsSortMode.None);
for (int i=0; i<enemCon.Length; i++)
{
enemCon[i].speed = 3;
}
}
}
}
Upvotes: 0