前言
借用梦想世界宠物属性图
想必大家都在游戏中见过属性图用于展示多种属性的数值,可以较为直观的对比某种属性的缺陷或者是哪种属性有优势。在三维可视化领域也会遇到类似的属性对比,用属性图来展示最为合适。
组件效果
- 基础效果
- 效果一
- 效果二
- 效果三
- 效果四
- 效果五
组件特点
- 一键创建,无需额外资源
- 超多属性可自定义
- 可跟具需求拓展
主要内容
- 组件实现(建造者模式)
- 组件多样化(工厂模式)
- 组件使用
详细讲解
组件实现(建造者模式)
建造者模式
- 什么是建造者模式
建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
属性图组件大致分为底图和线图两个层级,底图分为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 );
}
- 实现接口
// 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;
}
}
组件多样化(工厂模式)
通过上一篇 Unity自定义UI组件(十) 折线图中讲解工厂模式,所以在多样化操作中依旧使用工厂模式
工厂模式的使用
public class RadarFactory1 : BaseRadarFactory
{
// 重写父类方法
public override VertexHelper DrawBase(VertexHelper vh)
{
// 重新地图绘制部分,绘制另一种风格的底图
}
}
public class RadarFactory2 : BaseRadarFactory
{
// 重写父类方法
public override VertexHelper DrawLine( VertexHelper vh )
{
// 绘制新的线条样式
}
}
在客户端使用时,我们根据自己需要的类型构造对应的实例。如下:
// 雷达图绘制工厂
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;
}
}
组件使用
数据输入
对于组件的开发和使用,我们需要明白一个观点,组件一定要有自己固定的数据格式,需要外界转化成对应的数据格式才可以使用,否则人人都将根据自己的需要求该组件的中的代码,而且随着组件的复杂度提升,修改的难度也大幅提升,不符合关闭修改,放开拓展的设计模式。因此需要一个代理/中介者来对数据进行处理并输出对应的数据格式。
- 客户端输入
利用泛型运行更多类型的输入,方便数据的接入
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();
}
数据格式化
- 代理处理数据格式
利用代理处理数据并返回固定格式,代理利用反射的方法,获取固定类型中某一个属性值或者是字段的值,根据自己的使用情况来做适当的调整。当然你也拓展其他适应自己项目的方法。
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;
}
// 拓展适应自己项目的适配方法
}
具体使用
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);
Inspector面板配置
Inspector面板没有重写所以开启来比较杂乱,自己配置一下就熟悉啦,再有不懂评论区留言或者是邮箱我。
- Axis 部分是xy坐标,坐标是否显示箭头,箭头尺寸,颜色等。
- base 部分是底板网格,半径,边数,是否显示内部网格,网格颜色,网格尺寸、网格层级等。
- Layer 每个网格层级之间的颜色如果使用带颜色的模式一定要在此处配置,或者可能会出错。
- LineColor 配置每一条线的颜色
更多使用的方法在实例代码中可以看到,实例代码在文章结尾。
后续拓展
- SpringGUI中每个组件都是重新开发的基础方法用来绘制,我逐渐意识到我们可以将常用的方法封装起来作为以后的基类,加快绘制GUI的速度。
- SpringGUI中的组件基本都不具有与输入设备交互的属性,我将会注重交互这个部分为后续的组件添加与输入设备交互的功能。
UGUI组件系列
Unity框架解读系列
分享地址(置顶目录包含所有组件的最新下载地址)
- Github :https://github.com/ll4080333/UnityCodes
- CSDN : http://blog.csdn.net/qq_29579137
- 博客专栏 : http://blog.csdn.net/column/details/16329.html
- QQ群 : 593906968 有什么不懂的可以加群咨询互相学习
如果你想了解UGUI的更多拓展组件,欢迎关注我的博客,我会持续更新,支持一下我这个博客新手。如果以上文章对你有帮助,点个赞,让更多的人看到这篇文章,我们一起学习。如果有什么指点的地方欢迎在评论区留言,秒回复。