Trying to create an object with attributes but it won't spawn with needed attributes

I’m trying to make a grenade that can have changeable attributes (like cooldowns or damage), and when I instantiate a new object with the script that has it all the fields are set as their defaults and I don’t know how to change them.

Here is the GrenadeScript (thing that has the attributes):

public class GrenadeScript : MonoBehaviour
{
    private GameObject body;
    public GameObject  Body {  get {  return body; } }
    private string modelName;
    public string ModelName { get { return name; } }
    private int cooldownInSeconds;
    public int CoolDownInSeconds {  get { return cooldownInSeconds; } }
    private int timeTillDetonation;
    public int TimeTillDetonation { get { return timeTillDetonation; } }
    private float damage;
    public float Damage { get { return damage; } }

    // Start is called before the first frame update
    void Start()
    {
       
    }

    // Update is called once per frame
    void Update()
    {
       
    }

    public GrenadeScript(string grenadeName, int refreshRateInSeconds, float damagePerHit, int detonationTime, GameObject grenadeBody)
    {
        modelName = grenadeName;
        cooldownInSeconds = refreshRateInSeconds;
        timeTillDetonation = detonationTime;
        damage = damagePerHit;
        body = grenadeBody;
    }

    // Once a grenade hits
    private void OnCollisionEnter(Collision collision)
    {
        StartCoroutine(DetonationTimer(timeTillDetonation));
    }

    public IEnumerator DetonationTimer(int detonationTime)
    {
        yield return new WaitForSeconds(detonationTime);
        Destroy(gameObject);
    }
}

and then here was what I use to spawn the item in another script

            grenadeInfo = new GrenadeScript("placeHolder", 1, 100f, 3, grenade);
            grenadeObject = UnityEngine.Object.Instantiate(grenadeInfo.Body, abilitySpawn, camera.transform.rotation, abilities);

I’m sorry If it’s hard to read I’m new to the forums

To reiterate the problem I am having is I am trying to spawn an object that has the attributes of grenadeInfo but no matter what I do all of it’s fields are set to defaults. I know that my problem is There is no connection between grenadeObject and grenadeInfo but I need help with how I put them both together.

What I want to happen is once the grenadeObject collides with the floor it starts a timer of timeTillDetonation which I want to be the given field (3) but it is the default (0)

Always watch the console. Never ignore warnings until you understand what they mean. You cannot instantiate a MonoBehaviour with “new”, this will print a warning to the console.

All of your fields are private and not marked as [SerializeField], therefore you cannot edit these values in the Inspector.

You need to create a GameObject and put that component on it, then make it a prefab by dragging it onto the project view. Edit the script values in the prefab via Inspector. And then instantiate the prefab reference, you need a GameObject or Transform reference in the script that instantiates where you drag the prefab onto.

2 Likes

Everything that CodeSmile says above… 100%.

Also, this pattern may be useful to you if you like using ctors() to get all your data together at one time:

Factory Pattern in lieu of AddComponent (for timing and dependency correctness):

I forgot to mention the despawn on collision is working, the prefab I have has the GrenadeScript in it, but there are no console errors and when I get rid of the “new” a console error appears saying “Assets\InteractionScript.cs(128,27): error CS1955: Non-invocable member ‘GrenadeScript’ cannot be used like a method.”. Doesn’t this mean it needs the new keyword to work?

Can I not change the individual grenade attributes? should I just make my grenade types as prefabs and make it based off the name or could I do it my way?

Don’t get rid of the new: get rid of the ENTIRE constructor statement.

Anything derived from MonoBehaviour cannot be made by you. Don’t try.

See your console for warnings.

Use AddComponent() and/or one of the strategies I posted, one of which involves AddComponent.

It may be helpful for you to FORGET all the lifecycle crud you learned when you learned C#. Do not use constructors, period, as long as it is a MonoBehaviour- or ScriptableObject-derived type. Unity is NOT pure C#. Unity is a thin C# wrapper on top of a native C/C++ engine.

1 Like

Thank you for the advice, it worked out very well.