最近需要做装备合成树,类似于王者荣耀的那种直来直去的合成线。大概类似于下图:
然后王者荣耀这个合成树的画法是只显示相邻的合成关系,而不相邻的列之间的合成关系不显示。比如在第三列的装备A由第二列的装备B、C和第一列的装备D合成,那么只绘制A与B、C的关系,D与A之间则没有连接线。先暂且不讨论这是不是最优的解决方案,我们可以作为参考来制作自己的装备合成树。
下面开始弄装备合成树。
1、一条能自适应的折线
首先需要一条自适应的折线,他能根据起点和终点的位置自动适应。 我们分析这条线由3部分组成:左边横线、中间竖线、右边横线。我的预计效果如下:
具体步骤为:先制作一个预制,其包含三根线。
分别设置好其锚点和中心点(Pivot):
TreeLine 锚点:左上,中心点:(0,1);
LineLeft 锚点:左上,中心点:(0,1);
LineMiddle 锚点:左中,中心点:(0.5,0.5);
LineRight 锚点:右下,中心点:(1,0);
之后给TreeLine添加一个脚本:
using UnityEngine;
using UnityEngine.UI;
///
/// 左侧线
///
public Image LineLeft;
///
/// 中间线
///
public Image LineMiddle;
///
/// 右侧线
///
public Image LineRight;
///
/// 左侧线的占比;
///
[Range(0, 1)]
public float LeftRatio = 0.5f;
///
/// 设置线;
///
public void SetLines()
{
float x = (transform as RectTransform).sizeDelta.x;
float y = (transform as RectTransform).sizeDelta.y;
//先编辑左右两端的长度;
LineLeft.rectTransform.sizeDelta = new Vector2(Mathf.Abs(x * LeftRatio), 5);
LineRight.rectTransform.sizeDelta = new Vector2(Mathf.Abs(x * (1 - LeftRatio)), 5);
//中间线长度;
LineMiddle.rectTransform.anchoredPosition = new Vector2(x * LeftRatio, 0);
LineMiddle.rectTransform.sizeDelta = new Vector2(5, Mathf.Abs(y));
//设定反转;
LineLeft.transform.localScale = new Vector3(x > 0 ? 1 : -1, y > 0 ? 1 : -1, 1);
LineRight.transform.localScale = new Vector3(x > 0 ? 1 : -1, y > 0 ? 1 : -1, 1);
LineMiddle.transform.localScale = new Vector3(x > 0 ? 1 : -1, y > 0 ? 1 : -1, 1);
}
}
之后在编辑器下吧三条线拖进去就OK了。如果需要测试,可以在Update里面调用SetLines()方法,然后在编辑器里面更改TreeLine的宽高就能看到效果了。
我们以这个折线作为基础,来进行装备合成树的绘制。
2、装备合成树的绘制
和王者荣耀一样,相邻列显示合成树进行连接,不相邻的不显示。
具体装备合成树的代码就不再贴上来了,大家的解决方案都不太一样,没有太好的复用性。
由于我们已经有了TreeLine这个类,只要给他设定起始位置和宽高就能正确显示了。具体的显示效果如下:
(画面上各种红色的叉是因为TreeLine的宽高设定为负数的原因,起始在显示上没有影响,因为Unity支持图片的双面显示。当然你也可以在代码中手动翻转这些图片。)
起始还有一个间隔列的合成树的绘制。但是由于目前没有这个需求所以就没有做。
后面如果有需要了会补充关于间隔列之间的装备 合成树的绘制思路。