- Home /
Letting the player create a combination of any 4 items that the game will then give the player on a set timer.
Okay, so I've researched scriptable objects and I've realized that it's something that might be very useful for the kind of game I'm making. I've managed to create my own scriptable object for weapons that is able to hold weapon upgrades, range, damage, and other special stuff. I was told scriptable objects are much better for larger scales than enums so that I can hold data for each weapon. I do know how to implement them into
[CreateAssetMenu(fileName = "New Weapon", menuName = "Weapon")]
public class Weapon : ScriptableObject
{
public new string name;
public string _discription;
public Sprite _artwork;
public int _range;
public int _damage;
public int _upgrades;
public int _element;
public void Print()
{
Debug.Log(name + ": " + _discription + " The weapon does: " + _damage + "damage.");
}
}
I've researched how to show these on the UI, but is there any hint you could give me on getting scriptable objects working with an inventory system, and point me in a direction on how I can give the player control of the order of weapon in the inventory that the game will use to give said weapons in the same order the player set for themselves.
For Example, I want the player to be able to take any of the four weapons: Katana, Spear, Axe, Chakram, and be able to set them in any order. Even using multiple of itself. (Chakram, Spear, Spear, Axe, for example) and then the game will then give the player the items list they created on a set timer.
public class Weapon
{
public WeaponType type { get; set; }
}
public enum WeaponType
{
Katana,
Axe,
Spear,
Chakram
}
public class WeaponCycle: MonoBehaviour
{
[SerializeField] private Weapon[] _weapon;
public Weapon[] weapons = new Weapon[4];
List<Weapon> InventoryWeapons = new List<Weapon>();
// Start is called before the first frame update
void Start()
{
for (int i = 0; i < weapons.Length; i++)
{
weapons[i].type = (WeaponType)Random.Range(0, 3);
}
StartCoroutine(GiveWeapons(1));
}
IEnumerator GiveWeapons(float delay)
{
for (int i = 0; i < weapons.Length; i++)
{
yield return new WaitForSeconds(delay);
InventoryWeapons.Add(weapons[i]);
}
}
}
Sorry if it feels like I'm asking for too much, but I'm a beginner when it comes to C# and I'm trying to learn as efficiently as I can.
Answer by Llama_w_2Ls · Jan 25, 2021 at 09:17 AM
Hi again. You would need to rename your ScriptableObject, so that it doesn't confuse the two classes for each other. All you need to do is add a reference to your scriptable object. For example:
public class Weapon : MonoBehaviour
{
public WeaponType type { get; set; }
// the scriptable object
public WeaponObject weaponStats;
}
You would need to create 4 different types of scriptable objects, for each type of weapon in the enum. You could keep the enum, or remove it and place public string WeaponType
in the scriptable object, for simplicity. It doesn't really matter what you do with it.
The main goal of this is when you want to get the damage of the weapon, you can write weaponStats.damage
, for example, for every type of weapon, regardless. Without the scriptable object, you would have a large switch statement, of the enums, like:
switch (type)
case Katana:
Damage = bla bla bla;
break;
// And so on...
It's just a lot nicer, and a lot more readable, to do this using a scriptable object.
The next thing you wanted was to allow the player to select their items, instead of it being random. There are a lot of ways to go about this, but I am going to use key presses. For example, 1 would give you the chakram, 2 would give you the magic staff of magicness or smt, etc. E.g:
public class WeaponCycle : MonoBehaviour
{
[Header("Weapon Types")]
public Weapon Katana;
public Weapon Axe;
public Weapon Spear;
public Weapon Chakram;
List<Weapon> weapons = new List<Weapon>();
public List<Weapon> InventoryWeapons = new List<Weapon>();
bool CoroutineHasStarted = false;
private void Update()
{
// Choose weapons depending on key press
while (weapons.Count < 4)
{
if (Input.GetKeyDown(KeyCode.Alpha1))
weapons.Add(Katana);
else if (Input.GetKeyDown(KeyCode.Alpha2))
weapons.Add(Axe);
else if (Input.GetKeyDown(KeyCode.Alpha3))
weapons.Add(Spear);
else if (Input.GetKeyDown(KeyCode.Alpha4))
weapons.Add(Chakram);
}
if (!CoroutineHasStarted)
StartCoroutine(GiveWeapons(1));
}
IEnumerator GiveWeapons(float delay)
{
CoroutineHasStarted = true;
for (int i = 0; i < weapons.Count; i++)
{
yield return new WaitForSeconds(delay);
InventoryWeapons.Add(weapons[i]);
}
}
}
I hope this works. @unity_bJkbi0kaeUn_TQ
So I would have my own WeaponType class? Would this be on it's own script?
WeaponType is the name of the enum. I think you're confusing it with WeaponObject, which is the name of the script for the scriptable object. Also, you'll have to create separate GO's for each of the 4 weapons, and assign them their properties through the scriptable object.
Oh okay, so I'll have something like:
public class Katana : ScriptableObject
{
public string weaponName;
public string discription;
public Sprite artwork;
public int range;
public int spawnTime;
public int damage;
public int element;
}
And make the same for other weapon types? This way, it's possible for me from within the weapon script to control the damage, and other stuff, right? What would happen if I had four different katana objects? How would I, let's say, only change the range of one of the katana's, or does that require something completely different.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Null reference at for loop (list) 0 Answers
Do C# Lists start at 1 or 0 1 Answer