- Home /
Destroy trigger after a certain time
Hi! I have a problem with triggering a GUI text after a battery pick up. I want the batteries destroyed after I pick them up but there comes the problem. I'm using a timed GUI script that should make the text dissapear after some seconds but when I'm using "Destroy(other.gameObject);" the timed GUI won't work because it's destroyed. It shows the text but it wont dissapear from the screen. My question is, can you make so the trigger destroys after the GUI timer has ended?
Battery pick up script:
var batteryPower : int = 30;
function OnTriggerEnter (other : Collider) {
if (!other.CompareTag("Player")) return;
Flashlight.AlterEnergy(batteryPower);
Destroy(other.gameObject);
}
Triggering GUI script:
var theGuiObject : GUIText;
var displayTime = 3.0;
private var timerActive = false;
private var timer = 0.0;
function OnTriggerEnter (other : Collider) {
if (!other.CompareTag ("Player")) { // Do nothing if tag is not "Player"
return;
}
if (timerActive) { // Reset timer if player re-enters trigger while the timer's active
timer = 0.0;
return;
}
theGuiObject.enabled = true; // Enable GUIText, wait a while, then disable it
yield Wait();
theGuiObject.enabled = false;
}
function Wait () { // A custom WaitForSeconds coroutine that can be reset
timerActive = true;
timer = 0.0;
while (timer < displayTime) {
timer += Time.deltaTime;
yield;
}
timerActive = false;
}
For Bluestrike...
I have placed the scripts where it belongs but it won't work. (The cube is just for testing)
Answer by ByteSheep · Jan 12, 2013 at 03:20 PM
You could add a reference to the battery GameObject in the Triggering GUI Script:
var theGuiObject : GUIText;
var batteryObject : GameObject; // Don't forget to add the reference in the inspector
var displayTime = 3.0;
private var timerActive = false;
private var timer = 0.0;
function Start() {
batteryObject = GameObject.Find("ObjectName"); //replace ObjectName with the actual name of the battery object in the hierarchy view
}
function OnTriggerEnter (other : Collider) {
if (!other.CompareTag ("Player")) { // Do nothing if tag is not "Player"
return;
}
if (timerActive) { // Reset timer if player re-enters trigger while the timer's active
timer = 0.0;
return;
}
theGuiObject.enabled = true; // Enable GUIText, wait a while, then disable it
yield Wait();
theGuiObject.enabled = false;
Destroy(batteryObject); // Destroy the battery object when the GUI text disappears
}
function Wait () { // A custom WaitForSeconds coroutine that can be reset
timerActive = true;
timer = 0.0;
while (timer < displayTime) {
timer += Time.deltaTime;
yield;
}
timerActive = false;
}
I get an error:
"Destroying assets is not permitted to avoid data loss. If you really want to remove an asset use DestroyImmediate (theObject, true); UnityEngine.Object:Destroy(Object) $:$$anonymous$$oveNext() (at Assets/Scripts/TriggerGUITimer.js:19)"
It seems that the object you're trying to destroy is an asset rather than a gameobject in the scene.. I've added a start function to the script that searches for the battery object in the scene - don't forget to set the right object name in Find(""). As BlueStrike mentioned it may not be best to entirely delete the battery object, but rather disable the renderer.
The script you gave me worked but then I realized, I can only use one battery pick up in my game because of the "Find" part. I'm going to ask Bluestrike for further instructions on his idea but thanks for your help!
Answer by Bluestrike · Jan 12, 2013 at 04:28 PM
You probably have some HUD or interface in your game attached to a player. I would place the message in the hud and run a function there showing the message.
Also by creating my own game I read its better to hide a gameObject or renderer then to destroy and instantiate again (for pickups like weapons health etc) So you can create a main object (empty) with a trigger and the pickup script. have a child that is the battery.
This is in javascript, I am not familiar enough with c++
First the battery script:
// Asuming the baterry is a child object of your gameobject with script.
var battery :GameObject;
var respawnTime :float = 6.5;
private var isEnabled :boolean = true;
// hudscript should be the name of the script that is used for your hud.(caps sensitive).
private var hudReference :hudscript;
function Start() :void
{
// You can add a find function here to assign the battery so you do not need to set it in the inspector.
}
function OnTriggerEnter(thisCollider :Collider) :void
{
// Asumming the hud script is on the player gameobject that also has the collider.
// Again hudscript should be the name of the script containing the hud code.
if(isEnabled && thisCollider.CompareTag ("Player"))
{
hudReference = thisCollider.GetComponent(hudscript);
isEnabled = false;
HideBattery();
}
}
function HideBattery() :IEnumerator
{
// Disabling the battery gameobject and all its children
battery.SetActive(false);
// Send the hud a message that a battery has been found.
hudReference.BatteryPickup();
// optional respawntime
yield WaitForSeconds(respawnTime);
battery.SetActive(true);
// Enable the trigger again now there is a new pickup visible.
isEnabled = true;
}
You can enable and disable the renderer with:
battery.renderer.enabled = false;
This would do because the battery probebly has no collision, but I would use SetActive because it disabled the whole object and its children.
The hudscript: (hudscript.js)
var showBatteryPickup :boolean = false;
var batteryLabel :String = " You found a battery";
// The label could also be a icon shown on the hud that you assign trough the inspector:
// var batteryLabel :Texture;
function OnGUI()
{
// Shows the label on the hud, the label could be a texture or string
if(showBatteryPickup)
{
GUI.Label (Rect (100, 100, 300, 30), batteryLabel);
}
}
function BatteryPickup() :IEnumerator
{
var showTime :float = 2.5;
showBatteryPickup = true;
yield WaitForSeconds(showTime);
showBatteryPickup = false;
}
More info: http://docs.unity3d.com/Documentation/ScriptReference/Renderer.html http://docs.unity3d.com/Documentation/ScriptReference/GUI.Label.html
So if I just want to disable the renderer for the battery, how would the whole script look like then? Path to to GUI, ti$$anonymous$$g for the GUI etc etc.
I updated my awnser, there is a battery script that tells a script named hudscript to show the battery pickup.
So if I got this right. I add the battery script to a gameobject that has the battery object as a child. Then I add the hud script to the player. Nothing more then that?
Yes thats all, there was still an error in the battery script: triggerEnter should be OnTriggerEnter and the hudreference was never assigned in it, I updated the battery script and tested it here.
You need to adjust the label rect to position the text where you like it and to customize it you also need to create a guistyle (see de the documentation on that and a free guistyle can be found on the asset store.)
It wont work for me. I'm adding two images up top so yo can see that I have all I need for it to work.