'인벤토리'에 해당되는 글 1건

  1. 2014.04.07 유니티 인벤토리 관련 구현

유니티 인벤토리 관련 구현

|








자료 구조를 말씀하시는 건가요? 
보통 사이즈가 정해져 있는 인벤 같은 경우에는 배열로 하고, 
유동적으로 늘어나는 것은 맵 같은 자료를 많이 써요. 
아무래도 인벤토리의 아이템들은 서치도 빈번하게 일어나니까요. 
또 인덱스 위치랑 바로 매칭이 되고요. 
저도 기존에 온라인 rpg 유지보수 일 하면서 소소를 많이 봤는데 대부분 이런식으로 하더라구요. 
그리고 이번에 직접 플젝에 인벤을 구현했는데 직접 손으로 만들어보니까 생각보다 
신경 써야 할 부분들이 많더라구요. 
인벤토리 한 칸에 들어가야 할 정보들... 즉, 아이템 하나가 가지는 속성들을 잘 생각하셔서 
구조체로 만들고 이것들을 관리하는 자료구조를 잘 적용하고 설계하는 것을 주 목표로 잡으시면 될 것 같네요







일단 첨부하신건 보지 않았습니다. 

아이템에 수량이 존재한다면 다음처럼 풀 수 있을 것입니다. 

저는 c#으로 짜기때문에 c#으로 작성해보겠습니다. 

갯수를 가진 아이템 넣고 빼는 것중에서 가장 심플한 형태라고 생각합니다. 




이 재료로 이제 알아서 뿌려주시면 됩니다. 

UI와 연결하는것이나 아이템을 저장&불러오는 것은 본인의 재량으로... 

저 컴포넌트를 가진 게임오브젝트를 인벤토리로 만드시고 

OnGUI 함수 만드셔서 직접 뿌려줘도 될 것입니다.













Stacking Items in a Inventory List

0
1

I have my inventory script, an enemy script with item dropping and looting, and an Item Class script all in Java. It all works fine, but I'm trying to find a way to make Items stackable. I have added a stackable boolean to my items and set them to true as well as a stack limit and amount variable. What I don't understand is how, when a button is clicked, can I search through a list for that item, if it exists change a varialble on that item. That is my only problem with this script right now. Here are those scripts(one being just a snippet).

My Item Class.

  1. class ItemClass{
  2. public var ItemID : int;
  3. public var Name : String;
  4. public var icon : Texture2D;
  5. public var Description : String;
  6. public var Value : int;
  7. var Amount : int;
  8. public var itemType : ItemType;
  9. public var potionType : PotionType;
  10. public var potionAmount : int;
  11. public var stackAble : boolean;
  12. public var maxStack : int;
  13.  
  14. public enum ItemType{
  15. Potion,
  16. Weapon,
  17. QuestItem
  18. };
  19.  
  20.  
  21. public enum PotionType{
  22. None,
  23. Heal,
  24. Stamplus,
  25. strplus,
  26. agplus
  27. };
  28. }

