How to destroy a gameobject before instantiating another one in its location?
I am trying to achieve the same functionality as Invoker's orbs in Dota 2. My player character has 3 balls hovering over him ( 0 to begin with). Each time "R","G" or "B" is pressed, a ball of the corresponding color (red,green or blue) is created in predefined positions. Lets call them pos1, pos2 and pos3.
After the third input, wherein a ball is created at pos3, if the user provides yet another input, I want the corresponding ball to appear at pos1 , the 5th input at pos2 and so on.
Complete beginner here, I want to know how i can destroy the ball at pos1 created by the first input before creating the ball at the same position from the 4th input. This is what my code currently looks like. I would also be really thankful if someone could tell me a better/simpler approach to the problem
using UnityEngine;
using System.Collections;
using System;
public class orbControl : MonoBehaviour {
int currentOrb = 0;
int maxOrbs = 2;
public Transform[] spawnPos;
public GameObject airOrb;
public GameObject fireOrb;
public GameObject waterOrb;
void Update()
{
if (Input.GetKeyDown ("q") && currentOrb <= maxOrbs)
{
spawnAirOrb ();
currentOrb++;
if (currentOrb > maxOrbs)
{
currentOrb = (currentOrb % maxOrbs) -1;
}
}
if (Input.GetKeyDown ("w") && currentOrb <= maxOrbs)
{
spawnFireOrb ();
currentOrb++;
if (currentOrb > maxOrbs)
{
currentOrb = (currentOrb % maxOrbs) -1;
}
}
if (Input.GetKeyDown ("e") && currentOrb <= maxOrbs)
{
spawnWaterOrb ();
currentOrb++;
if (currentOrb > 2)
{
currentOrb = (currentOrb % maxOrbs) -1;
}
}
}
void spawnAirOrb( )
{
GameObject spawnedOrb = Instantiate (airOrb, spawnPos [currentOrb ].position, spawnPos [currentOrb ].rotation) as GameObject;
}
void spawnFireOrb( )
{
GameObject spawnedOrb = Instantiate (fireOrb, spawnPos [currentOrb ].position, spawnPos [currentOrb ].rotation) as GameObject;
}
void spawnWaterOrb( )
{
GameObject spawnedOrb = Instantiate (waterOrb, spawnPos [currentOrb ].position, spawnPos [currentOrb ].rotation) as GameObject;
}
}
Do these orbs orbit as well or are always in a static position?
They are static as of now but I would like to apply some kind of rotate script to the orbs in the future! I want to know if there is a way to reference a specific instance of a gameobject which I instantiated in the spawnAirOrb function for example.
Answer by TBruce · Dec 28, 2016 at 12:33 AM
The following tested script will destroy the orb before a new one is created and place the new one in the proper location. I added an extra bool
reference variable to allow for the placing of the orb that is being orbited . it will place the orb in the exact location as the old one.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
public class OrbControl : MonoBehaviour
{
int currentOrb = 0;
int maxOrbs = 3;
public Transform[] spawnPos;
public GameObject airOrb;
public GameObject fireOrb;
public GameObject waterOrb;
public bool allowOrbit = false; // if set to true then orbiting functionality needs to be added
public bool overRideCurrentOrb = false; // if set to true then "currentOrb" will not be used
void Start()
{
if (maxOrbs < spawnPos.Length)
{
maxOrbs = spawnPos.Length;
}
}
void Update()
{
if (Input.GetKeyDown ("q") && currentOrb < maxOrbs)
{
spawnAirOrb ();
}
if (Input.GetKeyDown ("w") && currentOrb < maxOrbs)
{
spawnFireOrb ();
}
if (Input.GetKeyDown ("e") && currentOrb < maxOrbs)
{
spawnWaterOrb ();
}
}
void spawnAirOrb()
{
spawnOrb(airOrb, 0);
}
void spawnFireOrb()
{
spawnOrb(fireOrb, 1);
}
void spawnWaterOrb()
{
spawnOrb(waterOrb, 2);
}
void spawnOrb(GameObject orb, int index)
{
if (!overRideCurrentOrb)
{
index = currentOrb;
}
if (orb != null)
{
GameObject oldOrb = GameObject.Find(orb.name + "(Clone)");
Vector3 position = spawnPos [index].position;
Quaternion rotation = spawnPos [index].rotation;
if (oldOrb != null)
{
if (allowOrbit)
{
// if orbiting is allowed then set the position and rotation values to the current object
position = oldOrb.transform.position;
rotation = oldOrb.transform.rotation;
}
Destroy(oldOrb);
}
GameObject spawnedOrb = (GameObject)Instantiate (orb, position, rotation);
currentOrb++;
if (currentOrb >= maxOrbs)
{
currentOrb = 0;
}
}
}
}
Note: There was a possible issue with logic where an individual orb
could be created many times without creating others. The effect would create the new orb in a location of a different color sometimes overlapping another orb. I do not know if this was intended or not, but just in case I added the reference variable overRideCurrentOrb
(defaults to false) which would not use the currentOrb
value to get the position and rotation.
@TBruce Hi, thank you for your reply. I tried out your version:
If i wanted to call 3 red orbs, and I pressed the corresponding key"w" thrice, I am able to have only 1 orb, at the corresponding position. The previous ones get destroyed. I want to destroy the orb at a certain position only if another orb is invoked at the same position.
In the script which i initially posted, everything runs as I want it to. The only functionality i am unable to produce is that of destroying an existing orb at a certain position if another one is made to spawn there.
Basically, the player can call upon $$anonymous$$AXORBS number of orbs with is currently set to 3. So I can have 3 red,blue or green orbs if I want to. The goal is to invoke a specific combination of orbs to create a unique PowerUp.
For example: Invoking RED RED BLUE will give me a jump boost. Invoking GREEN GREEN GREEN will give me a speed boost etc. If I press R thrice, I should have 3 Red orbs at Position1, Position2 and Position3 correspondingly. If my fourth input is G, the first of the Red orbs at Position1 should be destroyed and replaced with a Green Orb. Please excuse the lack of clarity in explanation, I hope i conveyed my problem adequately.
Hi @Diskodragon, Here is the updated and tested script that functions according to what you wanted (I also tested it with your original script which I did not do before).
The orbiting functionality was no longer working and I had to make some slight changes.
The new one also doesnt allow me to spawn multiple balls of the same color. Also the airOrb spawns only at pos1, fireOrb at pos2 and waterOrb at pos3.
The way i have set it up in Unity is:
Separate prefabs for airOrb, waterOrb and fireOrb
3 Empty GameObjects above the player with only a transform component as a reference to where the orbs will appear when called ( Pos1, Pos2 and Pos3). -The Script is attached to another Empty GameObject which holds the above Pos objects.
With each input(q,w or e) , I want the corresponding orb(air,fire,water) to appear in the first available spawnPosition. So if I press 'w' 3 times, i want 3 fire orbs to show up at Pos1,Pos2 and Pos3.( my first posted script was able to achieve this)
If my next input is 'e' 2 times, Pos1 and Pos2 should destroy the existing Fire orbs and create 2 Water orbs,
If next input is 'q' 2 times, Pos3 and Pos1(the spawnPos should loop back to 1 if any input is provided after Pos3 is full) should destroy the existing Fire and Water orb and create 2 Air orbs.
The List bit was new to me. Ill try playing around with that to store the orbs and destroy the old ones when new ones spawn in their place.
Thanks a lot for your help!
@TBruce THAN$$anonymous$$S A LOT :D ! Your last script worked wonderfully! So using the transform of the prefabs ins$$anonymous$$d of a separate empty GameObject as i had done earlier is the better way to do it (?).
I will try to figure out from your expert answer if i can find a way to get the same result using my earlier method as well! Thanks a ton for you help kind sir!
Hi @Diskodragon, Actually you you can do it either way. But after looking at what you are looking to do I realize that you will most likely want the orbs parented to the player so that they stay with the player as it moves.
Here is a new package, it has an updated and cleaner script with two players (`Player - Prefabs` & Player - GamObjects
) the latter one is disabled (Note: if you want to go the latter way of using separate empty GameObject's, you need to make sure that the GameObject's are not parented to the player).
Here is a video showing the package in action and demonstrating each method.
Here is the new script which is also in the package.
Your answer
Follow this Question
Related Questions
Gameobject array 0 Answers
Cannot destroy the SphereCollider on Instantiated Objects 1 Answer
Performance of instantiate and destroy for bullets 2 Answers