diff --git a/Assets/Logic Blocks.meta b/Assets/Logic Blocks.meta new file mode 100644 index 0000000..100b4c3 --- /dev/null +++ b/Assets/Logic Blocks.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4a735889677105942be7b151afec44b8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Logic Blocks/ForLoop.asset.meta b/Assets/Logic Blocks/ForLoop.asset.meta new file mode 100644 index 0000000..a9ea4fe --- /dev/null +++ b/Assets/Logic Blocks/ForLoop.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 02fe4498942f4dc4793eac71fb71f798 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Logic Blocks/Jump.asset.meta b/Assets/Logic Blocks/Jump.asset.meta new file mode 100644 index 0000000..340b327 --- /dev/null +++ b/Assets/Logic Blocks/Jump.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dcf80d6bc49692f4d849f5afb0d05911 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Logic Blocks/Move x2.asset.meta b/Assets/Logic Blocks/Move x2.asset.meta new file mode 100644 index 0000000..8201c96 --- /dev/null +++ b/Assets/Logic Blocks/Move x2.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4fb70ab7e566937488ae0147ee196462 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Logic Blocks/Move.asset.meta b/Assets/Logic Blocks/Move.asset.meta new file mode 100644 index 0000000..6693339 --- /dev/null +++ b/Assets/Logic Blocks/Move.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 25644a0d74897374aa41f8ef383c2ae0 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Logic Blocks/Rotate Left.asset.meta b/Assets/Logic Blocks/Rotate Left.asset.meta new file mode 100644 index 0000000..4e69469 --- /dev/null +++ b/Assets/Logic Blocks/Rotate Left.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4f23e55aecdb22443a7451e7a72c879d +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Logic Blocks/Rotate Right.asset.meta b/Assets/Logic Blocks/Rotate Right.asset.meta new file mode 100644 index 0000000..c8fb220 --- /dev/null +++ b/Assets/Logic Blocks/Rotate Right.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 51fdbaf21c006cb4d8ff078522b03fec +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/UI/Bag Item.prefab b/Assets/Prefabs/UI/Bag Item.prefab index b352039..d01ed8d 100644 --- a/Assets/Prefabs/UI/Bag Item.prefab +++ b/Assets/Prefabs/UI/Bag Item.prefab @@ -12,6 +12,7 @@ GameObject: - component: {fileID: 2209317013564011201} - component: {fileID: 5558332984822978772} - component: {fileID: 3015737051474137246} + - component: {fileID: 1021368708357542995} m_Layer: 5 m_Name: Bag Item m_TagString: Untagged @@ -31,7 +32,7 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 3844581474082900270} - - {fileID: 1307774795787687732} + - {fileID: 790293795267805298} m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -97,6 +98,21 @@ MonoBehaviour: m_FlexibleWidth: -1 m_FlexibleHeight: -1 m_LayoutPriority: 1 +--- !u!114 &1021368708357542995 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1656557556306861286} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d900b6d035606e046acdf763c041a7c9, type: 3} + m_Name: + m_EditorClassIdentifier: + LogicElementPrefab: {fileID: 6973439230367005604, guid: f1daf3f500b22a048bbbad4287c2fcb2, + type: 3} + LogicElementLocation: {fileID: 5884576982143469529} --- !u!1 &2143119419191061466 GameObject: m_ObjectHideFlags: 0 @@ -210,7 +226,7 @@ MonoBehaviour: m_enableWordWrapping: 1 m_wordWrappingRatios: 0.4 m_overflowMode: 0 - m_firstOverflowCharacterIndex: 1 + m_firstOverflowCharacterIndex: -1 m_linkedTextComponent: {fileID: 0} m_isLinkedTextComponent: 0 m_isTextTruncated: 0 @@ -238,7 +254,7 @@ MonoBehaviour: spaceCount: 1 wordCount: 1 linkCount: 0 - lineCount: 2 + lineCount: 1 pageCount: 1 materialCount: 1 m_havePropertiesChanged: 0 @@ -259,138 +275,38 @@ MonoBehaviour: - {fileID: 0} m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} ---- !u!1001 &1605020697400088548 -PrefabInstance: +--- !u!1 &6191069013480418572 +GameObject: m_ObjectHideFlags: 0 - serializedVersion: 2 - m_Modification: - m_TransformParent: {fileID: 5884576982143469529} - m_Modifications: - - target: {fileID: 995834699587958428, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_Name - value: Logic Element - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_LocalPosition.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_LocalPosition.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_LocalPosition.z - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_LocalRotation.x - value: -0 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_LocalRotation.y - value: -0 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_LocalRotation.z - value: -0 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_LocalRotation.w - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_RootOrder - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_LocalEulerAnglesHint.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_LocalEulerAnglesHint.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_LocalEulerAnglesHint.z - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_AnchoredPosition.x - value: 57.750065 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_AnchoredPosition.y - value: -57.349976 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_SizeDelta.x - value: 100 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_SizeDelta.y - value: 100 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_AnchorMin.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_AnchorMin.y - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_AnchorMax.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_AnchorMax.y - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_Pivot.x - value: 0.5 - objectReference: {fileID: 0} - - target: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_Pivot.y - value: 0.5 - objectReference: {fileID: 0} - - target: {fileID: 4794918698464335520, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_havePropertiesChanged - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 4794918698464335520, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - propertyPath: m_isInputParsingRequired - value: 0 - objectReference: {fileID: 0} - m_RemovedComponents: [] - m_SourcePrefab: {fileID: 100100000, guid: f1daf3f500b22a048bbbad4287c2fcb2, type: 3} ---- !u!224 &1307774795787687732 stripped + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 790293795267805298} + m_Layer: 5 + m_Name: Logic Element Location + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &790293795267805298 RectTransform: - m_CorrespondingSourceObject: {fileID: 315265088473579728, guid: f1daf3f500b22a048bbbad4287c2fcb2, - type: 3} - m_PrefabInstance: {fileID: 1605020697400088548} + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6191069013480418572} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 5884576982143469529} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 57.750065, y: -57.349976} + m_SizeDelta: {x: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} diff --git a/Assets/Prefabs/UI/Logic Element.prefab b/Assets/Prefabs/UI/Logic Element.prefab index aa2910d..5c0c244 100644 --- a/Assets/Prefabs/UI/Logic Element.prefab +++ b/Assets/Prefabs/UI/Logic Element.prefab @@ -11,7 +11,7 @@ GameObject: - component: {fileID: 315265088473579728} - component: {fileID: 8830634564332075202} - component: {fileID: 8680666039847169627} - - component: {fileID: 6832775970119436039} + - component: {fileID: 6973439230367005604} m_Layer: 5 m_Name: Logic Element m_TagString: Untagged @@ -76,7 +76,7 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 ---- !u!114 &6832775970119436039 +--- !u!114 &6973439230367005604 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -85,10 +85,10 @@ MonoBehaviour: m_GameObject: {fileID: 995834699587958428} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 8cbb276ef58343c4aab23f9d89081e25, type: 3} + m_Script: {fileID: 11500000, guid: d27160932f067354eb7ffaca0061531c, type: 3} m_Name: m_EditorClassIdentifier: - dragOnSurfaces: 1 + LogicElement: {fileID: 0} --- !u!1 &8739916369872115426 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/Inventory.cs b/Assets/Scripts/Inventory.cs index c9d9f1d..6b73c87 100644 --- a/Assets/Scripts/Inventory.cs +++ b/Assets/Scripts/Inventory.cs @@ -6,22 +6,25 @@ using UnityEngine; [CreateAssetMenu(menuName = "Major Project/Inventory", order = 150)] public class Inventory : ScriptableObject { + + public List BagItems { get { if (_bagItems == null) _bagItems = new List(); return _bagItems; } } + [SerializeField] - protected List AllElements = new List(); + protected List _bagItems = new List(); public void Add(LogicBlock element) { - InventoryData data; + Data data; try { - data = AllElements.First(p => p.element == element); + data = _bagItems.First(p => p.element == element); } catch { - data = new InventoryData() { element = element }; - AllElements.Add(data); + data = new Data() { element = element }; + _bagItems.Add(data); } data.Count++; @@ -29,10 +32,10 @@ public class Inventory : ScriptableObject public void Remove(LogicBlock element) { - if (!AllElements.Exists(p => p.element == element)) + if (!_bagItems.Exists(p => p.element == element)) return; - InventoryData data = AllElements.First(p => p.element == element); + Data data = _bagItems.First(p => p.element == element); if (!data.infinit) data.Count--; @@ -41,7 +44,7 @@ public class Inventory : ScriptableObject [System.Serializable] - public class InventoryData + public class Data { public LogicBlock element; public int Count; diff --git a/Assets/Scripts/Logic/Blocks/LogicBlock.cs b/Assets/Scripts/Logic/Blocks/LogicBlock.cs index 1fb3ee7..765339a 100644 --- a/Assets/Scripts/Logic/Blocks/LogicBlock.cs +++ b/Assets/Scripts/Logic/Blocks/LogicBlock.cs @@ -10,6 +10,15 @@ public abstract class LogicBlock : ScriptableObject { #region Inspector Fields + [SerializeField] + [Header("UI Settings")] + [Tooltip("Color which will identify this element")] + public Color Color; + + [SerializeField] + [Tooltip("Name which will appear in the UI")] + public string DisplayName; + [SerializeField] [Header("Base Settings")] [Tooltip("Wait until this block is resolved before moving to next")] diff --git a/Assets/Scripts/UI/BagItem.cs b/Assets/Scripts/UI/BagItem.cs index 256f264..2b1b505 100644 --- a/Assets/Scripts/UI/BagItem.cs +++ b/Assets/Scripts/UI/BagItem.cs @@ -2,97 +2,82 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; +using TMPro; -public class BagItem : Dragable +public class BagItem : LogicElementHolder { + #region Inspector Elements + [SerializeField] + private LogicElementUI LogicElementPrefab; [SerializeField] - protected LogicBlock logicElement; + private Transform LogicElementLocation; + #endregion Inspector Elements - protected LogicTrayUI tray; - protected RectTransform trayRect; + #region Private Variables + private int Count; + protected Inventory.Data InventoryData; + private TextMeshProUGUI CountText; + #endregion Private Variables - private bool isHovered; + #region Class Functionality - public override void OnBeginDrag(PointerEventData eventData) + public void Initialise(Inventory.Data data) { - base.OnBeginDrag(eventData); - tray = FindObjectOfType(); - if (tray != null) - trayRect = (tray.transform as RectTransform); - } - + InventoryData = data; - public override void OnDrag(PointerEventData data) - { - base.OnDrag(data); - DoTrayLogic(data); + if (CountText == null) + CountText = GetComponentInChildren(); + Count = data.Count; - string output = ""; - foreach (GameObject hover in data.hovered) - output += hover.name + " "; - Debug.Log(output); - } + LogicElementUI logicElement = Instantiate(LogicElementPrefab.gameObject, LogicElementLocation).GetComponent(); + logicElement.Initialise(data.element, this); - protected virtual void DoTrayLogic(PointerEventData data) - { - if (trayRect == null) - return; - - var rt = m_DraggingIcon.GetComponent(); - - - if (GetWorldSpaceRect(trayRect).Overlaps(GetWorldSpaceRect(rt))) - { - if (!isHovered) - { - tray.OnHoverStart(this, rt); - isHovered = true; - } - tray.OnHoverUpdate(this, rt); - }else if (isHovered) - { - isHovered = false; - tray.OnHoverEnd(this); - } - + UpdateUI(); } - public override void OnEndDrag(PointerEventData eventData) + public void UpdateUI() { - base.OnEndDrag(eventData); - - if (isHovered) - { - isHovered = false; - tray.InsertLogicElement(logicElement); - tray.OnHoverEnd(this); - } + CountText.text = Count.ToString(); } + #endregion Class Functionality - private void drawRect(RectTransform transform,Color color,bool global = true) + #region LogicElementHolder Implementation + /// + /// When a logicElement needs to be added back to this holder + /// + /// Element which is being Added + public override void OnAdd(LogicElementUI element) { - Rect rect = transform.rect; - if (global) - rect = GetWorldSpaceRect(transform); - - Debug.DrawLine(new Vector3(rect.min.x,rect.max.y,0), new Vector3(rect.max.x, rect.max.y, 0), color); - Debug.DrawLine(new Vector3(rect.max.x, rect.max.y, 0), new Vector3(rect.max.x, rect.min.y, 0), color); - Debug.DrawLine(new Vector3(rect.max.x, rect.min.y, 0), new Vector3(rect.min.x, rect.min.y, 0), color); - Debug.DrawLine(new Vector3(rect.min.x, rect.min.y, 0), new Vector3(rect.min.x, rect.max.y, 0), color); + Destroy(element.gameObject); + + if (!InventoryData.infinit) + Count++; + + UpdateUI(); } - Rect GetWorldSpaceRect(RectTransform rt) + /// + /// When a LogicElement has started being dragged from this holder + /// + /// Element which is being dragged + public override void OnRemove(LogicElementUI element) { - var r = rt.rect; + if (!InventoryData.infinit && Count > 0) + Count--; + else if (!InventoryData.infinit) + Destroy(element.gameObject); + + LogicElementUI logicElement = Instantiate(LogicElementPrefab.gameObject, LogicElementLocation).GetComponent(); + logicElement.Initialise(InventoryData.element, this); + + + UpdateUI(); - Vector2 centre = rt.TransformPoint(r.center); - r.size = rt.TransformVector(r.size); - r.center = centre; - return r; } + #endregion LogicElementHolder Implementation } diff --git a/Assets/Scripts/UI/Dragable.cs b/Assets/Scripts/UI/Dragable.cs index 1e1c642..9c30626 100644 --- a/Assets/Scripts/UI/Dragable.cs +++ b/Assets/Scripts/UI/Dragable.cs @@ -5,7 +5,6 @@ using UnityEngine.UI; [RequireComponent(typeof(Image))] public class Dragable : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler { - protected GameObject m_DraggingIcon; protected RectTransform m_DraggingPlane; public virtual void OnBeginDrag(PointerEventData eventData) @@ -13,35 +12,21 @@ public class Dragable : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDrag var canvas = FindInParents(gameObject); if (canvas == null) return; - - // We have clicked something that can be dragged. - // What we want to do is create an icon for this. - m_DraggingIcon = new GameObject("icon"); - - m_DraggingIcon.transform.SetParent(canvas.transform, false); - m_DraggingIcon.transform.SetAsLastSibling(); - m_DraggingIcon.layer = LayerMask.NameToLayer("Ignore Raycast"); - - var image = m_DraggingIcon.AddComponent(); - - image.sprite = GetComponent().sprite; - image.SetNativeSize(); - - + m_DraggingPlane = canvas.transform as RectTransform; + transform.SetParent(m_DraggingPlane,false); SetDraggedPosition(eventData); } public virtual void OnDrag(PointerEventData data) { - if (m_DraggingIcon != null) SetDraggedPosition(data); } protected virtual void SetDraggedPosition(PointerEventData data) { - var rt = m_DraggingIcon.GetComponent(); + var rt = transform as RectTransform; Vector3 globalMousePos; if (RectTransformUtility.ScreenPointToWorldPointInRectangle(m_DraggingPlane, data.position, data.pressEventCamera, out globalMousePos)) { @@ -52,8 +37,7 @@ public class Dragable : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDrag public virtual void OnEndDrag(PointerEventData eventData) { - Destroy(m_DraggingIcon); - m_DraggingIcon = null; + } static public T FindInParents(GameObject go) where T : Component diff --git a/Assets/Scripts/UI/ILogicElementHolder.cs b/Assets/Scripts/UI/ILogicElementHolder.cs new file mode 100644 index 0000000..e48ebd2 --- /dev/null +++ b/Assets/Scripts/UI/ILogicElementHolder.cs @@ -0,0 +1,84 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + + +/// +/// Class which component which an LogicElementUI can be dragged into should derive from +/// +public abstract class LogicElementHolder : MonoBehaviour +{ + + /// + /// List of all Holders in scene + /// + private static List EnabledHolders = new List(); + + #region Unity Functions + private void OnEnable() + { + EnabledHolders.Add(this); + } + + private void OnDisable() + { + EnabledHolders.Remove(this); + } + #endregion + + #region Class Funtions + /// + /// When a LogicElement has started being dragged from this holder + /// + /// Element which is being dragged + public abstract void OnRemove(LogicElementUI element); + + /// + /// When a logicElement needs to be added back to this holder + /// + /// Element which is being Added + public abstract void OnAdd(LogicElementUI element); + + /// + /// When a logic Element is hovering over this holder + /// + /// Element which is hovering + public virtual void OnHover(LogicElementUI element) { } + + /// + /// First frame a logic Element is hovering over this holder + /// + /// Element which is hovering + public virtual void OnHoverStart(LogicElementUI element) { } + + /// + /// first frame a logic Element is no longer hovering over this holder + /// + /// Element which is hovering + public virtual void OnHoverEnd(LogicElementUI element) { } + #endregion Class Funtions + + #region Static Functions + /// + /// Gets an array of Any element holders a RectTransform is overlapping with + /// + /// recttransform to check overlapping + /// array of Any element holders a rt is overlapping with + public static LogicElementHolder[] OverlappingElements(RectTransform rt) + { + List retVal = new List(); + + Rect rect = rt.GlobalRect(); + Rect holderRect; + foreach (LogicElementHolder holder in EnabledHolders) + { + holderRect = (holder.transform as RectTransform).GlobalRect(); + + if (rect.Overlaps(holderRect)) + retVal.Add(holder); + } + + return retVal.ToArray(); + } + #endregion +} diff --git a/Assets/Scripts/UI/ILogicElementHolder.cs.meta b/Assets/Scripts/UI/ILogicElementHolder.cs.meta new file mode 100644 index 0000000..56a4ffc --- /dev/null +++ b/Assets/Scripts/UI/ILogicElementHolder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0dfdfeba6aecbfa4c90a8b9921e6fa4f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/InventoryUI.cs b/Assets/Scripts/UI/InventoryUI.cs index a184396..ea35e49 100644 --- a/Assets/Scripts/UI/InventoryUI.cs +++ b/Assets/Scripts/UI/InventoryUI.cs @@ -4,15 +4,33 @@ using UnityEngine; public class InventoryUI : MonoBehaviour { - // Start is called before the first frame update - void Start() + + [SerializeField] + private Inventory inventory; + + [SerializeField] + private BagItem ItemPrefab; + + [SerializeField] + private Transform Parent; + + private void Start() { - + UpdateUI(); } - // Update is called once per frame - void Update() + [ContextMenu("Update UI")] + public void UpdateUI() { - + foreach(Transform child in Parent) + Destroy(child.gameObject); + + foreach (Inventory.Data data in inventory.BagItems) + { + BagItem item = Instantiate(ItemPrefab.gameObject, Parent).GetComponent(); + item.Initialise(data); + } } + + } diff --git a/Assets/Scripts/UI/LogicElementUI.cs b/Assets/Scripts/UI/LogicElementUI.cs index 310d132..c411295 100644 --- a/Assets/Scripts/UI/LogicElementUI.cs +++ b/Assets/Scripts/UI/LogicElementUI.cs @@ -1,11 +1,129 @@ using System.Collections; using System.Collections.Generic; +using System.Linq; using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.UI; +using TMPro; -public class LogicElementUI : MonoBehaviour +/// +/// Component which controls how a LogicElement is displayed in the UI; +/// +public class LogicElementUI : Dragable { + #region Inspector Fields + [SerializeField] + [Tooltip("Logic Block this will display")] + protected LogicBlock LogicElement; + #endregion Inspector Fields - LogicBlock LogicElement; + #region ReadOnly Variables + /// + /// RectTransform of LogicElementUI + /// + public RectTransform rectTransform { get { return transform as RectTransform; } } + public LogicBlock logicElement { get { return LogicElement; } } + #endregion ReadOnly Variables + #region Private Variables + //Text Mesh pro to display Name + protected TextMeshProUGUI nameText; + + //background image to color; + protected Image background; + + protected LogicElementHolder currentHolder; + + private List lastHover = new List(); + #endregion Private Variables + + + #region Unity Functions + private void Start() + { + UpdateUI(); + } + #endregion Unity Functions + + #region Class Implementation + /// + /// Updates the UI to match the LogicElemnts name and color + /// + public virtual void UpdateUI() + { + //Make sure we have the UI components + if (nameText == null) + nameText = GetComponentInChildren(); + + if (background == null) + background = GetComponentInChildren(); + + //Set UI + if (LogicElement != null) + { + //If name null use file name + nameText.text = (string.IsNullOrEmpty(LogicElement.DisplayName)) ? LogicElement.name : LogicElement.DisplayName; + background.color = LogicElement.Color; + } + } + + public virtual void Initialise(LogicBlock LogicElement, LogicElementHolder Holder) + { + this.LogicElement = LogicElement; + currentHolder = Holder; + } + #endregion Class Implementation + + + #region Drag Implementation + + public override void OnBeginDrag(PointerEventData eventData) + { + base.OnBeginDrag(eventData); + + if (currentHolder != null) + currentHolder.OnRemove(this); + + } + + public override void OnDrag(PointerEventData data) + { + base.OnDrag(data); + + //Get all overlapping holders + List currentHover = LogicElementHolder.OverlappingElements(transform as RectTransform).ToList(); + + //Call OnHoverStart() for each holder which wasn't in the last update + currentHover.Except(lastHover).ForEach(p => p.OnHoverStart(this)); + + //Call OnHover() for each overlapping holder + currentHover.ForEach(p => p.OnHover(this)); + + //Call OnHoverEnd() for each element not overlapping but was last update + lastHover.Except(currentHover).ForEach(p => p.OnHoverEnd(this)); + + //Save all overlapping elements this update + lastHover = currentHover; + } + + public override void OnEndDrag(PointerEventData eventData) + { + base.OnEndDrag(eventData); + + //Call OnHoverStop to each element we are hovering over + lastHover.ForEach(p => p.OnHoverEnd(this)); + + //If we are still hovering over anything add this to it + //Else add it back to where it came from + if (lastHover.Count > 0) + { + lastHover[0].OnAdd(this); + currentHolder = lastHover[0]; + } + else + currentHolder.OnAdd(this); + + } + #endregion Drag Implementaion } diff --git a/Assets/Scripts/UI/LogicTrayUI.cs b/Assets/Scripts/UI/LogicTrayUI.cs index 6e4dec6..c670505 100644 --- a/Assets/Scripts/UI/LogicTrayUI.cs +++ b/Assets/Scripts/UI/LogicTrayUI.cs @@ -4,98 +4,131 @@ using UnityEngine; using TMPro; using UnityEngine.UI; -public class LogicTrayUI : MonoBehaviour +public class LogicTrayUI : LogicElementHolder { [SerializeField] protected List list; [SerializeField] - protected GameObject Prefab; + protected LogicElementUI Prefab; [SerializeField] protected int insertIndex = -1; [SerializeField] private Transform content; - + #region Unity Functions public void Start() { UpdateDisplay(); } + #endregion Unity Functions - public void OnHoverStart(BagItem item, RectTransform rect) - { - insertIndex = content.childCount; - UpdateDisplay(); - } - public void OnHoverEnd(BagItem item) + [ContextMenu("Update Display")] + public void UpdateDisplay() { - insertIndex = -1; - UpdateDisplay(); - } + //Destroy all children + int destroyedCount = content.childCount; //we need to know how many were destroyed since unity doesn't actually destroy anything until the end of the frame + foreach (Transform child in content) + Destroy(child.gameObject); - public void InsertLogicElement(LogicBlock item) - { - if (insertIndex >= 0 && insertIndex <= list.Count) + //Instatiate logicElement prefab + foreach (LogicBlock element in list) { - list.Insert(insertIndex, item); + LogicElementUI elementUI = Instantiate(Prefab.gameObject, content).GetComponent(); + elementUI.Initialise(element, this); } - UpdateDisplay(); - } - public void OnHoverUpdate(BagItem item, RectTransform rect) - { - - foreach(Transform child in content) + //Add insertIndex object if needed + if (insertIndex != -1) { - RectTransform childRect = child as RectTransform; - if (child == null) - continue; - - if (rect.GlobalRect().Overlaps(childRect.GlobalRect())) - { - if (insertIndex != child.GetSiblingIndex()) - { - insertIndex = child.GetSiblingIndex(); - UpdateDisplay(); - - } - break; - } + GameObject elementObject = Instantiate(Prefab.gameObject, content); + elementObject.GetComponentInChildren().text = "insert"; + elementObject.GetComponentInChildren().color = new Color(0.5f, 0.5f, 0.5f, 0.25f); + //Set sibling index to where we want it in list + add destroyedCount since technically they are still here + elementObject.transform.SetSiblingIndex(destroyedCount + insertIndex); } + } - [ContextMenu("Update Display")] - public void UpdateDisplay() + #region LogicElementHolder Implementation + + /// + /// When a LogicElement has started being dragged from this Tray + /// + /// Element which is being dragged + public override void OnRemove(LogicElementUI element) { - int destroyedCount = content.childCount; - foreach (Transform child in content) - Destroy(child.gameObject); + list.Remove(element.logicElement); + UpdateDisplay(); + } - foreach(LogicBlock element in list) - { - GameObject elementObject = Instantiate(Prefab, content); - elementObject.GetComponentInChildren().text = element.name; - } + /// + /// When a logicElement needs to be added back to this Tray + /// + /// Element to add + public override void OnAdd(LogicElementUI element) + { + int index = GetInsertIndex(element.rectTransform); + list.Insert(index, element.logicElement); - if (insertIndex != -1) - { - GameObject elementObject = Instantiate(Prefab, content); - elementObject.GetComponentInChildren().text = "insert"; - elementObject.GetComponentInChildren().color = new Color(0.5f, 0.5f, 0.5f, 0.25f); + UpdateDisplay(); + Destroy(element.gameObject); + } - elementObject.transform.SetSiblingIndex(destroyedCount + insertIndex); - } + /// + /// When a logic Element is hovering over this holder + /// + /// Element which is hovering + public override void OnHover(LogicElementUI element) + { + insertIndex = GetInsertIndex(element.rectTransform); + UpdateDisplay(); + } - + /// + /// First frame a logic Element is hovering over this holder + /// + /// Element which is hovering + public override void OnHoverStart(LogicElementUI element) + { + //Create insert prefab at End + insertIndex = content.childCount; + UpdateDisplay(); + } + /// + /// first frame a logic Element is no longer hovering over this holder + /// + /// Element which is hovering + public override void OnHoverEnd(LogicElementUI element) + { + //Remove insert prefab + insertIndex = -1; + UpdateDisplay(); } + #endregion LogicElementHolder Implementation + + #region Helper Functions + public int GetInsertIndex(RectTransform rt) + { + Rect rect = rt.GlobalRect(); + foreach (Transform child in content) + { + RectTransform childRect = child as RectTransform; + + if (rect.Overlaps(childRect.GlobalRect())) + return child.GetSiblingIndex(); + } + return list.Count; + } + #endregion Helper Functions } diff --git a/Assets/Scripts/Utility/DebugExtensions.cs b/Assets/Scripts/Utility/DebugExtensions.cs index 6f42952..1a8e15d 100644 --- a/Assets/Scripts/Utility/DebugExtensions.cs +++ b/Assets/Scripts/Utility/DebugExtensions.cs @@ -54,4 +54,22 @@ public static class DebugExtensions DrawCube(Position, Vector3.one * Extent, color, duration); } + + /// + /// Draws wireframe around a RectTransform in scene view + /// + /// Rect transform to draw around + /// Color of the lines + /// How long the lines should be visible for + /// Should the lines be obscured by objects closer to the camera + public static void DrawRect(RectTransform transform, Color color, float duration = 0.0f, bool depthTest = false) + { + Rect rect = transform.GlobalRect(); + + Debug.DrawLine(new Vector3(rect.min.x, rect.max.y, 0), new Vector3(rect.max.x, rect.max.y, 0), color, duration, depthTest); + Debug.DrawLine(new Vector3(rect.max.x, rect.max.y, 0), new Vector3(rect.max.x, rect.min.y, 0), color, duration, depthTest); + Debug.DrawLine(new Vector3(rect.max.x, rect.min.y, 0), new Vector3(rect.min.x, rect.min.y, 0), color, duration, depthTest); + Debug.DrawLine(new Vector3(rect.min.x, rect.min.y, 0), new Vector3(rect.min.x, rect.max.y, 0), color, duration, depthTest); + } + }//End DebugExtentions diff --git a/Assets/Scripts/Utility/ExtensionMethods.cs b/Assets/Scripts/Utility/ExtensionMethods.cs index 1f7780a..645ba46 100644 --- a/Assets/Scripts/Utility/ExtensionMethods.cs +++ b/Assets/Scripts/Utility/ExtensionMethods.cs @@ -53,7 +53,11 @@ public static class ExtensionMethods } } - + /// + /// Gets the rect of a RectTransform in World coordinates + /// + /// RectTransform to get rect from + /// rect of a RectTransform in World coordinates public static Rect GlobalRect(this RectTransform rt) { var r = rt.rect; @@ -63,6 +67,19 @@ public static class ExtensionMethods r.center = centre; return r; } + + + + /// + /// Applies an action to each element in an IEnumerable + /// + /// IEnumerable to loop therough + /// Action to apply to each element + public static void ForEach(this IEnumerable enumeration, System.Action action) + { + foreach (T item in enumeration) + action(item); + } }