My Enemy

  1. import System.Collections.Generic;
  2.  
  3. var life = 100;
  4. var exp = 50;
  5. var drops : List.<ItemClass> = new List.<ItemClass>();
  6. var looting : boolean = false;
  7. var lootable : boolean = false;
  8. var lootRect : Rect = Rect(500,500,250,75);
  9. var LOOT_ID : int = 3;
  10.  
  11. var skin : GUISkin;
  12.  
  13.  
  14. function Start () {
  15.  
  16.  
  17. }
  18.  
  19. function Update () {
  20.  
  21.  
  22. if (life <= 0 && lootable == false ){
  23. gameObject.SendMessageUpwards("AddExp", exp);
  24. gameObject.tag = "Lootable";
  25. lootable = true;
  26. }
  27. }
  28.  
  29. function OnGUI(){
  30. GUI.skin = skin;
  31.  
  32. var levelManager = GameObject.Find("LevelManager").GetComponent(LevelManager);
  33.  
  34. if(looting == true && levelManager.paused == true ){
  35. lootRect = GUI.Window(LOOT_ID,lootRect,LootWindow,"Looting" + this.name);
  36. lootRect.y = Mathf.Clamp(lootRect.y,0,Screen.height-lootRect.height);
  37. lootRect.x = Mathf.Clamp(lootRect.x,0,Screen.width-lootRect.width);
  38. }
  39. if(looting == true && levelManager.paused == false){
  40. looting = false;
  41. }
  42. }
  43.  
  44. function Hit(){
  45. life -= 10;
  46.  
  47. }
  48.  
  49.  
  50.  
  51. function LootWindow(id : int){
  52. GUI.BringWindowToFront(id);
  53. GUI.DragWindow(Rect(20,0,lootRect.width-20 ,15));
  54. for( var x : int = 0; x< drops.Count; x++){
  55. if(GUI.Button(Rect(10 +(x * 45), 20,45,45), GUIContent(drops[x].icon,drops[x].Description), skin.customStyles[1])){
  56. if(drops[x].stackAble.Equals(true) && PlayerInventory.Inventory.Contains(drops[x])){
  57. var item = PlayerInventory.Inventory[PlayerInventory.Inventory.IndexOf(drops[x])];
  58. item.Amount += 1;
  59. drops.RemoveAt(x);
  60. }
  61. else
  62. {
  63. PlayerInventory.Inventory.Add(drops[x]);
  64. drops.RemoveAt(x);
  65. }
  66. }
  67. }
  68. if (GUI.Button(Rect(3,3,10,10),"x")){
  69. looting = false;
  70. }
  71.  
  72. }
  73.  
  74.  
  75.  
  76.  
  77. function Loot(){
  78. looting = true;
  79. return;
  80. }

my inventory class

  1. #pragma strict
  2. import System.Collections.Generic;
  3.  
  4.  
  5. public class PlayerInventory
  6. {
  7.  
  8. static var Inventory : List.<ItemClass> = new List.<ItemClass>();
  9.  
  10.  
  11. }
  12.  
  13.  
  14.  
  15. function Start(){
  16.  
  17. }
  18. function Update(){
  19.  
  20.  
  21. }

And the snippet that deals with the inventory in my levelmanager script.

  1. function Inventory(id : int){
  2.  
  3. GUI.DragWindow(Rect(0,0,InventoryRect.width,15));
  4.  
  5. var cnt : int = 0;
  6.  
  7.  
  8.  
  9. for(var x = 0; x < inventoryRows; x++){
  10. for(var y = 0; y < inventoryCols; y++){
  11. if (cnt < PlayerInventory.Inventory.Count){
  12.  
  13. var texture : Texture2D = PlayerInventory.Inventory[cnt].icon;
  14. var description : String = PlayerInventory.Inventory[cnt].Name + "\n" + PlayerInventory.Inventory[cnt].Description;
  15. if(GUI.Button(Rect(10 + (y * itemWidth ),20 + (x * itemHeight ), itemWidth, itemHeight),GUIContent(texture,description), customSkin.customStyles[1])){
  16. if(PlayerInventory.Inventory[cnt].itemType.Equals(ItemClass.ItemType.Potion) && PlayerInventory.Inventory[cnt].potionType.Equals(ItemClass.PotionType.Heal) && PlayerInventory.Inventory[cnt].Amount > 1){
  17. Health += PlayerInventory.Inventory[cnt].Amount;
  18. PlayerInventory.Inventory[cnt].Amount-= 1;
  19. if(PlayerInventory.Inventory[cnt].Amount == 1){
  20. PlayerInventory.Inventory.RemoveAt(cnt);
  21. }
  22. }
  23. else if(PlayerInventory.Inventory[cnt].itemType.Equals(ItemClass.ItemType.Weapon)){
  24. if(!GetComponent(WeaponManager).WeaponSlot[0].Name.Equals(""))
  25. PlayerInventory.Inventory.Add(GetComponent(WeaponManager).WeaponSlot[0]);
  26. GetComponent(WeaponManager).WeaponSlot[0] =(PlayerInventory.Inventory[cnt]);
  27. PlayerInventory.Inventory.RemoveAt(cnt);
  28.  
  29. }
  30. else{
  31. PlayerInventory.Inventory.RemoveAt(cnt);
  32. }
  33. }
  34. }
  35. else{
  36. GUI.Box(Rect(10 + (y * itemWidth ),20 + (x * itemHeight ), itemWidth, itemHeight),"", customSkin.customStyles[0]);
  37. }
  38. cnt++;
  39.  
  40. }
  41. }
  42. }

