zoukankan      html  css  js  c++  java
  • 通用窗口类 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();
     
            }
    
  • 相关阅读:
    xadmin 安装
    Python
    使用免费证书安装 ipa 到真机
    Jupyter PPT
    Javascript注意点
    论文哪里找?
    神经网络术语
    PyTorch上路
    DCGAN实现
    数据库和数据挖掘领域的会议和期刊
  • 原文地址:https://www.cnblogs.com/IlidanStormRage/p/5779460.html
Copyright © 2011-2022 走看看