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
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.
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.