Unity自定义UI组件(十一) 雷达图、属性图

来源:互联网 发布:妇科医生在线网络咨询 编辑:程序博客网 时间:2024/06/05 09:43

前言

借用梦想世界宠物属性图

image

想必大家都在游戏中见过属性图用于展示多种属性的数值,可以较为直观的对比某种属性的缺陷或者是哪种属性有优势。在三维可视化领域也会遇到类似的属性对比,用属性图来展示最为合适。

组件效果

  • 基础效果

这里写图片描述

  • 效果一

这里写图片描述

  • 效果二

这里写图片描述

  • 效果三

这里写图片描述

  • 效果四

这里写图片描述

  • 效果五

这里写图片描述

组件特点

  • 一键创建,无需额外资源
  • 超多属性可自定义
  • 可跟具需求拓展

主要内容

  • 组件实现(建造者模式)
  • 组件多样化(工厂模式)
  • 组件使用

详细讲解

组件实现(建造者模式)

建造者模式
  • 什么是建造者模式

建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

属性图组件大致分为底图和线图两个层级,底图分为xy坐标轴和线框,线图可以分为线框和填充物,依据建造者模式的思想,我们可以分为四个部分去建造属性图,然后再统一组合展示。

建造者模式使用

我们利用接口将建造过程抽象,在实现了该接口的类的DrawRadar方法中将分布建造的内容组合起来。

  • 抽象接口
// 绘制基础public interface IRadarBase {    /// 绘制底图线框    VertexHelper DrawBase( VertexHelper vh );    /// 绘制xy坐标    VertexHelper DrawAxis( VertexHelper vh );}// 绘制数据线段public interface IRadarline {    VertexHelper DrawLine( VertexHelper vh );}// 装配操作,将上述分布建造的内容合并public interface IRadarFactory : IRadarBase , IRadarline{    VertexHelper DrawRadar( VertexHelper vh , Rect rect ,RadarBaseData radardata );  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 实现接口
// SpringGUIBase中提供一些公用的绘制方法,可继承或使用实例调用public class BaseRadarFactory : SpringGUIBase, IRadarFactory{    public virtual VertexHelper DrawRadar( VertexHelper vh , Rect rect ,RadarBaseData radardata)    {        this.radarData = radardata;        this.radarDatas = this.radarData.Getdata();        this.size = rect.size;        this.origin = new Vector2(-size.x / 2.0f , -size.y / 2.0f);        // 依次调用不同的建造者,进行建造        DrawBase(vh);        DrawAxis(vh);        DrawLine(vh);        return vh;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

组件多样化(工厂模式)

通过上一篇 Unity自定义UI组件(十) 折线图中讲解工厂模式,所以在多样化操作中依旧使用工厂模式

工厂模式的使用
public class RadarFactory1 : BaseRadarFactory{    // 重写父类方法    public override VertexHelper DrawBase(VertexHelper vh)    {        // 重新地图绘制部分,绘制另一种风格的底图    }}public class RadarFactory2 : BaseRadarFactory{    // 重写父类方法    public override VertexHelper DrawLine( VertexHelper vh )    {        // 绘制新的线条样式    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在客户端使用时,我们根据自己需要的类型构造对应的实例。如下:

// 雷达图绘制工厂private IRadarFactory m_radarFactory{    get    {        // 获取对应实例,也可以利用反射的方法将其分装,进一步降低耦合使得新的模式的将入更加便捷,可以自己动手实现一下        switch ( radarType )        {            case RadarType.Base:                return new BaseRadarFactory();            case RadarType.Type1:                return new RadarFactory1();            case RadarType.Type2:                return new RadarFactory2();            case RadarType.Type3:                return new RadarFactory3();            case RadarType.Type4:                return new RadarFactory4();            case RadarType.Type5:                return new RadarFactory5();        }        return null;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

组件使用

数据输入

对于组件的开发和使用,我们需要明白一个观点,组件一定要有自己固定的数据格式,需要外界转化成对应的数据格式才可以使用,否则人人都将根据自己的需要求该组件的中的代码,而且随着组件的复杂度提升,修改的难度也大幅提升,不符合关闭修改,放开拓展的设计模式。因此需要一个代理/中介者来对数据进行处理并输出对应的数据格式。

  • 客户端输入

利用泛型运行更多类型的输入,方便数据的接入

public void Inject<T>( IList<T> datas ){     var radardata = RadarDataProxy.Convert2RD(datas);    RadarBaseData.Adddata(radardata);       OnEnable();}public void Inject<T>( IList<T>[] datas ){    var radardatas = RadarDataProxy.Convert2RD(datas);    RadarBaseData.Adddata(radardatas);    OnEnable();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
数据格式化
  • 代理处理数据格式

利用代理处理数据并返回固定格式,代理利用反射的方法,获取固定类型中某一个属性值或者是字段的值,根据自己的使用情况来做适当的调整。当然你也拓展其他适应自己项目的方法。

public class RadarDataProxy{    public static RadarData Convert2RD<T>(IList<T> datas)    {        RadarData data = new RadarData();        Type type = typeof(T);        PropertyInfo[] infos = type.GetProperties();        foreach(var v in datas)        {            foreach (var info in infos)            {                if (info.Name.Equals("value"))                    data.AddData((float)info.GetValue(v,null));            }         }        return data;    }    public static IList<RadarData> Convert2RD<T>( IList<T>[] datas )    {        IList<RadarData> result = new List<RadarData>();        foreach (var data in datas)            result.Add(Convert2RD(data));        return result;    }    // 拓展适应自己项目的适配方法}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
具体使用
public class RMExampleData{    public float value{get;set;}    public RMExampleData(float value)    {        this.value = value;    }}IList<RMExampleData> radarthree = new List<RMExampleData>()     {         new RMExampleData(0.0f),         new RMExampleData(0.1f),         new RMExampleData(0.2f),         new RMExampleData(0.3f),         new RMExampleData(0.4f),         new RMExampleData(0.5f),         new RMExampleData(0.6f),         new RMExampleData(0.7f),         new RMExampleData(0.8f),         new RMExampleData(0.9f),         new RMExampleData(1f),     };RadarMap6.Inject(radarthree);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
Inspector面板配置

Inspector面板没有重写所以开启来比较杂乱,自己配置一下就熟悉啦,再有不懂评论区留言或者是邮箱我。

  • Axis 部分是xy坐标,坐标是否显示箭头,箭头尺寸,颜色等。
  • base 部分是底板网格,半径,边数,是否显示内部网格,网格颜色,网格尺寸、网格层级等。
  • Layer 每个网格层级之间的颜色如果使用带颜色的模式一定要在此处配置,或者可能会出错。
  • LineColor 配置每一条线的颜色

这里写图片描述

更多使用的方法在实例代码中可以看到,实例代码在文章结尾。

后续拓展

  • SpringGUI中每个组件都是重新开发的基础方法用来绘制,我逐渐意识到我们可以将常用的方法封装起来作为以后的基类,加快绘制GUI的速度。
  • SpringGUI中的组件基本都不具有与输入设备交互的属性,我将会注重交互这个部分为后续的组件添加与输入设备交互的功能。