I want to make a script that loops through all game objects with the tag, Enemy
I modified a code snippet from here, and ended up with 2 errors.
Cannot Implicitly convert 'Unity.GameObject[]' to 'Unity.GameObject'
and
Error CS1579 foreach statement cannot operate on variables of type 'GameObject' because 'GameObject' does not contain a public instance definition for 'GetEnumerator'
If anyone could tell me why this is happening or a solution to this I would be very grateful, thanks in advance! Here is my code:
void FixedUpdate()
{
GameObject objects = GameObject.FindGameObjectsWithTag("Enemy");
var objectCount = objects.Length;
foreach (var obj in objects)
{
// Move the players accordingly
//var rb =
Vector2 direction = (player.position - transform.position).normalized;
obj.rigidbody.velocity = direction * moveSpeed;
}
}
FindGameObjectsWithTag
as the name hints returns a GameObject[]
.
In order tog et the attached Rigidbody2D
use GetComponent<Rigidbody2D>
It should be either GameObject[]
or simply var
/*GameObject[]*/ var objects = GameObject.FindGameObjectsWithTag("Enemy");
var objectCount = objects.Length;
foreach (var obj in objects)
{
// Move the players accordingly
var rb = obj.GetComponent<Rigidbody2D>()
Vector2 direction = (player.position - transform.position).normalized;
rb.velocity = direction * moveSpeed;
}
The second one was just a follow up error since you declared objects
as a GameObject
which indeed as the error says has no GetEnumerator
implementation.
In general it is not the best thing to use FindObjectsWithTag
repeatedly. I would rather use a pattern with a static
list of all existing instances like
// Put this component on your enemy prefabs / objects
public class EnemyController : MonoBehaviour
{
// every instance registers to and removes itself from here
private static readonly HashSet<EnemyController> _instances = new HashSet<EnemyController>();
// Readonly property, I would return a new HashSet so nobody on the outside can alter the content
public static HashSet<EnemyController> Instances => new HashSet<EnemyController>(_instances);
// If possible already drag the Rigidbody into this slot via the Inspector!
[SerializedField] private Rigidbody2D rb;
// public read-only access
public Rigidbody2D Rb => rb;
private void Awake()
{
if(!rb) rb = GetComponent<Rigidbody2D>();
_instances.Add(this);
}
private void OnDestroy()
{
_instances.Remove(this);
}
}
and then use
var enemies = EnemyControler.Instances;
foreach (var enemy in enemies)
{
// Move the players accordingly
Vector2 direction = (player.position - transform.position).normalized;
enemy.Rb.velocity = direction * moveSpeed;
}