using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; using UnityEngine.EventSystems; // TODO: Expand for other measurement systems later namespace SimpleInventorySystem { public enum Orientation { Portrait, Landscape }; [Serializable] public struct Size { public int Width; public int Height; public Size(int width, int height) { this.Width = width; this.Height = height; } public Size(float width, float height) { this.Width = (int)width; this.Height = (int)height; } public int span { get { return Width * Height; } } } public struct KeyInput { public bool pressedKey, holdingKey; public KeyCode keyCode; public KeyInput(KeyCode keyCode) { this.keyCode = keyCode; pressedKey = false; holdingKey = false; } public void Update() { if (Input.GetKeyDown(keyCode) && !pressedKey && !holdingKey) { //Debug.Log("R"); pressedKey = true; } else if (pressedKey && !holdingKey) { holdingKey = true; } else if (Input.GetKeyUp(keyCode)) { //Debug.Log("R - up"); holdingKey = false; pressedKey = false; } } public bool PressedKey(bool singlePress) { return pressedKey && (!singlePress || !holdingKey); } } public enum ItemTags { Any, Helmet, Headset, Glasses, FaceCover, Plate, Weapon, Sidearm, MeleeWeapon, TacticalRig, TacticalRigAttachment, MedPouch, Backpack, Pouch1x1, Pouch1x2, Pouch1x3, Pouch2x2, BodyArmor } public class InventorySystem : MonoBehaviour, IPointerClickHandler { [SerializeField] private string[] RaritySystemUnits; private string[] weightSystemUnitsSymbols; [SerializeField] private string[] weightSystemUnits; [SerializeField] private float[] currencySystemUnits; [SerializeField] private string[] currencySystemUnitsSymbols; public static InventorySystem instance; public Canvas inventoryUI; public Canvas playerUI; private TextMeshProUGUI lootMessage; public GameObject InventoryMenuUI; public GameObject LootMenuUI; public GameObject StatsMenuUI; public KeyCode rotateKey; public KeyCode menuKey; public KeyCode interactKey; protected KeyInput rotationKeyInput; protected KeyInput menuKeyInput; protected KeyInput interactKeyInput; [SerializeField] private int DefaultWidthOnGrid = 100; [SerializeField] private int DefaultHeightOnGrid = 100; public Size DefaultSizeOnGrid; public Camera playerCamera; public GameObject EventsObject; private GameObject toolbarEvents; public StandaloneInputModule StandaloneInputModule; public Vector2 MouseInCanvasPosition; public ItemUI DraggedItem; public ContextMenuManagerUI ContextMenuUI; public static List hoverResults; private void Awake() { if (instance == null) { instance = this; } else { // TODO: Test this, make sure only one inventory system is active throughout the game Destroy(gameObject); } DefaultSizeOnGrid = new Size(DefaultWidthOnGrid, DefaultHeightOnGrid); rotationKeyInput = new KeyInput(rotateKey); menuKeyInput = new KeyInput(menuKey); interactKeyInput = new KeyInput(interactKey); lootMessage = playerUI.transform.Find("Loot Message").GetComponent(); if (lootMessage != null) { string text = lootMessage.text; if (text.Contains("{key:interactKey}")) lootMessage.text = lootMessage.text.Replace("{key:interactKey}", "[ " + interactKey.ToString() + " ]"); } toolbarEvents = EventsObject.transform.Find("Toolbar").gameObject; InventoryMenuUI.SetActive(false); } // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { rotationKeyInput.Update(); menuKeyInput.Update(); interactKeyInput.Update(); DetectObject(); if (menuKeyInput.PressedKey(true)) { if(InventoryMenuUI != null) { ToggleInventory(); } } hoverResults = GetPointerOverUIObject(); } private List GetPointerOverUIObject() { PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current); eventDataCurrentPosition.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y); List results = new List(); EventSystem.current.RaycastAll(eventDataCurrentPosition, results); List rGOs = new List(); for (int i = 0; i < results.Count; i++) { if (results[i].gameObject.layer == LayerMask.GetMask("Ignore Raycast")) { results.RemoveAt(i); i--; } else// if (results[i].gameObject.layer == LayerMask.GetMask("UI")) { rGOs.Add(results[i].gameObject); } } return rGOs; } public static bool IsMouseOverUI(GameObject go) { if(hoverResults == null || hoverResults.Count == 0) { return false; } return hoverResults.Contains(go); } public static bool IsMouseOverItemUITop(ItemUI item) { if (hoverResults == null || hoverResults.Count == 0) { return false; } foreach(GameObject go in hoverResults) { if(go.GetComponent() != null) { if (go.GetComponent() == item) return true; else return false; } } return false; } private void FixedUpdate() { Vector2 movePos; RectTransformUtility.ScreenPointToLocalPointInRectangle(inventoryUI.transform as RectTransform, Input.mousePosition, inventoryUI.worldCamera, out movePos); MouseInCanvasPosition = InventorySystem.instance.inventoryUI.transform.TransformPoint(movePos); } public void ToggleInventory() { if (InventoryMenuUI.activeInHierarchy) { CloseInventory(); } else { OpenInventory(); } } public void OpenInventory() { InventoryMenuUI.SetActive(true); toolbarEvents.GetComponent().MoveToTarget(false, true); } public void CloseInventory() { toolbarEvents.GetComponent().MoveToSource(true, false); InventoryMenuUI.SetActive(false); } public void OpenContextMenu(MonoBehaviour uiContext) { if (uiContext.GetType() == typeof(ItemUI)) { ContextMenuUI.OpenContextMenu((ItemUI)uiContext); } } private void DetectObject() { if (playerCamera == null) { //Debug.Log("Uh OHHH. No camera detected"); } else { //Debug.Log("Detecting..."); } Ray ray = playerCamera.ScreenPointToRay(new Vector2(Screen.width / 2, Screen.height / 2));//controls.Mouse.Position.ReadValue()); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { if (hit.collider != null)// && hit.transform.parent.parent.parent != null) { //Debug.Log("3D Hit: " + hit.collider.transform.name); // TODO: functionality here Inventory response = hit.collider.transform.GetComponent(); if (response != null && !InventorySystem.instance.IsUsingInventoryMenuUI()) { if (interactKeyInput.PressedKey(true)) { OpenInventory(); LootMenuUI.SetActive(true); StatsMenuUI.SetActive(false); lootMessage.gameObject.SetActive(false); } else if (!InventorySystem.instance.IsUsingInventoryMenuUI()) { lootMessage.gameObject.SetActive(true); } } else if(!InventorySystem.instance.IsUsingInventoryMenuUI()) { lootMessage.gameObject.SetActive(false); LootMenuUI.SetActive(false); StatsMenuUI.SetActive(true); } } } /*RaycastHit[] hits = Physics.RaycastAll(ray, 200); for(int i = 0; i < hits.Length; i++) { if (hits[i].collider != null) { Debug.Log("3D Hit All: " + hits[i].collider.tag); } }*/ /*RaycastHit[] hitsNonAlloc = new RaycastHit[1]; int numberOfHits = Physics.RaycastNonAlloc(ray, hitsNonAlloc); for (int i = 0; i < numberOfHits; i++) { if (hitsNonAlloc[i].collider != null) { Debug.Log("3D Hit Non Alloc All: " + hitsNonAlloc[i].collider.tag); } }*/ } /// /// This can be called to check if player is interacting with the Inventory System's UI /// /// public bool IsUsingInventoryMenuUI() { return InventoryMenuUI.activeInHierarchy; } public bool PressedKeyRotation(bool singlePress) { return rotationKeyInput.PressedKey(singlePress); } public void OnPointerClick(PointerEventData eventData) { } } }