UI系统介绍
| Unity2D 和 UI 的区别
Unity2D: 主要基于 Sprite Renender 和2D物理系统
UI: 由Canvas 及 UI组件组成(显示不基于Sprite Renender)
| UI 系统组成
Canvas 画布: UI 的根节点
EventSystem: 事件系统,基于这个才可以让我们按钮可以点击
Image / Text 等各种组件: 具体的功能组件,显示一个图片、制作一个按钮等
Image 组件
主要负责 图片 的展示
| 主要属性
SourceImage:源图片,在脚本中叫 sprite
Color:图片颜色
RaycastTarget:是否可以作为射线目标,后续点击、拖拽等事件需要使用
ImageType:显示模式
Simple:普通模式
Sliced:切片,需要图片九空格,要在组员层面处理
Tilled:平铺
Filled:填充
| 主要功能
- Set Native Size:设置为图片的原始尺寸
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 如果需要用脚本操作 UI 相关的操作,必须引入 UI 的命名空间
using UnityEngine.UI;
public class L5_2Demo : MonoBehaviour
{
private Image image;
void Start()
{
image = GetComponent<Image>();
image.color = Color.black;
}
}
Text 组件
| 组件介绍
显示文本,如等级、属性值、角色名称等
| 常用属性
Text:显示的文本内容
Font:字体
Font Style:字体样式,主要是加粗、斜体
Font Size:字体大小
Line Spacing:行间距
RichText:富文本,Html经验者可尝试
Color:字体颜色
Raycast Target:是否作为射线检测的目标,也就是射线可以检测到,意味着后续是否可以点击等
| 对齐属性
Alignment:文本的对齐方式
Horizontal Oveflow:水平溢出
Wrap:当达到水平边界,文本将自动换行
Overflow:可以超出水平边界,继续显示
Vertical Oveflow:垂直溢出
Truncate:文本不显示超出垂直边界的部分
Overflow:文本可以超出垂直边界,继续显示
Best Fit:尽可能匹配边缘
Min Size:字体的最小大小
Max Size:字体的最大大小
Button 组件
| 构成
Button:Image、Button、Text
| 样式
Interactable:可交互的,就是 按钮是否有效
Transition:过渡方式,按钮一般分为几种状态,比如鼠标悬浮、点击、不可用
Target Graphic:按钮影响的 Image
Normal Color:常规
Highlighted Color:高亮、鼠标悬浮
Pressed Color:按下
Disabled Color:禁用
Fade Duration:颜色过渡时间
| Navigation
通常我们使用 WASD 或 上下左右 等方式选择按钮,Unity 的 UGUI 也具备这个功能并且设置起来十分方便
| 事件
OnClick():直接添加 or 自写函数
演示:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class L5_4Demo : MonoBehaviour
{
private Button button;
private void Start()
{
button = GetComponent<Button>();
button.onClick.AddListener(ButtonClick2);
}
public void ButtonClick2()
{
Debug.Log("ButtonClick2");
}
public void ButtonClick()
{
Debug.Log("ButtonClick");
}
}
InputField 组件
| 结构
InputField: Image组件(背景图片)、InputField组件
Placeholder: Text组件(玩家完全没输入时显示内容)
Text: Text 组件实际输入的承载组件
| 输入类型
InputField 中 ContentType 可以设置玩家输入的类型,比如邮箱、密码等
| 事件
和 Button 类似
注意:如果需要手动获取 InputField 中玩家输入的值,要直接使用 InputField.text,而不要去查找子物体 Text 中的组件
演示:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class L5_5Demo : MonoBehaviour
{
private InputField inputField;
void Start()
{
inputField = GetComponent<InputField>();
//inputField.text = "666";
//Debug.Log(inputField.text);
inputField.onValueChanged.AddListener(OnValueChanged);
inputField.onEndEdit.AddListener(OnEndEdit);
}
public void OnValueChanged(string value)
{
Debug.Log("OnValueChanged: "+value);
}
public void OnEndEdit(string value)
{
Debug.Log("OnEndEdit: "+value);
}
}
Toggle 组件
| 基本使用
Toggle组件:
Background:Image组件(背景图)
Checkmark:Image组件(打勾)
Label:Text组件(文本)
| ToggleGroup
演示:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class L5_6Demo : MonoBehaviour
{
private Toggle toggle;
void Start()
{
toggle = GetComponent<Toggle>();
toggle.onValueChanged.AddListener(OnValueChanged);
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Debug.Log(toggle.isOn);
}
}
public void OnValueChanged(bool bl)
{
Debug.Log("bl: " + bl);
}
}
案例:注册与登录
| 介绍
注册: 玩家输入账号、密码、重复密码、性别等来完成注册,其中需要对密码与重复密码进行一致性校验
登录: 玩家输入账号、密码后和之前输入的账号密码等信息进行匹配;玩家输入有误时进行弹窗提示
| 分析
主面板: 有两个按钮 - 注册 / 登录,点击后切换到对应面板
注册面板:
玩家输入账号、密码、重复密码、性别后点击注册,对密码与重复密码进行匹配
输入正确:弹窗 “注册成功,请登录!”
输入错误 - 账号与密码没输入:弹窗 “请输入账号或密码!”
输入错误 - 密码与重复密码不一致:弹窗 “密码与重复密码不一致!”
返回按钮:返回主面板
| 实现
L5_7MainPanel:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class L5_7MainPanel : MonoBehaviour
{
public static L5_7MainPanel Instance;
private Button signUpButton;
private Button loginButton;
private void Awake()
{
Instance = this;
}
void Start()
{
signUpButton = transform.Find("SignUpButton").GetComponent<Button>();
loginButton = transform.Find("LoginButton").GetComponent<Button>();
signUpButton.onClick.AddListener(SignUpButtonClick);
loginButton.onClick.AddListener(LoginButtonClick);
}
private void SignUpButtonClick()
{
// open sign up
L5_7SignUpPanel.Instance.Show();
gameObject.SetActive(false);
}
private void LoginButtonClick()
{
// open log in
L5_7LoginPanel.Instance.Show();
gameObject.SetActive(false);
}
public void Show()
{
gameObject.SetActive(true);
}
}
L5_7FloatWindow:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class L5_7FloatWindow : MonoBehaviour
{
public static L5_7FloatWindow Instance;
private Text infoText;
private Button okButton;
private void Awake()
{
Instance = this;
infoText = transform.Find("Info").GetComponent<Text>();
okButton = transform.Find("OKButton").GetComponent<Button>();
okButton.onClick.AddListener(OKButtonClick);
OKButtonClick();
}
public void ShowInfo(string info)
{
gameObject.SetActive(true);
infoText.text = info;
}
private void OKButtonClick()
{
gameObject.SetActive(false);
}
}
L5_7SignUpPanel:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class L5_7SignUpPanel : MonoBehaviour
{
public static L5_7SignUpPanel Instance;
private InputField account;
private InputField password;
private InputField rePassword;
private Toggle isMan;
private Button returnButton;
private Button okButten;
private void Awake()
{
Instance = this;
account = transform.Find("Account/InputField").GetComponent<InputField>();
password = transform.Find("Password/InputField").GetComponent<InputField>();
rePassword = transform.Find("RePassword/InputField").GetComponent<InputField>();
isMan = transform.Find("GenderGroup/Male").GetComponent<Toggle>();
returnButton = transform.Find("ReturnButton").GetComponent<Button>();
okButten = transform.Find("OKButten").GetComponent<Button>();
returnButton.onClick.AddListener(ReturnButtonClick);
okButten.onClick.AddListener(OKButtenClick);
gameObject.SetActive(false);
}
private void ReturnButtonClick()
{
// back Main
L5_7MainPanel.Instance.Show();
gameObject.SetActive(false);
}
private void OKButtenClick()
{
// login go
if (string.IsNullOrEmpty(account.text) || string.IsNullOrEmpty(password.text) || string.IsNullOrEmpty(rePassword.text))
{
L5_7FloatWindow.Instance.ShowInfo("Please input account or password!");
}
else if (password.text != rePassword.text)
{
L5_7FloatWindow.Instance.ShowInfo("Password is not match!");
}
else
{
// The account does exist
if (L5_7GameManager.Instance.GetUserInfo(account.text) != null )
{
L5_7FloatWindow.Instance.ShowInfo("Do not repeat sign up!");
}
else
{
L5_7UserInfo userInfo = new L5_7UserInfo(account.text, password.text, isMan.isOn);
// save account
L5_7GameManager.Instance.SaveUserInfo(userInfo);
L5_7FloatWindow.Instance.ShowInfo("Success! Please log in!");
}
}
}
public void Show()
{
gameObject.SetActive(true);
account.text = "";
password.text = "";
rePassword.text = "";
isMan.isOn = true;
}
}
L5_7LoginPanel:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class L5_7LoginPanel : MonoBehaviour
{
public static L5_7LoginPanel Instance;
private InputField account;
private InputField password;
private Button returnButton;
private Button okButten;
private void Awake()
{
Instance = this;
account = transform.Find("Account/InputField").GetComponent<InputField>();
password = transform.Find("Password/InputField").GetComponent<InputField>();
returnButton = transform.Find("ReturnButton").GetComponent<Button>();
okButten = transform.Find("OKButten").GetComponent<Button>();
returnButton.onClick.AddListener(ReturnButtonClick);
okButten.onClick.AddListener(OKButtenClick);
gameObject.SetActive(false);
}
private void ReturnButtonClick()
{
// back Main
L5_7MainPanel.Instance.Show();
gameObject.SetActive(false);
}
private void OKButtenClick()
{
if (string.IsNullOrEmpty(account.text) || string.IsNullOrEmpty(password.text))
{
L5_7FloatWindow.Instance.ShowInfo("Please input account or password!");
}
else
{
L5_7UserInfo userInfo = L5_7GameManager.Instance.GetUserInfo(account.text);
if (userInfo == null)
{
L5_7FloatWindow.Instance.ShowInfo("The account does not exist!");
}
else if(userInfo.password != password.text)
{
L5_7FloatWindow.Instance.ShowInfo("account or password is wrong!");
}
else if(userInfo.password == password.text)
{
L5_7FloatWindow.Instance.ShowInfo("sign up Success!");
}
}
}
public void Show()
{
gameObject.SetActive(true);
account.text = "";
password.text = "";
}
}
L5_7GameManager:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class L5_7UserInfo
{
public string account;
public string password;
public bool isMan;
public L5_7UserInfo(string account, string password, bool isMan)
{
this.account = account;
this.password = password;
this.isMan = isMan;
}
}
public class L5_7GameManager
{
private static L5_7GameManager instance;
// after sign up's account massage
public List<L5_7UserInfo> UserInfos = new List<L5_7UserInfo>();
public static L5_7GameManager Instance
{
get
{
if(instance == null) instance = new L5_7GameManager();
return instance;
}
}
public void SaveUserInfo(L5_7UserInfo userInfo)
{
UserInfos.Add(userInfo);
}
public L5_7UserInfo GetUserInfo(string userNamer)
{
for (int i = 0; i < UserInfos.Count; i++)
{
if(userNamer == UserInfos[i].account)
{
return UserInfos[i];
}
}
return null;
}
}
Slider 组件
| 功能
Slider:Slider组件
Background:Image组件(背景图)
Fill Area:填充区域
- Fill:Image组件(填充物)
Handle Slider Area:触摸区域
- Handle:Image组件(触摸物体实际图片)
演示:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class L5_8Demo : MonoBehaviour
{
private Slider slider;
void Start()
{
slider = GetComponent<Slider>();
slider.onValueChanged.AddListener(SliderOnValueChanged);
}
void SliderOnValueChanged(float value)
{
Debug.Log(value);
}
}
ScrollBar 组件
| 结构
Scrollbar:Scrollbar 组件
Sliding Area:拖拽区域
Handle:Image组件(拖拽物体的实际显示)