the below scripts act as Containers for the Item class. These are attached to GameObjects and represent the Item in the world. I will have a Prefab for each W_Item. If I had 10000 items, I would need 10000 W_Whatever scripts to represent these while the only thing that would change in PickUp() is which child class constructor is called.
What I would like to do: I would like to have 1 class W_Item that works for all World Items. I would like to select which Item child class will be instantiated at the Prefab level. When game is ran, it should already know which Type will be created by each W_Item.
W_Item
using UnityEngine;
using System.Collections;
public abstract class W_Item : MonoBehaviour {
public Item item;
public abstract void PickUp(Inventory invRef);
public void OnPickUp(){
Destroy (this.gameObject);
}
}
W_Gun_22Rifle
using UnityEngine;
using System.Collections;
public class W_Gun_22Rifle : W_Item {
public override void PickUp(Inventory invRef){
item = new Gun_22Rifle();
invRef.inv.Add (item);
if(true)
OnPickUp ();
}
}
yes and no. I want to be able to set the type on the Prefab. I could do it with a giant Enum of item names and Generics but that would be a pain in the ass to maintain.
In this case, I would use serialization to my benefit.
In your example, I see you have the item Gun_22Rifle as a regular C# class, because you’re creating it with new.
Instead, I’d suggest making a base Weapon (or item) MonoBehaviour, and placing your pickup functionality there, and adding that Behaviour to prefabs you want to make items.
Then you could either extend the item class to give functionality to different items, or create new components to give functionality to different items.
Something like this:
using UnityEngine;
using System.Collections;
public class Item: MonoBehaviour {
[SerializeField][Range(1f,10f)] float spinSpeed;
SphereCollider pickupCollider;
void Awake()
{
pickupCollider = GetComponent<SphereCollider> () ?? gameObject.AddComponent<SphereCollider> ();
pickupCollider.isTrigger = true;
}
//Spin Around, cuz why not
void Update()
{
if (pickupCollider.enabled) {
var spin = transform.rotation * Quaternion.Euler (Vector3.up * spinSpeed);
Quaternion.Slerp (transform.rotation, spin, Time.deltaTime);
}
}
void OnTriggerEnter(Collider other)
{
var player = other.GetComponent<Player> ();
if (player) {
transform.parent = player.transform;
transform.localPosition = Vector2.zero;
transform.localRotation = Quaternion.identity;
//Remove pickup functionality
pickupCollider.enabled = false;
}
}
}
Yeah, I should have went with this solution from the start. Now I am having to reiterate over a bunch of my classes and redesign them as MonoBehaviours instead. Much easier to handle. Thanks!