I'm not looking for a system all coded out, or I would have already done that. I like the way my system works, and the fact I made it. this is the first time I've come to the answers community and I hope I can learn something here. Any help would be appreciated :)

more ▼

asked Aug 17 '12 at 09:32 PM

mactinite77 gravatar image

mactinite77 
58  1  1  3


2 answers:sort voted first 
1

Well there are some things i would change ;)

First the boolean is redundant. Since you have a MaxStack variable you can simply set it to 0 or -1 for items that aren't stackable.

Next thing is how can you tell that two items are of the same type? ItemID? Name? You have to specify a criteria which you can use to identify similar items.

I would probably create a filter function. Something like that:

  1. public class PlayerInventory
  2. {
  3. static var Inventory : List.<ItemClass> = new List.<ItemClass>();
  4. static function FilterItems(ID : int) : List.<ItemClass>
  5. {
  6. var result = new List.<ItemClass>();
  7. for(var item : ItemClass in Inventory)
  8. {
  9. if (item.ItemID == ID && item.Amount < item.maxStack)
  10. result.Add(item);
  11. }
  12. return result;
  13. }
  14.  
  15. }
  16.  
  17. // [...]
  18. for( var x : int = 0; x< drops.Count; x++)
  19. {
  20. if(GUI.Button(Rect(10 +(x * 45), 20,45,45), GUIContent(drops[x].icon,drops[x].Description), skin.customStyles[1]))
  21. {
  22. if( drops[x].maxStack > 0)
  23. {
  24. var stacks = PlayerInventory.FilterItems(drops[x].ItemID);
  25. if (stacks.Count > 0)
  26. {
  27. stacks[0].Amount++;
  28. drops.RemoveAt(x);
  29. x--; // Since we removed this one
  30. }
  31. else // when there is no stack yet or all stacks are full, add a new one
  32. {
  33. PlayerInventory.Inventory.Add(drops[x]);
  34. drops.RemoveAt(x);
  35. x--;
  36. }
  37. }
  38. else
  39. {
  40. PlayerInventory.Inventory.Add(drops[x]);
  41. drops.RemoveAt(x);
  42. x--;
  43. }
  44. }
  45. }

Note: I just wrote / modified that here on UA so there might be some syntax errors ;)

I just compared the ItemID in this case. Maybe you want something else?!

more ▼

answered Aug 18 '12 at 01:55 AM

Bunny83 gravatar image

Bunny83 
66.3k  22  68  267

You are brilliant. This worked like a dream, albeit with some modification to my inventory managing but it worked out perfectly. This is where I was trying to go with my script, but I had no idea how to approach this. Thank you very much for showing me.

Aug 18 '12 at 03:01 AMmactinite77
0

Take a look, maybe you can do something like this(C# Code):

  1. public class Items
  2. {
  3. public int life;
  4. public int price;
  5. public int weight;
  6. }
  7.  
  8. //Creating our List
  9. public List<Items> inventory = new List<Items>();
  10.  
  11. void Start()
  12. {
  13. //Creating some items to put in the list
  14. Items potion = new Items();
  15. potion.life = 50;
  16. potion.price = 70;
  17. potion.weight = 10;
  18.  
  19. Items sword = new Items();
  20. sword.life = 150;
  21. sword.price = 350;
  22. sword.weight = 100;
  23.  
  24. //Adding them to the list
  25. inventory.Add(potion);
  26. inventory.Add(sword);
  27.  
  28. //Searching for the sword
  29. foreach (Items i in inventory)
  30. {
  31. if(i == sword)
  32. {
  33. Debug.Log(i.price); //Loging the current price
  34. i.price = 8001; // Chanching the proce
  35. }
  36. }
  37.  
  38. Debug.Log(sword.price); // Loging the swrod price to double check our implementation works!
  39. }
  40. }

(Tested)

more ▼

answered Aug 18 '12 at 02:20 AM

Paulo Henrique gravatar image

Paulo Henrique 
876  13  20  26

Your answer







