- Home /
Modify a boolean for all instances of a class
Hello friends, I'm in my first week of learning Unity. What I am trying to achieve in this script is:
All prefabs "ssr", of type "aircraft" move on their y axis once every 5 seconds.
My approach is probably quite inefficient as I'm still learning, but I'm achieving this by running a script gameControl on an object also called gameControl. This script contains a coroutine that loops once every 5 seconds.
The aircraft script has a condition boolean "a" that will ensure that as part of the 5 second looped coroutine, the aircraft will only move by the variable groundSpeed a single time.
I have it working on the first instance of ssr, but subsequent instantiated prefabs are not working and stay still.
Scripts are below, I'm losing my mind a little on this one... thanks for your help!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class aircraft : MonoBehaviour
{
public float groundSpeed;
//public aircraft ssr; do I actually need this?
public static gameControl controls;
public static bool a;
void Awake()
{
controls = GetComponent<gameControl>();
groundSpeed = 10.0f;
}
void Update()
{
if (gameControl.radarUpdate == true)
{
while(a == true)
{
transform.position += Vector3.up * groundSpeed;
Debug.Log("moved by " + groundSpeed);
a = false;
Debug.Log("a is " + a);
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class gameControl : MonoBehaviour
{
public GameObject aircraftSymbol;
public int track, x, y, a;
public static bool radarUpdate = false, gameOver = false; //removed static
public static aircraft link;
void Awake()
{
//Application.targetFrameRate = 30; force framerate if required
link = GetComponent<aircraft>();
StartCoroutine(radar());
}
void Update()
{
if (Input.GetKeyDown("w"))
{
print("w");
Vector3 pos = transform.position + new Vector3(50, 50, 1);
Quaternion rot = Quaternion.Euler(0, 0, 0);
Instantiate(aircraftSymbol, pos, rot);
}
}
public IEnumerator radar()
{
while (gameOver == false)
{
aircraft.a = true;
radarUpdate = true;
print("updating radar");
yield return new WaitForSeconds(1.0f);
radarUpdate = false;
print("not updating radar");
yield return new WaitForSeconds(2.0f);
}
}
}
Answer by mjrsaunders · Nov 30, 2021 at 07:47 AM
Worked it out by using FindObjectsWithTag in conjunction with GetComponent as per below script replacing the old coroutine:
public IEnumerator radar()
{
while (gameOver == false)
{
GameObject[] go;
go = GameObject.FindGameObjectsWithTag("ssrTag");
foreach (GameObject ssr in go)
{
aircraft sc = ssr.GetComponent<aircraft>();
sc.a = true;
}
radarUpdate = true;
print("updating radar");
yield return new WaitForSeconds(1.0f);
radarUpdate = false;
print("not updating radar");
yield return new WaitForSeconds(2.0f);
}
}
Shouldnt this be?
public IEnumerator radar()
{
while (gameOver == false)
{
print("updating radar");
radarUpdate = true;
GameObject[] go;
go = GameObject.FindGameObjectsWithTag("ssrTag");
foreach (GameObject ssr in go)
{
aircraft sc = ssr.GetComponent<aircraft>();
sc.a = true;
}
radarUpdate = false;
print("not updating radar");
yield return new WaitForSeconds(3.0f);
}
}
Yes, your way is much cleaner. It still worked fine with the code I posted, just wasn't that worried about that part while I was working on the single update every 5 seconds (which does work with my messy code).
Answer by andrew-lukasik · Nov 30, 2021 at 11:35 AM
Entertain this:
AircraftComponent.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AircraftComponent : MonoBehaviour
{
public static List<AircraftComponent> Instances = new List<AircraftComponent>();
public static HashSet<AircraftComponent> InstancesSsrActive = new HashSet<AircraftComponent>();// hashset is similar to list<t> but also prevents duplicate entries
public Vector3 velocity = new Vector3( 0 , 10 , 0 );
public bool isSsrTransponderActive = true;
void OnEnable ()
{
Instances.Add( this );
if( isSsrTransponderActive ) InstancesSsrActive.Add( this );
}
void OnDisable ()
{
Instances.Remove( this );
InstancesSsrActive.Remove( this );
}
void Update ()
{
transform.position += velocity * Time.deltaTime;
}
public void DisableSsrTransponder ()
{
isSsrTransponderActive = false;
InstancesSsrActive.Remove( this );
}
}
RadarComponent.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RadarComponent : MonoBehaviour
{
[SerializeField] float _radarRefreshRate = 5f;
[SerializeField] Mesh _iconMesh = null;
[SerializeField] Material _iconMaterial = null;
Matrix4x4[] _iconTransforms = new Matrix4x4[0];
void OnEnable ()
{
InvokeRepeating( nameof(RadarPing) , 0 , _radarRefreshRate );
}
void OnDisable ()
{
CancelInvoke();
}
void LateUpdate ()
{
Graphics.DrawMeshInstanced(
mesh: _iconMesh ,
submeshIndex: 0 ,
material: _iconMaterial ,
matrices: _iconTransforms
);
}
public void RadarPing ()
{
int newLength = AircraftComponent.InstancesSsrActive.Count;
if( _iconTransforms.Length!=newLength ) _iconTransforms = new Matrix4x4[ newLength ];
int i = 0;
foreach( var ssrTransponder in AircraftComponent.InstancesSsrActive )
_iconTransforms[i++] = Matrix4x4.Translate( ssrTransponder.transform.position );
}
}
PlayerInputController.cs
using UnityEngine;
public class PlayerInputController : MonoBehaviour
{
[SerializeField] GameObject _aircraftPrefab;
void Update ()
{
if( Input.GetKeyDown(KeyCode.W) )
Instantiate( _aircraftPrefab , Random.insideUnitCircle*10f , Quaternion.identity );
}
}
player input is separated from radar & aircraft-specific code
aircrafts move however they want, radar does not control aircrafts
radar looks for aircrafts in dedicated & easy to manage lists
Thankyou so much for the detailed alternative. I was vaguely aware of lists being an option and will have a proper look at your suggestion so I can learn how to do it that way as well. Really appreciate it!
Your answer
Follow this Question
Related Questions
Are sprites reference (script) loaded every time? 0 Answers
Persisting Prefabs across scenes 1 Answer
Animations on instantiated prefabs not working 0 Answers
how do i get the audio and prefabs to work in space shooter? 0 Answers
Switching between prefabs 0 Answers