-4

hey does anyone knows how to make a C# script for object to re spawn after getting destroyed by a bullet

kanishka
  • 1
  • 2

3 Answers3

1

There are multible ways to archive this.

Note that you can also work completely without Coroutine but this usually sucks

private float timer;

private bool isRespawning;
private GameObject clone;

private void DestroyObject(GameObject obj)
{
    isRespawning = true;
    timer = 3f;

    // first make a clone of the current Object
    var clone = Instantiate(obj, obj.transform.position, obj.transform.rotation, objtransform.parent);

    // disable the clone
    clone.SetActive(false);

    // Destroy the original
    Destroy(obj);
}

private void Update()
{
    if(Mathf.Approximately(timer,0f)) return;

    timer += Time.deltaTime;

    if(timer > 0) return;

    // Set the clone active
    clone.SetActive(true);
    timer = 0;
}

Simplier would be a Coroutine:

private void DestroyAndRespawn(GameObject obj)
{
    StartCoroutine(DestroyAndRespawnRoutine(obj));
}

private IEnumerator DestroyAndRespawnRoutine(GameObject obj)
{
    // first make a clone of the current Object
    var clone = Instantiate(obj, obj.transform.position, obj.transform.rotation, objtransform.parent);

    // disable the clone
    clone.SetActive(false);

    // Destroy the original
    Destroy(obj);

    // Wait 3 seconds
    yield return new WaitForSeconds(3f);

    // Set the clone active
    clone.SetActive(true);
}

But why should you destroy the object and respawn it? You can simply only disable and later re enable it

private void DestroyAndRespawn(GameObject obj)
{
    StartCoroutine(DestroyAndRespawnRoutine(obj));
}

private IEnumerator DestroyAndRespawnRoutine(GameObject obj)
{
    // disable the obj
    obj.SetActive(false);

    // Wait 3 seconds
    yield return new WaitForSeconds(3f);

    // Set the objactive
    obj.SetActive(true);
}

Update

Since you want to call this on collision:

You will need another GameObject that works as a Manager for the respawning / enabling, disabling since you can not just attach that script to the object you disable -> would also disable the script and never re-enable the object.

  1. Create a new empty GameObject e.g. called "RespawnManager"
  2. Create a new Script RespawnManager.cs:

    public class RespawnManager : MonoBehaviour
    {
        public static RespawnManager Singleton;
    
        private void Awake()
        {
            if(Singleton)
            {
                enabled = false;
                return;
            }
    
            Singleton = this;
        }
    
        private void DestroyAndRespawn(GameObject obj)
        {
            StartCoroutine(DestroyAndRespawnRoutine(obj));
        }
    
        private IEnumerator DestroyAndRespawnRoutine(GameObject obj)
        {
            // disable the obj
            obj.SetActive(false);
    
            // Wait 3 seconds
            yield return new WaitForSeconds(3f);
    
            // Set the objactive
            obj.SetActive(true);
        }
    }
    
  3. Than you can call it on collision like

    OnCollisionEnter(Collision obj)
    {
        if (obj.gameObject.name != "bullet") return;
    
        // pass this GameObject to the manager
        RespawnManager.Singleton.DestroyAndRespawn(gameObject);
    }
    
derHugo
  • 83,094
  • 9
  • 75
  • 115
  • how to make sure it acts only after getting hit by the bullet – kanishka Oct 15 '18 at 08:27
  • I leave this as a homework for you. https://answers.unity.com/questions/372595/how-to-detect-collisions-in-c.html – derHugo Oct 15 '18 at 08:52
  • using System.Collections; using System.Collections.Generic; using UnityEngine; public class destroy : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { } void OnCollisionEnter(Collision obj) { if (obj.gameObject.name == "bullet") { Destroy (gameObject); } } } – kanishka Oct 15 '18 at 13:27
  • where should i attach your original code to, object or and empty game object – kanishka Oct 15 '18 at 13:29
  • well if you would attach this code to the object itself you are going to destroy it would probably not be a good idea, right? If you rather use the last section with just disabling the object than you could put the code directly in the `OnCollisionEnter` method – derHugo Oct 15 '18 at 13:32
  • like how?| void OnCollisionEnter(Collision obj) { if (obj.gameObject.name == "bullet") { // disable the obj obj.SetActive(false); // Wait 3 seconds yield return new WaitForSeconds(3f); // Set the objactive obj.SetActive(true); } – kanishka Oct 15 '18 at 13:43
  • No, calling `DestroyAndRespawn`, the method I posted as answer. Please see my last section "Update". – derHugo Oct 15 '18 at 13:45
  • like this?? // Use this for initialization void Start() { } // Update is called once per frame void Update() { } private IEnumerator DestroyAndRespawnRoutine(GameObject obj) { if (obj.gameObject.name == "bullet") { // disable the obj obj.SetActive(false); // Wait 3 seconds yield return new WaitForSeconds(3f); // Set the objactive obj.SetActive(true); } } – kanishka Oct 15 '18 at 13:49
  • no wait I just noticed that would maybe also not work because you would also disable the script itself -> your object wouldn't be re-enabled. You have to use a seperate Manager object to controll that respawn – derHugo Oct 15 '18 at 13:51
  • with the original script? – kanishka Oct 15 '18 at 13:52
  • empty game object? – kanishka Oct 15 '18 at 13:54
  • please see my Update – derHugo Oct 15 '18 at 13:59
  • how to add the enemy object to the RespawnManager.cs – kanishka Oct 16 '18 at 08:44
  • `RespawnManager .Singleton.DestroyAndRespawn(gameObject);` see my update. I didn't read well and accidently passed in the bullet instead of the hit object – derHugo Oct 16 '18 at 08:50
  • do i have to attach to the empty game object or object, – kanishka Oct 16 '18 at 09:24
  • because spawn script doesn't have any variable to explain the object in my scene – kanishka Oct 16 '18 at 09:25
  • finally got it i need to change your script little bit then it was ok . thanks man – kanishka Oct 16 '18 at 09:44
  • needed to erase the 'return' part (enabled = false; return;) – kanishka Oct 16 '18 at 09:45
  • that part makes actually only sure, you don't have multible Managers running at the same time ... so it shoudl work with it – derHugo Oct 16 '18 at 13:07
0

Set object active to False. using

gameobject.SetActive(false);

And you can use Coroutine to do this.

Morasiu
  • 1,204
  • 2
  • 16
  • 38
  • 1
    To be fair the question is very bad. But could you please elaborate this a bit in order to make this post a valid complete answer. Currently it is somewhere inbetween a comment and an answer – derHugo Oct 15 '18 at 07:13
0

If you use Destroy(yourObject);, the object does get removed and you loose access. You could make your Object into a prefab and spawn it where you want by using GameObject obj = Instantiate(...); Obj contains the reference to the new spawned object and not to the prefab, which means you can later again use Destroy(obj);

Denk758
  • 3
  • 1
  • To be fair the question is very bad. But the OP actually wants it the other way round: Destroy an object -> remember its position -> (re)Spawn at this position .... whatever this means – derHugo Oct 15 '18 at 07:08
  • If op wants to use the exact same obj, then he needs to use setActive as the other answers says and he cannot use Destroy. – Denk758 Oct 15 '18 at 07:17