on this line, which is line 10 it says "AudioClip" does not take a constructor that takes 0 arguments. How to fix it? I know that AudioClip is a default class in Unity. What parameters shall I pass there or how to solve this issue?
AudioClip _clipRecord = new AudioClip()
int _sampleWindow = 128;
How to solve it?
public class MicInput : MonoBehaviour {
public static float MicLoudness;
private string _device;
//mic initialization
void InitMic(){
if(_device == null) _device = Microphone.devices[0];
_clipRecord = Microphone.Start(_device, true, 999, 44100);
}
void StopMicrophone()
{
Microphone.End(_device);
}
AudioClip _clipRecord = new AudioClip();
int _sampleWindow = 128;
//get data from microphone into audioclip
float LevelMax()
{
float levelMax = 0;
float[] waveData = new float[_sampleWindow];
int micPosition = Microphone.GetPosition(null)-(_sampleWindow+1); // null means the first microphone
if (micPosition < 0) return 0;
_clipRecord.GetData(waveData, micPosition);
// Getting a peak on the last 128 samples
for (int i = 0; i < _sampleWindow; i++) {
float wavePeak = waveData[i] * waveData[i];
if (levelMax < wavePeak) {
levelMax = wavePeak;
}
}
return levelMax;
}
void Update()
{
// levelMax equals to the highest normalized value power 2, a small number because < 1
// pass the value to a static var so we can access it from anywhere
MicLoudness = LevelMax ();
}
bool _isInitialized;
// start mic when scene starts
void OnEnable()
{
InitMic();
_isInitialized=true;
}
//stop mic when loading a new level or quit application
void OnDisable()
{
StopMicrophone();
}
void OnDestroy()
{
StopMicrophone();
}
// make sure the mic gets started & stopped when application gets focused
void OnApplicationFocus(bool focus) {
if (focus)
{
//Debug.Log("Focus");
if(!_isInitialized){
//Debug.Log("Init Mic");
InitMic();
_isInitialized=true;
}
}
if (!focus)
{
//Debug.Log("Pause");
StopMicrophone();
//Debug.Log("Stop Mic");
_isInitialized=false;
}
}
}
on this line, which is line 10 it says "AudioClip " does not take a constructor that takes 0 arguments. How to fix it?
----AudioClip _clipRecord = new AudioClip()----
---int _sampleWindow = 128;----
How to solve it?
In the AudioClip class add the following:
public AudioClip(){}
This issue arises because although you do initially get an empty ctor when you create a class, you lose that once you create a non-empty ctor so you MUST add the empty one if you wish to use it.
In the new unity version just change new AudioClip();
with
AudioClip _clipRecord = null;
Hope it helps
Related
I have this simplified version of my code that I'm working on. Briefly, I create a list of 5000 Agents and I want each of them to perform a simple raycast and print if the ray hits something.
I want the tasks to be multi-threaded so I'm using for this example the IJob interface. The Job part of the code works OK for any other operation, but I can't make it work for simple raycasting. So here's the code:
using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
public class simpleRaycast : MonoBehaviour
{
[SerializeField] private List<Agent> agentList;
public class Agent
{ }
void Start()
{
agentList = new List<Agent>();
for (int i = 0; i < 5000; i++)
{
agentList.Add(new Agent());
}
}
void Update()
{
NativeList<JobHandle> jobHandles = new NativeList<JobHandle>(Allocator.TempJob);
NativeArray<RaycastCommand> raycastCommands = new NativeArray<RaycastCommand>(1, Allocator.TempJob);
NativeArray<RaycastHit> raycasthits = new NativeArray<RaycastHit>(1, Allocator.TempJob);
raycastCommands[0] = new RaycastCommand(Vector3.zero, Vector3.down);
for (int i = 0; i < agentList.Count; i++)
{
RaycastTest job = new RaycastTest { raycastHit = raycasthits[0] };
JobHandle _jobHandleRay = RaycastCommand.ScheduleBatch(raycastCommands, raycasthits, 1);
_jobHandleRay.Complete();
JobHandle jobHandle = job.Schedule();
jobHandles.Add(jobHandle);
}
JobHandle.CompleteAll(jobHandles);
jobHandles.Dispose();
raycastCommands.Dispose();
raycasthits.Dispose();
}
}
[BurstCompile]
public struct RaycastTest : IJob
{
public RaycastHit raycastHit;
public void Execute()
{
if (raycastHit.collider != null)
{
Debug.Log("hit");
}
}
}
What am I missing here? I tried the suggested approach in the Raycast Command documentation but it obviously failed.
The main error I get is this :
UnityException: FindObjectFromInstanceID can only be called from
the main thread. Constructors and field initializers will be executed
from the loading thread when loading a scene. Don't use this function
in the constructor or field initializers, instead move initialization
code to the Awake or Start function.
UnityEngine.RaycastHit.get_collider () (at
:0) RaycastTest.Execute () (at
Assets/scripts/simpleRaycast.cs:60)
Unity.Jobs.IJobExtensions+JobStruct`1[T].Execute (T& data,
System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData,
Unity.Jobs.LowLevel.Unsafe.JobRanges& ranges, System.Int32 jobIndex)
(at :0)
If anyone here have any raycasts in their Unity jobs please enlighten me, even part of your code will help a lot, I failed to find any examples online and the documentation on the subject is scarce.
SUMMARY:
I need Raycasts in a function I want to multithread using the Unity Job System. I tried the approach that was suggested in the documentation but it failed so I tried for some time to move stuff around without really knowing what I was doing.
The error is coming from
UnityEngine.RaycastHit.get_collider ()
As the error is telling you: You can't use RaycastHit and its properties within a job.
I think you misunderstood the concept of RaycastCommand a little => You want do perform the raycasts themselves async within Jobs -> but then you want to handle the results in the Unity main tread after the CompleteAll!
See e.g. the Example
It depends a bit what you are after
If you just want to check if ANY of those 5000 raycasts hits something
=> You only need 1 single result
public class simpleRaycast : MonoBehaviour
{
[SerializeField] private List<Agent> agentList;
[Serializable]
public class Agent
{
// TODO somehow provide ray origin and direction
}
void Start()
{
agentList = new List<Agent>();
for (int i = 0; i < 5000; i++)
{
agentList.Add(new Agent());
}
}
void Update()
{
var raycastCommands = new NativeArray<RaycastCommand>(agentList.Count, Allocator.TempJob);
// only need a single result
var raycasthits = new NativeArray<RaycastHit>(1, Allocator.TempJob);
for (int i = 0; i < agentList.Count; i++)
{
var agent = agentList[i];
// TODO: where does every agent get origin and direction from?
raycastCommands[i] = new RaycastCommand(agent.origin, agent.direction, QueryParameters.Default);
}
var handle = RaycastCommand.ScheduleBatch(commands, raycasthits, 1, 1, default(JobHandle));
handle.Complete();
var hasHit = raycasthits[0].collider != null;
if(hasHit)
{
Debug.Log("Has hit at least one object!");
}
raycastCommands.Dispose();
raycasthits.Dispose();
}
}
Or you want to get all hits then you probably need up to 5000 results. However afaik this way there is no way to tell exactly which agent has hit which object. The job can only tell you that the given set of raycasts has hit a set of colliders (up to the given amount).
public class simpleRaycast : MonoBehaviour
{
[SerializeField] private List<Agent> agentList;
[Serializable]
public class Agent
{
// TODO somehow provide ray origin and direction
}
void Start()
{
agentList = new List<Agent>();
for (int i = 0; i < 5000; i++)
{
agentList.Add(new Agent());
}
}
void Update()
{
var raycastCommands = new NativeArray<RaycastCommand>(agentList.Count, Allocator.TempJob);
var raycasthits = new NativeArray<RaycastHit>(agentList.Count, Allocator.TempJob);
for (int i = 0; i < agentList.Count; i++)
{
var agent = agentList[i];
// TODO: where does every agent get origin and direction from?
raycastCommands[i] = new RaycastCommand(agent.origin, agent.direction, QueryParameters.Default);
}
var handle = RaycastCommand.ScheduleBatch(commands, raycasthits, 1, agentList.Count, default(JobHandle));
handle.Complete();
foreach (var hit in raycasthits)
{
if (hit.collider != null)
{
Debug.Log($"Has hit {hit.collider}", hit.collider);
}
}
raycastCommands.Dispose();
raycasthits.Dispose();
}
}
The post is a bit long but the scripts are connected to each other.
When the game start first time it's saving after 3 seconds and fading for 3 seconds.
but in the game later when it's saving again it's showing the save text fading only once.
In this script I'm making the save and also set the time to start the saving and the time it will fade in/out :
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class SaveLoad : MonoBehaviour
{
public FadeInOutSaveGameText fadeInOutSaveGame;
public float timeToStartSaving;
public float savingFadeInOutTime;
private List<GameObject> objectsToSave = new List<GameObject>();
private void Awake()
{
SaveSystem.Init();
var objectsWithGenerateGuid = GameObject.FindObjectsOfType<GenerateGuid>().ToList();
if (objectsWithGenerateGuid.Count > 0)
{
for (int i = 0; i < objectsWithGenerateGuid.Count; i++)
{
objectsToSave.Add(objectsWithGenerateGuid[i].gameObject);
}
}
Debug.Log("Start");
for (int i = 0; i < objectsToSave.Count; i++)
{
Debug.Log($"{i}");
Debug.Log($"{objectsToSave[i].name}");
}
Debug.Log("End Init");
}
public void Save()
{
SaveGame saveGame = new SaveGame();
saveGame.saveObjects = new List<SaveObject>();
for (int i = 0; i < objectsToSave.Count; i++)
{
SaveObject saveObject = new SaveObject();
saveObject.transformSaver = new TransformSaver();
Debug.Log($"{i}");
Debug.Log($"{objectsToSave[i].name}");
saveObject.gameObjectUniqueID = objectsToSave[i].GetComponent<GenerateGuid>().uniqueGuidID;
var x = objectsToSave[i].GetComponents<Component>();
var stateQueryComponent = x.Where(component => component is IStateQuery).ToList();
List<KeyToValue> componentsState = new List<KeyToValue>();
foreach (var z in stateQueryComponent)
{
var w = z as IStateQuery;
componentsState.Add(new KeyToValue(w.UniqueId.ToString(), w.GetState()));
}
saveObject.transformSaver.position = objectsToSave[i].transform.position;
saveObject.transformSaver.rotation = objectsToSave[i].transform.rotation;
saveObject.transformSaver.scaling = objectsToSave[i].transform.localScale;
saveObject.componentsState = componentsState;
saveGame.saveObjects.Add(saveObject);
}
string json = JsonUtility.ToJson(saveGame);
SaveSystem.Save(json);
}
public void Load()
{
Dictionary<string, GameObject> uniqueIdToObject = objectsToSave
.ToDictionary(o => o.GetComponent<GenerateGuid>().uniqueGuidID, o => o);
var saveString = SaveSystem.Load();
if (saveString != null)
{
SaveGame saveGame = JsonUtility.FromJson<SaveGame>(saveString);
foreach (var saveObject in saveGame.saveObjects)
{
List<KeyToValue> loadedComponents = saveObject.componentsState;
var objectToSetState = uniqueIdToObject[saveObject.gameObjectUniqueID];
objectToSetState.transform.position = saveObject.transformSaver.position;
objectToSetState.transform.rotation = saveObject.transformSaver.rotation;
objectToSetState.transform.localScale = saveObject.transformSaver.scaling;
var y = objectToSetState.GetComponents<Component>();
var z = y.Where(component => component is IStateQuery).ToList();
Dictionary<string, IStateQuery> zz = z.ToDictionary(sq => (sq as IStateQuery).UniqueId.ToString(), sq => sq as IStateQuery);
foreach (KeyToValue keyvalue in loadedComponents)
{
zz[keyvalue.Key].SetState(keyvalue.Value);
}
}
}
}
public IEnumerator SaveWithTime()
{
yield return new WaitForSeconds(timeToStartSaving);
Save();
StartCoroutine(fadeInOutSaveGame.OverAllTime(savingFadeInOutTime));
}
}
At the bottom I created the to save with time :
public IEnumerator SaveWithTime()
{
yield return new WaitForSeconds(timeToStartSaving);
Save();
StartCoroutine(fadeInOutSaveGame.OverAllTime(savingFadeInOutTime));
}
The method OverAllTime make the fading depending on the time I set in this case 3 seconds :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FadeInOutSaveGameText : MonoBehaviour
{
public Canvas canvas;
public float fadingSpeed;
private bool stopFading = false;
private const float THRESHOLD = 0.01F;
// Start is called before the first frame update
void Start()
{
}
IEnumerator CanvasAlphaChangeOverTime(Canvas canvas, float duration)
{
float alphaColor = canvas.GetComponent<CanvasGroup>().alpha;
while (true)
{
alphaColor = (Mathf.Sin(Time.time * duration) + 1.0f) / 2.0f;
canvas.GetComponent<CanvasGroup>().alpha = alphaColor;
// only break, if current alpha value is close to 0 or 1
if (stopFading && Mathf.Abs(alphaColor) <= THRESHOLD)//if (stopFading && (Mathf.Abs(alphaColor) <= THRESHOLD || Mathf.Abs(alphaColor - 1) <= THRESHOLD))
{
break;
}
yield return null;
}
}
public IEnumerator OverAllTime(float time)
{
StartCoroutine(CanvasAlphaChangeOverTime(canvas, fadingSpeed));
yield return new WaitForSeconds(time);
stopFading = true;
}
}
And in this script at the bottom I'm starting the save :
private void Update()
{
if(dimLights.lightsDimmed == true && lightsDim == false && unlockCarte.HasOpened() == true
&& MenuController.LoadSceneForSavedGame == false)
{
m_state.naviLightsIntensity = dimLights.lightsToDim[0].intensity;
lightsDim = true;
var brainBlendTime = Camera.main.GetComponent<CinemachineBrain>();
saveLoad.timeToStartSaving = brainBlendTime.m_DefaultBlend.m_Time;
StartCoroutine(saveLoad.SaveWithTime());
}
}
I'm setting the timeToStartSaving to the time it takes to blend from one cinemachine camera to another camera in this case 5 seconds.
I used break points and it's getting to the SaveWithTime method when the value of timeToStartSaving is 5 and the value of savingFadeInOutTime stay 3 as before. Only the timeToStartSaving variable vlaue was 3 and changed to 5.
but ion the game the fading happens only once one time instead 3 times.
in the start of the game first time saving it does fading 3 times for 3 seconds. but on the second saving for some reason it's fading only one time even if the value of savingFadeInOutTime is 3.
You have to reset stopFading, otherwise your loop will always break after the first time reaching the zero threshold.
public IEnumerator OverAllTime(float time)
{
stopFading = false; // reset this, otherwise it stays true, after the first run
StartCoroutine(CanvasAlphaChangeOverTime(canvas, fadingSpeed));
yield return new WaitForSeconds(time);
stopFading = true;
}
I know, so many of people have asked this question. I have gone to all of those posts, and none of the solutions have solved my problem. i am creating a level progress bar , here in this script i am trying to update text (levelNumber) and add +1 to levelNumber every time level is completed, here i am using playerprefs to save levelNumber so data can passes through next levels(scenes). but problem is levelNumber not even updating in Text field , as per script Text_1 should start from 0 and Text_2 from 1 when game starts its showing values which i have given in inspector 1 and 2. to confirm that i have changed values in inspector to 21 and 30 again when game starts its showing 21 and 30. that means UI Text not updating from script .
public class PrograssBar : MonoBehaviour
{
[SerializeField] private Text Text_1;
[SerializeField] private Text Text_2;
private int levelNumber = 0;
[SerializeField] Transform startTransform;
Transform finishTransform;
[SerializeField] Slider slider;
float maxDistance;
void OnEnable()
{
levelNumber = 0;
}
void Start()
{
finishTransform = GameObject.FindGameObjectWithTag("CloneGoal").GetComponent<Transform>();
maxDistance = getDistance();
levelNumber = PlayerPrefs.GetInt("LevelNumber");
}
void Update()
{
if (startTransform.position.z <= maxDistance)
{
float distance = 1 - (getDistance() / maxDistance);
setProgress(distance);
}
}
float getDistance()
{
return Vector3.Distance(startTransform.position, (finishTransform.position - new Vector3(0, 0, 22)));
}
void setProgress(float p)
{
slider.value = p;
}
private void LevelUp()
{
UpdateLevel(levelNumber + 1);
PlayerPrefs.SetInt("LevelNumber", levelNumber);
}
private void UpdateLevel(int levelNumber)
{
this.levelNumber = levelNumber;
Text_1.text = " " +this.levelNumber.ToString();
Text_2.text = " " +(this.levelNumber + 1).ToString();
}
}
The problem is that you never save your levelNumber to prefs during your execution, so your LevelUp function should look like:
private void LevelUp()
{
UpdateLevel(levelNumber + 1);
PlayerPrefs.SetInt("LevelNumber", levelNumber);
PlayerPrefs.Save();
}
See this doc
In the method private void UpdateLevel(int level) you're setting this.levelNumber = levelNumber.
And the attribute of a method is int level.
So you might want to do:
this.levelNumber = level;
And I'm not quite sure where you're calling the method private void LevelUp() since it's private and it's not called anywhere inside this class.
I'm developping an audio application in C# and UWP using the AudioGraph API.
My AudioGraph setup is the following :
AudioFileInputNode --> AudioSubmixNode --> AudioDeviceOutputNode.
I attached a custom echo effect on the AudioSubmixNode.
If I play the AudioFileInputNode I can hear some echo.
But when the AudioFileInputNode playback finishes, the echo sound stops brutally.
I would like it to stop gradually after few seconds only.
If I use the EchoEffectDefinition from the AudioGraph API, the echo sound is not stopped after the sample playback has finished.
I don't know if the problem comes from my effect implementation or if it's a strange behavior of the AudioGraph API...
The behavior is the same in the "AudioCreation" sample in the SDK, scenario 6.
Here is my custom effect implementation :
public sealed class AudioEchoEffect : IBasicAudioEffect
{
public AudioEchoEffect()
{
}
private readonly AudioEncodingProperties[] _supportedEncodingProperties = new AudioEncodingProperties[]
{
AudioEncodingProperties.CreatePcm(44100, 1, 32),
AudioEncodingProperties.CreatePcm(48000, 1, 32),
};
private AudioEncodingProperties _currentEncodingProperties;
private IPropertySet _propertySet;
private readonly Queue<float> _echoBuffer = new Queue<float>(100000);
private int _delaySamplesCount;
private float Delay
{
get
{
if (_propertySet != null && _propertySet.TryGetValue("Delay", out object val))
{
return (float)val;
}
return 500.0f;
}
}
private float Feedback
{
get
{
if (_propertySet != null && _propertySet.TryGetValue("Feedback", out object val))
{
return (float)val;
}
return 0.5f;
}
}
private float Mix
{
get
{
if (_propertySet != null && _propertySet.TryGetValue("Mix", out object val))
{
return (float)val;
}
return 0.5f;
}
}
public bool UseInputFrameForOutput { get { return true; } }
public IReadOnlyList<AudioEncodingProperties> SupportedEncodingProperties { get { return _supportedEncodingProperties; } }
public void SetProperties(IPropertySet configuration)
{
_propertySet = configuration;
}
public void SetEncodingProperties(AudioEncodingProperties encodingProperties)
{
_currentEncodingProperties = encodingProperties;
// compute the number of samples for the delay
_delaySamplesCount = (int)MathF.Round((this.Delay / 1000.0f) * encodingProperties.SampleRate);
// fill empty samples in the buffer according to the delay
for (int i = 0; i < _delaySamplesCount; i++)
{
_echoBuffer.Enqueue(0.0f);
}
}
unsafe public void ProcessFrame(ProcessAudioFrameContext context)
{
AudioFrame frame = context.InputFrame;
using (AudioBuffer buffer = frame.LockBuffer(AudioBufferAccessMode.ReadWrite))
using (IMemoryBufferReference reference = buffer.CreateReference())
{
((IMemoryBufferByteAccess)reference).GetBuffer(out byte* dataInBytes, out uint capacity);
float* dataInFloat = (float*)dataInBytes;
int dataInFloatLength = (int)buffer.Length / sizeof(float);
// read parameters once
float currentWet = this.Mix;
float currentDry = 1.0f - currentWet;
float currentFeedback = this.Feedback;
// Process audio data
float sample, echoSample, outSample;
for (int i = 0; i < dataInFloatLength; i++)
{
// read values
sample = dataInFloat[i];
echoSample = _echoBuffer.Dequeue();
// compute output sample
outSample = (currentDry * sample) + (currentWet * echoSample);
dataInFloat[i] = outSample;
// compute delay sample
echoSample = sample + (currentFeedback * echoSample);
_echoBuffer.Enqueue(echoSample);
}
}
}
public void Close(MediaEffectClosedReason reason)
{
}
public void DiscardQueuedFrames()
{
// reset the delay buffer
_echoBuffer.Clear();
for (int i = 0; i < _delaySamplesCount; i++)
{
_echoBuffer.Enqueue(0.0f);
}
}
}
EDIT :
I changed my audio effect to mix the input samples with a sine wave. The ProcessFrame effect method runs continuously before and after the sample playback (when the effect is active). So the sine wave should be heared before and after the sample playback. But the AudioGraph API seems to ignore the effect output when there is no active playback...
Here is a screen capture of the audio output :
So my question is : How can the built-in EchoEffectDefinition output some sound after the playback finished ? An access to the EchoEffectDefinition source code would be a great help...
By infinitely looping the file input node, then it will always provide an input frame until the audio graph stops. But of course we do not want to hear the file loop, so we can listen the FileCompleted event of AudioFileInputNode. When the file finishes playing, it will trigger the event and we just need to set the OutgoingGain of AudioFileInputNode to zero. So the file playback once, but it continues to silently loop passing input frames that have no audio content to which the echo can be added.
Still using scenario 4 in the AudioCreation sample as an example. In the scenario4, there is a property named fileInputNode1. As mentioned above, please add the following code in fileInputNode1 and test again by using your custom echo effect.
fileInputNode1.LoopCount = null; //Null makes it loop infinitely
fileInputNode1.FileCompleted += FileInputNode1_FileCompleted;
private void FileInputNode1_FileCompleted(AudioFileInputNode sender, object args)
{
fileInputNode1.OutgoingGain = 0.0;
}
I get the error on:
lad = GameObject.FindGameObjectsWithTag ("Ladder");
I'm just trying to disable all the ladders in the scene while the alarm is on and then enable them again once the alarm goes away. I'm not sure what the error means but need it fixed as soon as possible. I'm using C# and Unity 5. Thanks for any help you guys can provide!
using UnityEngine;
using System.Collections;
public class LevelAlarm : MonoBehaviour {
public bool alarmOn = false;
public bool bPlayerHidden = false;
// How long an alarm lasts for
[SerializeField]
private float alarmTimer = 5.0f;
private float alarmCurrentTimer = 0.0f;
public GameObject lad;
// Use this for initialization
void Start ()
{
lad = GameObject.FindGameObjectsWithTag ("Ladder");
}
// Update is called once per frame
void Update ()
{
// While alarm is on, run a timer
if (alarmOn)
{
alarmCurrentTimer += Time.deltaTime;
lad.SetActive(false);
// Timer is complete, alarm resets
if(alarmCurrentTimer >= alarmTimer)
{
alarmOn = false;
alarmCurrentTimer = 0.0f;
lad.SetActive(true);
}
}
}
}
GameObject.FindGameObjectsWithTag() returns an array of GameObjects, if you want first object of this array, use this:
void Start ()
{
var objects = GameObject.FindGameObjectsWithTag ("Ladder");
if(objects != null && objects.Length > 0)
{
lad = objects[0];
}
}
It's GameObject.FindGameObjectWithTag, not GameObject.FindGameObjectsWithTag, don't has character "s" after "Object".
Error CS0029: Cannot implicitly convert type UnityEngine.GameObject[]' toUnityEngine.GameObject'
This error simply means that you try to stop alarm whose tag are "Ladder".It creates an array and the function you use accept only one element of utilityEngine.GameObject. So you may use foreach loop to access all elements in the array by using :
public bool alarmOn = false;
public bool bPlayerHidden = false;
// How long an alarm lasts for
[SerializeField]
private float alarmTimer = 5.0f;
private float alarmCurrentTimer = 0.0f;
**public GameObject[] lad;**
// Use this for initialization
void Start ()
{
lad = GameObject.FindGameObjectsWithTag ("Ladder");
}
// Update is called once per frame
void Update ()
{
// While alarm is on, run a timer
if (alarmOn)
{
alarmCurrentTimer += Time.deltaTime;
**foreach(var eachLad in lad)
{
eachLad.SetActive(false);
}**
// Timer is complete, alarm resets
if(alarmCurrentTimer >= alarmTimer)
{
alarmOn = false;
alarmCurrentTimer = 0.0f;
**foreach(var eachLad in lad)
{
eachLad.SetActive(true);
}**
}
}
}