• 通用窗口类 Inventory Pro 2.1.2 Demo1(上)


    插件功能

    按照Demo1的实现,使用插件来实现一个装备窗口是很easy的,虽然效果还很原始但是也点到为止了,本篇涉及的功能用加粗标出,具体的功能如下:

    1、实现了两个窗口,通过点击键盘I来,打开或者关闭窗口也就是Toggle功能

    2、装备窗口中的物品栏空格数量动态生成可控,可以在属性窗口手动配置

    3、窗口具有拖拽功能

    4、窗口物品具有拖拽,及窗口间拖拽

    5、可以在窗口使用物品的功能,物品有消耗扇形显示功能

    具体效果图如下所示:

    2

    插件使用

    1、具体在UGUI 中的Canvas中创建一个InventoryWindow

    2、在InventoryWindow下创建空GameObject并命名Container,赋予Grid LayOut 插件

    3、给InventoryWindow添加InventoryUI组件,插件将自动添加WindowUI也就是通用窗口辅助插件

    4、添加拖拽功能组件DraggableWindow,这样窗口就有了拖拽功能了

    至此简单的点击I键可以打开和关闭的装备窗口做好了

    总结

    最后总结下实现通用窗口的三个类,分别是WindowHelper文件夹下的,UIWindow,UIWindowPage和DraggableWindow

    4

    1、DraggableWindow有就是拖拽窗口的组件,这里还是比较赞的,也是插件编程的简单例子,这里学过UGui的同学都知道要实现拖拽功能实现IBeginDragHandler和IDargHandler接口即可,原理很简单, 源码如下

    using UnityEngine;
    using System.Collections;
    using UnityEngine.EventSystems;
    
    namespace Devdog.InventorySystem
    {
        [AddComponentMenu("InventorySystem/UI Helpers/DraggableWindow")]
        public partial class DraggableWindow : MonoBehaviour, IBeginDragHandler, IDragHandler
        {
            public float dragSpeed = 1.0f;
    
            private Vector2 dragOffset;
    
    
            public void OnBeginDrag(PointerEventData eventData)
            {
                if (InventorySettingsManager.instance.isUIWorldSpace)
                    dragOffset = transform.position - eventData.worldPosition;            
                else
                    dragOffset = new Vector2(transform.position.x, transform.position.y) - eventData.position;
            }
    
            void IDragHandler.OnDrag(PointerEventData eventData)
            {
                transform.position = new Vector3(eventData.position.x + dragOffset.x * dragSpeed, eventData.position.y + dragOffset.y * dragSpeed, 0.0f);
            }
        }
    }
    

    2、UIWindow这个类是窗口的公共类,先上类图主要功能点在类图上标注了,这里就不废话了,主要就是控制的窗口的显示关闭,及组合动画效果比较难的是实现了类似组合窗口的功能(这部分有后有机会再仔细分析)

    7

    源码就不全上了,上点有亮点的部分如下:

            public virtual void Hide()
            {
                if (isVisible == false)
                    return;
    
                isVisible = false;
    
                if (OnHide != null)
                    OnHide();
    
                if (hideAudioClip != null)
                    InventoryUIUtility.AudioPlayOneShot(hideAudioClip);
    
                if (hideAnimation != null)
                {
                    animator.enabled = true;
                    animator.Play(hideAnimation.name);
    
                    if (hideCoroutine != null)
                    {
                        StopCoroutine(hideCoroutine);                    
                    }
    
                    hideCoroutine = _Hide(hideAnimation);
                    StartCoroutine(hideCoroutine);
                }
                else
                {
                    animator.enabled = false;
                    SetChildrenActive(false);
                }
            }
    
    
            /// <summary>
            /// Hides object after animation is completed.
            /// </summary>
            /// <param name="animation"></param>
            /// <returns></returns>
            protected virtual IEnumerator _Hide(AnimationClip animation)
            {
                yield return new WaitForSeconds(animation.length + 0.1f);
    
                // Maybe it got visible in the time we played the animation?
                if (isVisible == false)
                {
                    SetChildrenActive(false);
                    animator.enabled = false;
                }
            }
    

      以上部分是通过协程实现的具有延时效果的动画关闭窗口的代码,有代表意义。

    3、UIWindowPage类,该类是UIWindow的子类,在UIWindow有一个Page的集合用于组合显示UIWindowPage,这块Demo1中没有涉及到该功能这里就不仔细分析了,等后面的例子中出现了再研究,亮点代码如下:

            /// <summary>
            /// Container that olds the items, if any.
            /// </summary>
            public RectTransform itemContainer;
            public UIWindow windowParent { get; set; }
    
            public override void Awake()
            {
                base.Awake();
    
                windowParent = transform.parent.GetComponentInParent<UIWindow>();
                if (windowParent == null)
                    Debug.LogWarning("No UIWindow found in parents", gameObject);
    
                // Register our page with the window parent
                windowParent.AddPage(this);
            }
    
            public override void Show()
            {
                if(isEnabled == false)
                {
                    Debug.LogWarning("Trying to show a disabled UIWindowPage");
                    return;
                }
    
                base.Show();
    
                windowParent.NotifyPageShown(this);
            }
    

    这里UIWindow和UIWindowPage 本身是继承关系,然又彼此引用,代码可读性有些差了,作者这里通过Page类中Awake和Show来做父类的初始化和调用,也是一种方法,我觉得还行(请高手拍砖)。

    总体来说目前的UIWinow和UIWindowPage更像是容器Panel或者Group不像是窗口,等以后的Demo中有复杂的再学习吧。

    4、如何通过键盘唤起窗口

    这个比较简单用到了U3D的输入输出模块,关键代码如下:

            /// <summary>
            /// Keys to toggle this window
            /// </summary>
            public KeyCode[] keyCombination;
    
            public virtual void Update()
            {
                if (keyCombination.Length == 0)
                    return;
    
                bool allDown = true;
                foreach (var key in keyCombination)
                {
                    if (Input.GetKeyDown(key) == false)
                    {
                        allDown = false;
                    }
                }
    
                if (allDown)
                    Toggle();
     
            }
    
  • 相关阅读:
    SharePoint 2013 安装.NET Framework 3.5 报错
    SharePoint 2016 配置工作流环境
    SharePoint 2016 站点注册工作流服务报错
    Work Management Service application in SharePoint 2016
    SharePoint 2016 安装 Cumulative Update for Service Bus 1.0 (KB2799752)报错
    SharePoint 2016 工作流报错“没有适用于此应用程序的地址”
    SharePoint 2016 工作流报错“未安装应用程序管理共享服务代理”
    SharePoint JavaScript API in application pages
    SharePoint 2016 每天预热脚本介绍
    SharePoint 无法删除搜索服务应用程序
  • 原文地址:https://www.cnblogs.com/IlidanStormRage/p/5779460.html
Copyright © 2020-2023  润新知