- Home /
Item pick up system
I'm working on a game with strong RPG elements; item pick up is a good example of this. I want to create a system that involves placing a dummy prefab on the ground with a script (1. pick up helper script) containing, or leading into a database containing (whichever is quicker) properties of the item being picked up. This script(1) then translates these properties to the player's inventory system which uses the data provided by script(1) to display this item in the player's inventory, decide what assets to use if the player equips the item, and confer any stat bonuses afforded by the item if it is equipped. My questions are these: what types of messages or unity commands could I use to transfer information in that way? and would using a database of item properties be beneficial in terms of efficiency?
I suggest against the use of a Database in any game. It means your data needs to get saved outside of Unity and in many cases traditional approaches are just as fast. It also means, that some features that you would need might not be supported and if you were using a database it would be a pain (if not impossible) to implement them :)
I understand. So how could i send a message from the item being picked up can be interpreted like this: player's cursor is on the object, it is deter$$anonymous$$ed that it is an item (I know how to do this, just being thorough). The player asks to pick up the item, and the pick up system tells the inventory system a phrase or code that the inventory system can interpret as a certain item with certain properties (this second part is where I am lost). I would imagine that I would have to implement an array of items that it could be, and narrow it down with tags on the actual physical object. $$anonymous$$y problem is that I don't know how to send a message when interacting with one particular object that has the ability to be procedurally placed.
As mentioned, Db is not really the solution for object attributes. It is more likely if you want to store information and being able to compare them with other player's information like their score, achievement or else. And still, that is only if you want to compare or allow the player to use his info across different devices. Apart from that, store on the machine, faster and safer.
For your comment/question, you need to use a raycast, that is sent from the player in front of him. When the ray collides, you get info on the cllision and you can check what you are oclliding with. If it is one of those items then you can open a GUI for info. Check out the raycast page on Unity API, it has the example given.
@BenProductions1, true. But he should learn easy first then when he got this one going, he can start using binary values(still easy to convert) then later he can go for encryption to really give a hell to the hacker.
But @bubzy, I would go for basic class variables. That would prevent cheating and is faster and safer. What if your user delete the file? -> Crash. Or you could use the PlayerPrefs class from unity that stores info in the registry then harder to find.
Answer by Cherno · Aug 26, 2013 at 01:10 AM
I can't provide any code that would fit your particular needs, but here's a basic outline how I would do it:
The dummy object has of course a collider attached. Set the object's tag to "item" or whatever you create for it.
When clicked, check if the MainCamera.ScreenPointToRay (Input.mousePosition) ray hits the dummy's collider, and check if the object you hit has an item tag.
If you are sure it was an item, just store the gameobject either directly into your inventory array/list (containg item GameObjects), OR, if you want it to "pick up" first into your virtual "hand" so you could drop it again or put it into your inventory from there, assign the clicked item to a "hand slot" GameObject variable. Then you could put it into your inventory array if you click on a GUI element representing an inventory slot, but be sure to set the hand slot to null (when dropping the item as well). Whenever the item is picked up from your world, set collider.enabled and renderer.enabled to false, and to true when you drop it again into the world.
If you want to have different item types, you could just add a simple int variable to your item script, like 0 = melee weapon, 1 = ranged weapon, 2 = healing item and so on. This could let the game/inventory identify which kind of item it is, and you only need one kind of tag.
Hope that helps get you started.
Here's how my item script looks, it has enums so you can select which kind of item it is without having to use multiple item scripts (helps a lot when your game only need to check for one kind of item script, letting the "type" variable inside tell what it actually is)
//select a specific item from the drop down lists below in //the inspector. Note that only the last one selected gets //accepted if you have more than one, so be sure to set one //to your item and the rest to NONE.
var RangedWeapon : RangedWeaponEnum;
enum RangedWeaponEnum
{
None,
Colt1911
}
var MeleeWeapon : MeleeWeaponEnum;
enum MeleeWeaponEnum
{
None,
CombatKnife
}
var Type : TypeEnum;//don't touch this one, it gets assigned by the game at start!
enum TypeEnum
{
RangedWeapon,
MeleeWeapon,
HealingItem
}
//item statistics
var Name : String;
var Description : String;
var Weight : float = 1.0; //weight in kilograms
var Condition : float = 100;
var Stackable : boolean;
var MaxStackSize : int;
var Damage : int;
//how much damage is dealt each hit (or how much is healed if it's a healing item)
var Owner : GameObject;//who is the current owner? change when picked up or dropped (null).
//check which kind of item was selected in the inspector, and assign the item type (melee, //ranged etc.) according to it. The type variable is mainly used for the UseItem function below.
function Start ()
{
if(RangedWeapon != 0)
{
Type = 0;
if(RangedWeapon == 1){Colt1911();}
if(RangedWeapon == 2){Tommygun();}
if(RangedWeapon == 3){BoltActionRifle();}
}
if(MeleeWeapon != 0)
{
Type = 1;
if(MeleeWeapon == 1){CombatKnife();}
if(MeleeWeapon == 2){MeatCleaver();}
if(MeleeWeapon == 3){CavalrySabre();}
}
if(Healing != 0)
{
Type = 2;
if(Healing == 1){MedKit();}
}
}
function HideItem()//when it's picked up
{
transform.position = Vector3(0,0,0);
renderer.enabled = false;
collider.enabled = false;
}
function ShowItem()//when it's dropped, world position has to be set too
{
renderer.enabled = true;
collider.enabled = true;
}
//what happens when the item is used?
function UseItem(Target : GameObject, TargetPos : Vector3)
{
if(Type == 0)//ranged weapon
{
//deal damage to target etc.
}
if(Type == 1)//melee weapon
{
//deal damage to target etc.
}
if(Type == 2)//healing item
{
//Heal user
}
}
function Colt1911()
{
Name = "Colt 1911";
Weight = 1.0;
Stackable = false;
//MaxStackSize = 5;
Description = "The venerable Colt 1911 in .45 calibre.";
Damage = 10;
}
function CombatKnife()
{
Name = "Combat Knife";
Weight = 1.0;
Stackable = false;
//MaxStackSize = 5;
Description = "A heavy Bowie knife.";
Damage = 10;
}
function MedKit()
{
Name = "MedKit";
Weight = 1.0;
Stackable = true;
MaxStackSize = 2;
Description = "A small pouch containing various medical supplies designed for quick use during and after combat.";
Damage = 50;
}
//... and so on. basically, you have one function per specific item that is called at start to //assign all item values.
I$$anonymous$$O that's a very clunky and messy method. Depending on the number of items you could have millions of lines of code that would be very hard to traverse (especially if your items are more complex), especially because you have to add all your functions into another function for calling.
However, it does work :)
Yes I agree. It is certainly cumbersome to navigate if there are a lot of items to cover. On the plus side, it keeps all item information in one place ;)
I also experimented with having the specific item data stored in seperate scripts, each one different with hard-coded values, attached to an item library object of sorts, and then referring to these scripts for assigning values for the generic item script values on start.
Cherno, you are going the right direction. I have a different idea about the system now. I have to agree with Benproductions though, I need to be able to spawn many items on the ground or in containers. I also have to spawn many different types of items. Benproductions, can you talk a little about your idea for a leaner method? One that allows for simple reproduction over many different specific items grouped into item types? I have the idea that I can do something like this: An A$$anonymous$$-47 is a Rifle weapon in the Ranged weapons group. Ranged weapons are weapons. Weapons are items. An iron sword is a blade weapon in the melee weapons group. melee weapons are weapons and weapons are items. Can I simply say that all weapons have damage and that all ranged weapons have damage and accuracy; then could i say that Rifles have a base Damage and accuracy of 20 and an A$$anonymous$$-47 has + 5 damage but -5 accuracy? I'm thinking of taking a series of steps and applying properties and values along the way. Is this possible?
Your answer
Follow this Question
Related Questions
Implementing an offline Inventory that must sync with a server 0 Answers
RPG ability database - Scriptable Object vs XML vs Prefab? 0 Answers
How do I retrieve an item from a list? 1 Answer
Simple Dictionary / Hashtag system for Inventory with Unityscript only ?? (no C#) 1 Answer
Simple inventory 1 Answer