Search code examples
c#unity-game-engineinstantiation

How do I activate the component of an instantiated object without activating the original object


I'm trying to add a bullet crafting system to my game where you can craft bullets with customizable properties. I've been testing ways for the gun to find the bullet and instantiate it. The bullets are inactive after being constructed and only the bullets instantiated from the gun are active

I've run into a strange problem, as soon as my gun fires, the original bullet becomes active (this results in it flying into a wall and getting destroyed).

Here is a basic summary of what I wanted to happen: My bullet maker script increases it's values for speed and damage when fed certain objects, it creates a "bullet" object with those values into a "Projectile" script when you click on it. The script is deactivated

My bullet finder script references the "bullet" object within it's box collider.

My gun script instantiates the "bullet" but with the projectile script activated.

I've been looking online for a way to activate the instantiated bullet without activating the original but I haven't been able to find anything. Almost every post related to instantiation only considers prefabs and not the instantiation of objects in the scene.

here are my scripts related to the problem

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BulletMaker : MonoBehaviour
{
    bool bulletReady = true;
    public float bulletDamage = 0f;
    public float bulletSpeed = 0f;
    Projectile projectile;
    public Transform bulletDrop;
    void Start()
    {
        
    }
    void Update()
    {
        
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Red"))
        {
            bulletDamage += 10;
            Destroy(other.gameObject);
        }
        if (other.CompareTag("Blue"))
        {
            bulletSpeed += 100;
            Destroy(other.gameObject);
        }
    }

    private void OnMouseDown()
    {
        if (bulletReady)
        {
            GameObject bullet = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            bullet.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
            bullet.transform.position = bulletDrop.position;
            bullet.AddComponent<Rigidbody>();
            bullet.GetComponent<Rigidbody>().useGravity = false;
            bullet.AddComponent<Projectile>();
            bullet.GetComponent<Projectile>().speed = bulletSpeed;
            bullet.GetComponent<Projectile>().damage = bulletDamage;
            bullet.GetComponent<Projectile>().enabled = false;
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BulletFinder : MonoBehaviour
{
    public GameObject selectedBullet;
    void Start()
    {

    }
    void Update()
    {

    }

    private void OnTriggerStay(Collider other)
    {
        selectedBullet = other.gameObject;
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Gun : MonoBehaviour
{
    public Transform muzzle;
    public int magazineSize;
    public int bulletsInMag;
    public float reloadTime = 3;
    bool reloading = false;
    BulletFinder bulletFinder;
    void Start()
    {
        bulletFinder = GameObject.Find("Bullet Holder").GetComponent<BulletFinder>();
    }

    // Update is called once per frame
    void Update()
    {
        if (bulletFinder.selectedBullet != null)
        {
            if (Input.GetKeyDown(KeyCode.Mouse0) && bulletsInMag > 0)
            {
                Shoot();
            }
            else if ((Input.GetKeyDown(KeyCode.Mouse0) && bulletsInMag <= 0 && !reloading))
            {
                Reload();
            }
        }
    }
    private void Shoot()
    {
        if (bulletFinder.selectedBullet != null)
        {
            Instantiate(bulletFinder.selectedBullet, muzzle.position, muzzle.rotation);
            bulletFinder.selectedBullet.GetComponent<Projectile>().enabled = true;
            bulletsInMag--;

        }
    }

    private void Reload()
    {
        reloading = true;
        StartCoroutine(ReloadTime());
    }

    IEnumerator ReloadTime()
    {
        yield return new WaitForSeconds(reloadTime);
        bulletsInMag = magazineSize;
        reloading = false;
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Projectile : MonoBehaviour
{
    public float damage;
    public float speed;
    private Rigidbody projectile;
    bool active = true;
    BulletMaker bulletMaker;
    void Start()
    {
        projectile = GetComponent<Rigidbody>();
    }

    void Update()
    {
        if (active & projectile != null)
        {
            projectile.AddForce(transform.forward * Time.deltaTime * speed, ForceMode.Impulse);
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        Destroy(gameObject);
    }
}

Solution

  • Because you did activate the original bullet, the correct approach is to enable the instantiated bullet which is returned by the Instantiate method.

    var bullet = Instantiate(bulletFinder.selectedBullet, muzzle.position, muzzle.rotation);
    bullet.GetComponent<Projectile>().enabled = true;