added cost amount to items

added Shop UI
added Shop.cs
 * you now can buy items and you lose the cost when bought
 * shop is scrollable

added comments in Inventory.cs, InventorySlot.cs, InventoryUI.cs
now showing description when hovering over items in shop or inventory
This commit is contained in:
d-hain 2022-06-02 00:08:37 +02:00
parent c9416181fc
commit ce1f6ed389
30 changed files with 4726 additions and 64 deletions

View file

@ -0,0 +1,48 @@
using System;
using TMPro;
using UnityEngine;
public class HoverManager : MonoBehaviour {
public TextMeshProUGUI descriptionText;
public RectTransform descriptionHoverBackground;
public static Action<string, Vector2> onMouseHover;
public static Action onMouseExit;
private void OnEnable() {
onMouseHover += ShowDescription;
onMouseExit += HideDescription;
}
private void OnDisable() {
onMouseHover -= ShowDescription;
onMouseExit -= HideDescription;
}
private void Start() {
HideDescription();
}
/**
* Show the description Text at the mouse position
*/
private void ShowDescription(string description, Vector2 mousePos) {
descriptionText.text = description;
descriptionHoverBackground.sizeDelta =
new Vector2(descriptionText.preferredWidth > 200 ? 200 : descriptionText.preferredWidth,
descriptionText.preferredHeight);
descriptionHoverBackground.gameObject.SetActive(true);
float descBgX = descriptionHoverBackground.sizeDelta.x;
descriptionHoverBackground.transform.position =
new Vector2(mousePos.x + (descBgX / 2) + (descBgX / 16), mousePos.y);
}
/**
* Hide the description Text
*/
private void HideDescription() {
descriptionText.text = default;
descriptionHoverBackground.gameObject.SetActive(false);
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cc03ecff3c94867408bc3475337a6b03
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -1,5 +1,5 @@
using UnityEngine;
public interface IUsable {
public void select();
public void Select();
}

View file

@ -1,5 +1,3 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -20,8 +18,11 @@ public class Inventory : MonoBehaviour {
public Dictionary<Item, int> items;
public Item[] startItems;
public const int inventorySpace = 28;
public const int InventorySpace = 28;
/**
* Methods can be added to this and they will get called every time onItemChangedCallback gets Invoked
*/
public delegate void OnItemChanged();
public OnItemChanged onItemChangedCallback;
@ -32,8 +33,11 @@ public class Inventory : MonoBehaviour {
}
}
/**
* Adds the specified amount of items to the Inventory
*/
public void AddItem(Item item, int amount) {
if(items.Count >= inventorySpace) {
if(items.Count >= InventorySpace) {
Debug.Log("Not enough inventory space!");
return;
}
@ -46,12 +50,15 @@ public class Inventory : MonoBehaviour {
onItemChangedCallback?.Invoke();
}
/**
* Removes the specified amount of items in the Inventory
*/
public void RemoveItem(Item item, int amount) {
if(items[item] <= 0) {
items.Remove(item);
} else {
items.Add(item, -amount);
items[item] -= amount;
}
onItemChangedCallback?.Invoke();

View file

@ -1,16 +1,47 @@
using System;
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.PlayerLoop;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class InventorySlot : MonoBehaviour {
public class InventorySlot : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler {
public Image icon;
private Item _item;
public TextMeshProUGUI amountText;
private void Start() {
Physics.queriesHitTriggers = true;
public Item _item;
#region DescriptionHover
public float timeToWait;
public void OnPointerEnter(PointerEventData eventData) {
StopAllCoroutines();
StartCoroutine(StartTimer());
}
public void OnPointerExit(PointerEventData eventData) {
StopAllCoroutines();
HoverManager.onMouseExit();
}
private void ShowMessage() {
if(_item){
HoverManager.onMouseHover(_item.description, Input.mousePosition);
}
}
private IEnumerator StartTimer() {
yield return new WaitForSeconds(timeToWait);
ShowMessage();
}
#endregion
/**
* Sets the Item of the Inventory Slot
*/
public void AddItem(Item newItem) {
_item = newItem;
@ -18,33 +49,24 @@ public class InventorySlot : MonoBehaviour {
icon.enabled = true;
}
/**
* Clears the Inventory Slot
*/
public void ClearSlot() {
_item = null;
icon.sprite = null;
icon.enabled = false;
}
public void RemoveItem() {
Inventory.instance.items.Remove(_item);
}
/**
* Gets called when the Inventory Slot is clicked
*/
public void UseItem() {
if(_item.GetType() == typeof(UsableItem)) {
((UsableItem) _item).select();
((UsableItem) _item).Select();
Debug.Log("using " + _item.displayName);
} else {
Debug.Log("Item not usable " + _item.displayName);
}
}
public void OnMouseOver() {
icon.sprite = _item.selectedSprite;
Debug.Log("Mouse Over Slot");
}
//TODO: OnMouse Methods not working :'(
public void OnMouseExit() {
icon.sprite = _item.defaultSprite;
Debug.Log("Mouse Exit Slot");
}
}

View file

@ -1,3 +1,4 @@
using System;
using System.Linq;
using UnityEngine;
@ -7,30 +8,44 @@ public class InventoryUI : MonoBehaviour {
private Inventory _inventory;
private InventorySlot[] _slots;
// Start is called before the first frame update
void Start() {
private void Start() {
// Get Inventory instance and add UpdateUI method to OnItemChanged delegate
_inventory = Inventory.instance;
_inventory.onItemChangedCallback += UpdateUI;
// Add all InventorySlot GameObjects to _slots and turn off the Inventory UI
_slots = itemsParent.GetComponentsInChildren<InventorySlot>();
ToggleInventory();
// Set the icon to not be a raycast target for the Description Hovering to work
foreach(InventorySlot slot in _slots) {
slot.icon.raycastTarget = false;
}
}
// Update is called once per frame
void Update() {
private void Update() {
// When "Inventory" button is pressed turn on/off Inventory UI
if(Input.GetButtonDown("Inventory")) {
ToggleInventory();
}
}
/**
* Turn on/off the Inventory UI
*/
private void ToggleInventory() {
inventoryUI.SetActive(!inventoryUI.activeSelf);
}
/**
* Is called when something in the Inventory UI should update
*/
private void UpdateUI() {
// Add all items to the correct slots and clear the ones where no item should be
for(int i = 0; i < _slots.Length; i++) {
if(i < _inventory.items.Count) {
_slots[i].AddItem(_inventory.items.ElementAt(i).Key);
_slots[i].amountText.text = "" + _inventory.items[_inventory.items.ElementAt(i).Key];
} else {
_slots[i].ClearSlot();
}

View file

@ -21,23 +21,20 @@ public class PlayerController : MonoBehaviour {
#endregion
private Inventory _inventory;
private int money;
private UsableItem selectedItem;
public int money;
private UsableItem _selectedItem;
public int startMoney = 100;
// Start is called before the first frame update
void Start() {
private void Start() {
money = startMoney;
_inventory = Inventory.instance;
}
// Update is called once per frame
void Update() { }
public void SetSelectedItem(UsableItem item) {
if(_inventory.items.ContainsKey(item)) {
selectedItem = item;
_selectedItem = item;
Cursor.SetCursor(item.selectedSprite.texture, Vector2.zero, CursorMode.Auto);
} else {
Debug.Log("An item requested to select isn't in the inventory" + item);
@ -45,6 +42,6 @@ public class PlayerController : MonoBehaviour {
}
public UsableItem GetSelectedItem() {
return selectedItem;
return _selectedItem;
}
}

60
Assets/Scripts/Shop.cs Normal file
View file

@ -0,0 +1,60 @@
using System.Collections.Generic;
using UnityEngine;
public class Shop : MonoBehaviour {
#region Singleton
public static Shop instance;
private void Awake() {
if(instance != null) {
Debug.LogWarning("More than one instance of Shop found");
}
instance = this;
}
#endregion
public Dictionary<Item, int> items;
public Item[] tempItems;
/**
* Methods can be added to this and they will get called every time onItemChangedCallback gets Invoked
*/
public delegate void OnItemChanged();
public OnItemChanged onItemChangedCallback;
private void Start() {
items ??= new Dictionary<Item, int>();
foreach(Item item in tempItems) {
AddItem(item, 1);
}
}
/**
* Adds the specified amount of items to the Shop
*/
public void AddItem(Item item, int amount) {
if(!items.ContainsKey(item)) {
items.Add(item, amount);
} else {
items[item] += amount;
}
onItemChangedCallback?.Invoke();
}
// TODO: add to buy more than one item
/**
* Removes the specified amount of items in the Shop
*/
public void RemoveItem(Item item, int amount) {
if(items[item] <= 0) {
items.Remove(item);
} else {
items[item] -= amount;
}
onItemChangedCallback?.Invoke();
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bc5eb8967b8912c42b93a2086383ddd9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,93 @@
using System;
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ShopSlot : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler {
public Image icon;
public Item item;
public TextMeshProUGUI nameText;
public TextMeshProUGUI costText;
public TextMeshProUGUI amountText;
private Shop _shop;
private Inventory _inventory;
private PlayerController _playerController;
#region DescriptionHover
public float timeToWait;
public void OnPointerEnter(PointerEventData eventData) {
StopAllCoroutines();
StartCoroutine(StartTimer());
}
public void OnPointerExit(PointerEventData eventData) {
StopAllCoroutines();
HoverManager.onMouseExit();
}
private void ShowMessage() {
if(item) {
HoverManager.onMouseHover(item.description, Input.mousePosition);
}
}
private IEnumerator StartTimer() {
yield return new WaitForSeconds(timeToWait);
ShowMessage();
}
#endregion
private void Start() {
_shop = Shop.instance;
_inventory = Inventory.instance;
_playerController = PlayerController.instance;
}
/**
* Sets the Item of the Shop Slot
*/
public void AddItem(Item newItem) {
item = newItem;
icon.sprite = item.defaultSprite;
icon.enabled = true;
}
/**
* Clears the Shop Slot
*/
public void ClearSlot() {
item = null;
icon.sprite = null;
icon.enabled = false;
nameText.text = "";
costText.text = "";
amountText.text = "";
}
/**
* Gets called when the Shop Slot is clicked
*/
public void UseItem() {
if(_playerController.money >= item.cost) {
_inventory.AddItem(item, 1);
_shop.RemoveItem(item, 1);
_playerController.money -= item.cost;
Debug.Log("Buying Item: " + item.displayName);
Debug.Log("money left: " + _playerController.money);
} else {
Debug.Log("Not enough money to buy item.");
}
_shop.onItemChangedCallback?.Invoke();
_inventory.onItemChangedCallback?.Invoke();
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3e6f808bd381a554eb64a7e84f997f45
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

57
Assets/Scripts/ShopUI.cs Normal file
View file

@ -0,0 +1,57 @@
using System.Linq;
using UnityEngine;
public class ShopUI : MonoBehaviour {
public Transform itemsParent;
public GameObject shopUI;
private Shop _shop;
private ShopSlot[] _slots;
private void Start() {
// Get Shop instance and add UpdateUI method to OnItemChanged delegate
_shop = Shop.instance;
_shop.onItemChangedCallback += UpdateUI;
// Add all ShopSlot GameObjects to _slots and turn off the Shop UI
_slots = itemsParent.GetComponentsInChildren<ShopSlot>();
ToggleShop();
// Set the icon to not be a raycast target for the Description Hovering to work
foreach(ShopSlot slot in _slots) {
slot.icon.raycastTarget = false;
}
UpdateUI();
}
private void Update() {
// When "Shop" button is pressed turn on/off Shop UI
if(Input.GetButtonDown("Shop")) {
ToggleShop();
}
}
/**
* Turn on/off the Shop UI
*/
private void ToggleShop() {
shopUI.SetActive(!shopUI.activeSelf);
}
/**
* Is called when something in the Shop UI should update
*/
private void UpdateUI() {
// Add all items to the correct slots and clear the ones where no item should be
for(int i = 0; i < _slots.Length; i++) {
if(i < _shop.items.Count) {
_slots[i].AddItem(_shop.items.ElementAt(i).Key);
_slots[i].nameText.text = _slots[i].item.displayName;
_slots[i].costText.text = _slots[i].item.cost + " €";
_slots[i].amountText.text = _shop.items[_shop.items.ElementAt(i).Key] + " #";
} else {
_slots[i].ClearSlot();
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 61c489f20d0ead245902b7e9d7984c7f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -4,18 +4,10 @@ using UnityEngine;
[CreateAssetMenu(fileName = "New UsableItem", menuName = "Inventory/UsableItem")]
public class UsableItem : Item, IUsable {
// Start is called before the first frame update
void Start() {
}
// Update is called once per frame
void Update() {
}
public UsableItem(string displayName, string description, int id) : base(displayName, description, id) {
}
public void select() {
public void Select() {
PlayerController.instance.SetSelectedItem(this);
}
}