The code is like http://www.burgzergarcade.com/. Thanks to his tutorials i was able to start a game. I have been modifying and changing so it can become my own game. i would really like to be able to stack items, since my inventory will have infinity items. I am not sure how to start with the code to check if item is same vs quantity vs stack number.

May 28 '13 at 11:00 PMssoulreaper
  1. public class Item
  2. {
  3. public int itemID;
  4. public string name = "";
  5. public int level;
  6. public bool stackable = true;
  7. public int quantity = 1;
  8. public int maxQuantity = 99;
  9. public int stack = 1;
  10. public int maxStack = 5;
  11. public int attack;
  12. public int physicalDefense;
  13. public int charges;
  14. public int cost;
  15. public string description = "";
  16. public Texture2D icon;
  17. }
  18.  
  19. public static class ItemGenerator
  20. {
  21.  
  22. public static Weapon AddMeleeWeapon(ItemsNames meleeWeaponName, int quantity)
  23. {
  24. Weapon meleeWeapon = new Weapon();
  25.  
  26. switch(meleeWeaponName)
  27. {
  28. case ItemsNames.Sword:
  29. meleeWeapon.itemID = 1;
  30. meleeWeapon.name = "Sword";
  31. meleeWeapon.level = 1;
  32. meleeWeapon.stackable = true;
  33. meleeWeapon.quantity = quantity;
  34. meleeWeapon.maxQuantity = 99;
  35. meleeWeapon.stack = 1;
  36. meleeWeapon.maxStack = 5;
  37. meleeWeapon.attack = 10;
  38. meleeWeapon.cost = 5;
  39. meleeWeapon.description = "Iron Sword";
  40. break;
  41. default:
  42. break;
  43. }
  44.  
  45. meleeWeapon.icon = Resources.Load( "Item/Icon/Weapon/Melee/" + "Sword" ) as Texture2D;
  46.  
  47. return meleeWeapon;
  48. }
  49. }
  50.  
  51. public class Chest : MonoBehaviour
  52. {
  53. public List<Item> loot = new List<Item>();
  54.  
  55. void Start()
  56. {
  57. loot.Add(ItemGenerator.AddMeleeWeapon( ItemsNames.Sword ));
  58. loot.Add(ItemGenerator.AddMeleeWeapon( ItemsNames.Sword ));
  59. loot.Add(ItemGenerator.AddMeleeWeapon( ItemsNames.Sword ));
  60. loot.Add(ItemGenerator.AddMeleeWeapon( ItemsNames.Sword ));
  61. }
  62. }
  63.  
  64. public class PC : BaseCharacter(MonoBehavior)
  65. {
  66. private List<Item> inventory = new List<Item>();
  67.  
  68. public List<Item> Inventory
  69. {
  70. get { return inventory; }
  71. set { inventory = value; }
  72. }
  73. }
  74.  
  75. public class MyGUI : MonoBehaviour
  76. {
  77.  
  78. private void LootWindow(int id)
  79. {
  80.  
  81. for(int cnt = 0; cnt < chest.loot.Count; cnt++)
  82. {
  83. if(GUI.Button(new Rect(5 +(50 * cnt), 10, 50, 50), new GUIContent(chest.loot[cnt].icon)))
  84. {
  85. PC.Instance.Inventory.Add(chest.loot[cnt]);
  86. chest.loot.RemoveAt(cnt);
  87. }
  88. }
  89. }
  90.  
  91. public void InventoryWindow(int id)
  92. {
  93. int cnt = 0;
  94.  
  95. for(int y = 0; y < 15; y++)
  96. {
  97. for(int x = 0; x < 10; x++)
  98. {
  99. if(cnt < PC.Instance.Inventory.Count)
  100. {
  101. if(GUI.Button(new Rect(5 + ( x * buttonWidth ), 20 + (y * 50), 50, 50), new GUIContent(PC.Instance.Inventory[cnt].icon)))
  102. {
  103. }
  104. }
  105. else
  106. {
  107. GUI.Button(new Rect(10 + x * 50, 25 + y * 50, 50, 50), "");
  108. }
  109.  
  110. cnt++;
  111. }
  112. }
  113. }
  114. }

This is Trimmed down to explain what i have.


Trackback 0 And Comment 0
prev | 1 | next