Unity2019 UIElement 笔记(九)简单练习一
那么到目前为止,已经学会了如何使用UXML和USS,那么接下来就是实际运用了。
那么在这里我会演示一个最简单的运用,如果有不足之处请大家指出。
目标
我们的目标是做出类似冒险岛1中角色属性的编辑界面,如下图:
图片是直接从百度图片上找的,那我们就要开始简单的仿制这个UI布局来练习目前学到的内容。
一、创建C#脚本
首先我们创建一个C#脚本,命名为ActorState,并在里面写好我们所需要的属性
using UnityEngine;
[ExecuteInEditMode]
public class ActorState : MonoBehaviour
{
public string m_name;
public string m_career;
public int m_level;
public int m_pk;
public string m_family;
public int m_maxHP;
public int m_maxMP;
public int m_maxEXP;
public int m_popu;
public int m_apoint;
public int m_str;
public int m_agi;
public int m_int;
public int m_luc;
}
然后创建另外一个C#脚本,命名为ActorStateEditor,如下所示:
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
[CustomEditor(typeof(ActorState))]
public class ActorStateEditor : Editor
{
public override VisualElement CreateInspectorGUI()
{
var visualTree = Resources.Load("actorstate_inspector_uxml") as VisualTreeAsset;
var uxmlVE = visualTree.CloneTree();
uxmlVE.styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/Resources/actorstate_inspector_styles.uss"));
return uxmlVE;
}
}
同时创建actorstate_inspector_uxml和actorstate_inspector_styles.uss并放入Resources文件夹中。
那么前期的准备工作就做好了。
二、设置PropertyField
首先在UXML中关联PropertyField
<editor:PropertyField binding-path="m_name" label="名称"/>
然后在USS中设置PropertyField的样式
PropertyField
{
border-style: solid;
border-width: 1px 1px 1px 1px;
border-color: #000;
border-radius: 6px;
padding: 2px 0px 0px 0px;
width:220px;
background-color: #ACD70C;
}
PropertyField TextField
{
width:210px;
align-self:flex-start;
}
PropertyField Label
{
margin: 0px 0px 0px 20px;
align-self:center;
align-self:flex-start;
min-width:50px;
width:50px;
font-size: 12;
}
这里unity的背景色貌似还不支持渐变,我就直接用单一颜色了
那么最后的结果如下
效果。。。还行吧
那么让我们把其他的属性也全部放入
首先添加上IntegerField
PropertyField IntegerField
{
width:210px;
align-self:flex-start;
}
然后写入其他所有的属性
<editor:PropertyField binding-path="m_name" label="名字" />
<editor:PropertyField binding-path="m_career" label="职业" />
<editor:PropertyField binding-path="m_level" label="等级" />
<editor:PropertyField binding-path="m_pk" label="PK" />
<editor:PropertyField binding-path="m_family" label="家族" />
<editor:PropertyField binding-path="m_maxHP" label="HP" />
<editor:PropertyField binding-path="m_maxMP" label="MP" />
<editor:PropertyField binding-path="m_maxEXP" label="经验值" />
<editor:PropertyField binding-path="m_popu" label="人气度" />
<editor:PropertyField binding-path="m_str" label="力量" />
<editor:PropertyField binding-path="m_agi" label="敏捷" />
<editor:PropertyField binding-path="m_int" label="智力" />
<editor:PropertyField binding-path="m_luc" label="运气" />
能力值属性我们待会儿单独写,现在我们已经有大部分的框了,如图
三、设置container
那么我们现在需要一个大框将他们框起来,那我们就需要一个container
.container
{
justify-content:flex-start;
}
.container__column
{
flex-direction:column;
}
.container__row
{
flex-wrap:wrap;
flex-direction:row;
}
这里使用column的话,那么所有的元素都会垂直排列(这也是默认排列)。
而使用row的话,所有元素就会水平排列,如果不使用flex-wrap:wrap;那么就会变得很挤:
如果使用了flex-wrap:wrap;那么就会根据大小自动换行:
当然我们这边使用的是column,接下来我们需要给它一个框
/*....*/
.container__column
{
border-style: solid;
border-width: 1px 1px 1px 1px;
border-color: #000;
flex-direction:column;
}
.container__column--main
{
align-self:center;
}
/*....*/
PropertyField
{
align-self:center;
/*...*/
}
这边我还添加了一个边框,因为默认子元素是左对齐的,所以我们还要让PropertyField元素居中,为它加上align-self:center;
而container__column–main中的align-self:center;是为了让整个框在界面中居中。
<VisualElement name="main" class="container__column container__column--main">
<!--......-->
</VisualElement>
可以看到我们的框颇具雏形了
接下来让这个框往外延伸一点,并再做一个倒角,设置一下背景颜色
.container__column--main
{
padding:4px;
border-radius: 6px;
background-color: #F1F1F1;
align-self:center;
}
嗯哼,还可以,那么按照这个样子作出最外面的大框,并为其加上标题
.container__column--out
{
padding:4px;
border-radius: 6px;
background-color: #444444;
border-color: #FFF;
align-self:center;
}
.midTitle
{
align-self:center;
font-size:16;
color:#EEB422;
}
<VisualElement name="main" class="container__column container__column--out">
<Label name="title" text="角色属性" class="midTitle"/>
<VisualElement name="main" class="container__column container__column--main">
<!--......-->
</VisualElement>
</VisualElement>
最后我们的成果就像这样
四、制作能力点面板
其实这个能力点的面板有点麻烦,但是,我们可以理解成这样:能力点将整个UI分为了三部分,我们现在只要分开上下两部分,并为中间添加上一部分就可以了。
那么这里我自己做了一下,这里放上完整代码:
CSS部分
/*----------------------container----------------------*/
.container
{
justify-content:flex-start;
}
.container__column
{
border-style: solid;
border-width: 1px 1px 1px 1px;
border-color: #000;
flex-direction:column;
}
.container__column--main
{
padding:4px;
background-color: #F1F1F1;
align-self:center;
}
.container__column--main__down
{
border-radius: 0px 0px 6px 6px;
}
.container__column--main__up
{
border-radius: 6px 6px 0px 0px;
}
.container__column--mid
{
width:230px;
height:50px;
background-color: #3AADEE;
border-width: 0px 1px;
border-color: #000;
}
.container__column--out
{
padding:4px;
border-radius: 6px;
background-color: #444444;
border-color: #FFF;
align-self:center;
}
.container__row
{
flex-wrap:wrap;
flex-direction:row;
}
/*----------------------midTitle----------------------*/
.midTitle
{
align-self:center;
font-size:16;
color:#EEB422;
}
.midTitle__white
{
align-self:flex-start;
padding:5px 0px 0px 20px;
font-style: bold;
color:#FFFFFF;
}
/*----------------------PropertyField----------------------*/
PropertyField
{
align-self:center;
border-style: solid;
border-width: 1px 1px 1px 1px;
border-color: #000;
border-radius: 6px;
padding: 2px 0px 0px 0px;
width:220px;
background-color: #C2EE35;
}
PropertyField IntegerField
{
width:210px;
align-self:flex-start;
}
PropertyField TextField
{
width:210px;
align-self:flex-start;
}
PropertyField Label
{
margin: 0px 0px 0px 20px;
align-self:center;
align-self:flex-start;
min-width:50px;
width:50px;
font-size: 12;
}
/*----------------------TextField----------------------*/
.tField
{
align-self:center;
width:60px;
margin:0px 0px 0px 80px;
}
/*----------------------Button----------------------*/
.btn
{
width:75px;
margin:8px 0px 0px 5px;
background-image:none;
background-color:#B3DA1F;
border-radius:4px;
border-style: solid;
border-width: 1px 1px 1px 1px;
border-color: #CCCCCC;
font-size:13;
}
.btn:active:after
{
background-color:#E8EF8F;
}
XML部分
<VisualElement name="main" class="container__column container__column--out">
<Label name="title" text="角色属性" class="midTitle"/>
<VisualElement name="main1" class="container__column container__column--main container__column--main__up">
<editor:PropertyField binding-path="m_name" label="名字" />
<editor:PropertyField binding-path="m_career" label="职业" />
<editor:PropertyField binding-path="m_level" label="等级" />
<editor:PropertyField binding-path="m_pk" label="PK" />
<editor:PropertyField binding-path="m_family" label="家族" />
<editor:PropertyField binding-path="m_maxHP" label="HP" />
<editor:PropertyField binding-path="m_maxMP" label="MP" />
<editor:PropertyField binding-path="m_maxEXP" label="经验值" />
<editor:PropertyField binding-path="m_popu" label="人气度" />
</VisualElement>
<VisualElement name="mid" class="container__column container__column--mid">
<VisualElement class="container__row">
<VisualElement class="container">
<Label name="atitle" text="能力点" class="midTitle midTitle__white"/>
<TextField name="text" class="tField"/>
</VisualElement>
<Button name="Button" text="分配属性" class="btn"/>
</VisualElement>
</VisualElement>
<VisualElement name="main3" class="container__column container__column--main container__column--main__down">
<editor:PropertyField binding-path="m_str" label="力量" />
<editor:PropertyField binding-path="m_agi" label="敏捷" />
<editor:PropertyField binding-path="m_int" label="智力" />
<editor:PropertyField binding-path="m_luc" label="运气" />
</VisualElement>
</VisualElement>
结果
总结
经过这个简单的练习,对于Unity这个新的UIElement系统我有了简单的了解,相较于之间的系统,我觉得方便了不少,可还是有一些麻烦的地方,但总的来说更棒了,个人而言更加喜欢这个新系统。
就我个人而言,我本身并没有HTML和CSS方面的知识储备,对于我和那些没学过这方面内容的人,稍微有点吃亏,但是HTML和CSS本身就是一个完整的体系,某些在Unity官方文档中没有提到的内容,去百度上找也不是特别麻烦。
做起来的话,由于没什么经验,可能会显得比较冗杂,我个人觉得我的USS部分写的有些复杂,而在UXML部分也可以选择使用模板。
这个案例就到这里结束了吧,下一次会做一个有关模板的案例,并且还有最重要的事件系统没有介绍,先挖个坑吧,就这样。