- Home /
FPS Advice for Item Management
Hello,
Working with C#, I've been looking into plausible methods for item management, and more specifically, item data storage. My requirements are:
Five item classes (Weapon, Collectable, Food etc.)
Of these five classes, there are 5-10 different item types. (Machine gun, pistol, sniper rifle etc). No difference in script, just different variables in the inspector.
Of these items, each individual item has its properties edited at runtime. (Weapon.fRateOfFire += 1)
Every single object needs to be able to be picked up/dropped, and stored in the player inventory.
While I'm not looking for one outright answer, any and all advice you could give to improve my method, or suggest appropriate alternatives, would be highly valuable.
My method
Item Manager: Stores the functions that allow picking up/dropping, and structures that the player can use to store variable data for instances of items.
Player_Generic: On a per-player basis, this script attaches to the player prefab, and deals with controls, interactions, and player data storage, including the player inventory. Every time the player picks up an object, its data is copied from its script and placed into this structure, to be stored in a list.
(Example) Item_Weapon: The class for each item type. This only contains public variables, and is attached to each item prefab.
Item_Weapon_Pistol(In the pistol prefab): In the inspector, I can set default values for these items. These will be spawned into the game world with their default properties, and during run-time, these variables can be edited.
While, in theory, this will work fine, it does seem like somewhere, what I'm doing is unnecessary. For example, I'm storing individual item properties in two places, depending on where it is. I.e. Both in the instance of the object, or as a structure inside the Player_Generic script. Ideally, I would just reference a global list of items. However, I have no idea how to save that, especially with varying structure types.
Which leads me to my next problem, how can I store multiple structs of varying (and sometimes identical) types in an inventory? Similar to minecraft, you could have two identical items, except one has high durability, while one has low. I know I need to make a primitive GUID system, but its only necessary for the inventory, as, outside it, items are separated by scripts.
To pick up items, I've got a working ray cast from player mouse, that returns the game object hit if it has the tag "Item". I then check that item for each of the scripts:
Attempt to get the first script type using getcomponent. (working)
If it is not null, get the data of that type (working) and put it into a struct. (not attempted yet, so far I can debug.log the data that I obtain)
Delete the instance and return (working)
If it is null, repeat with next script type, and see if the item contains that script.
The trouble I've had with structuring Unity scripts is that it differs quite dramatically with the language I'm learning primarily (C++). While I've been adjusting, I'm always worried that the methods that I've got for each system is completely inefficient, I just cant think of a better way.
However, from what I've read, making a global list of all items, and then simply moving the reference to the player inventory, seems to be the best option, I just need an example of that (or a base) to work with.
Cheers for reading, and thanks for the help!
Answer by Kryptos · Apr 11, 2012 at 11:29 AM
To solve the duplicate properties issues, you can 'delegate' the properties to a data class. The item object and Player_Generic will then have a reference to the data rather than dealing with copies.
To make sure thoses data are editable inside Unity, just make a Serializable class. Something like:
public interface Item_Data
{
}
[System.Serializable]
public class Item_WeaponData : Item_Data
{
public float yourVariable;
// ...
}
public class Item_Weapon : MonoBehaviour
{
public Item_WeaponData data;
// ...
}
public class Player_Generic : MonoBehaviour
{
public List<Item_Data> itemsDataList;
// ...
}
Thank you very much! This always happens: I ask a question and moments later stumble upon loads of resources. So to deviate slightly, could you tell me more about the function "interface". I've never seen it before, so have no idea how its used. I can see that you put in in the same place as $$anonymous$$onobehaviour, but then again I dont know much about that either.
An interface is a class definition: you declare properties and methods without their implementation. It is like a contract.
In C#, a class can only inherits from one class, but can implement several interfaces.
In your case, the goal is to be able to have different Item_Data
in the same list (`List`). But it is not mandatory, you can also use the non-generic list from System.Collections
. Or you can create a base class for all your items and inherits from it:
public class Item_Data
{
// put common properties here
}
[System.Serializable]
public class Item_WeaponData : Item_Data
{
// put specific properties here
}
The main part of my code sample is the use of a Serializable
class which values can be edited inside Unity.
Again, thank you! Very informative! So an interface is like a virtual class in C++, that defines values, but to declare them, you must declare them inside classes?
Also, so you are saying that [System.Serializable] will prevent run-time variable changing? Sort of like an external database?
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Need advice for C# Freelance-Work 1 Answer
How to force a script to affect only a single instance of the object it is applied to? 0 Answers
Inventory AddItem help 1 Answer