相关链接:http://www.cnblogs.com/ybgame/p/3844315.html
效果图:
对于新手引导,主要分两种做法:需要使用shader的和不需要shader的,这里介绍的是后者
1.屏蔽点击
假如ImageA在ImageB前面,且ImageA完全覆盖ImageB,点击两者的重叠部分,ImageA会收到点击事件,而ImageB不会。对于UGUI来说,就是将一张灰色半透明图放到最前面了
2.目标UI高亮
这里有三种做法:
a.调整目标UI的Hierarchy层级
b.克隆目标UI,调整克隆UI的Hierarchy层级
c.使用Canvas + Graphic Raycaster
这里本人选择的是第三种,因为第一种会破坏原有的的层级,第二种的话,如果目标UI本身没有绑定Mono脚本,则需要复制事件,不太好
需要注意的是,上面三种做法都是会增加drawcall的
这里给出核心脚本:
- using UnityEngine;
- using System.Collections;
- using UnityEngine.UI;
- using System;
- public class GuideManager : MonoSingletion<GuideManager> {
- private Transform maskTra;
- private string fileDir = "GuideFile/";
- private string nowCsvFile;
- private int nowIndex;
- private bool isFinish = false;//是否完成所有的新手引导
- private string[] nameArray;
- public void Init()
- {
- //读取进度
- string content = Resources.Load<TextAsset>(fileDir + "GuideProgress").ToString();
- string[] temp = content.Split(',');
- nowCsvFile = temp[0];
- nowIndex = int.Parse(temp[1]);
- isFinish = bool.Parse(temp[2]);
- //读取需要高亮的组件的Hierarchy路径
- if (!isFinish)
- {
- string s = Resources.Load<TextAsset>(fileDir + nowCsvFile).ToString();
- nameArray = s.Split(new string[] { "\r\n" }, System.StringSplitOptions.RemoveEmptyEntries);
- }
- }
- void OnDestroy()
- {
- //退出游戏后的处理
- Debug.Log("OnDestroy");
- }
- public void Next()
- {
- if (nowIndex < nameArray.Length)
- {
- ShowHightLight(nameArray[nowIndex]);
- nowIndex++;
- }
- else//加载下一个文件
- {
- maskTra.gameObject.SetActive(false);
- int index = int.Parse(nowCsvFile.Substring(nowCsvFile.Length - 1));
- index++;
- nowCsvFile = nowCsvFile.Substring(0, nowCsvFile.Length - 1) + index.ToString();
- string path = fileDir + nowCsvFile;
- string content = null;
- try
- {
- content = Resources.Load<TextAsset>(path).ToString();
- }
- catch (Exception e)
- {
- isFinish = true;
- Debug.Log("finish");
- return;
- }
- nowIndex = 0;
- nameArray = content.Split(new string[] { "\r\n" }, System.StringSplitOptions.RemoveEmptyEntries);
- }
- }
- void ShowHightLight(string name, bool checkIsClone = true)
- {
- if(checkIsClone && name.Contains("/"))
- {
- name = name.Insert(name.IndexOf('/'), "(Clone)");
- }
- StartCoroutine(FindUI(name));
- }
- void CancelHightLight(GameObject go)
- {
- Destroy(go.GetComponent<GraphicRaycaster>());
- Destroy(go.GetComponent<Canvas>());
- Next();
- EventTriggerListener.GetListener(go).onPointerClick -= CancelHightLight;
- }
- IEnumerator FindUI(string name)
- {
- //寻找目标
- GameObject go = UIManager.Instance.Find(name);
- while(go == null)
- {
- yield return new WaitForSeconds(0.1f);
- Debug.Log("wait");
- go = UIManager.Instance.Find(name);
- }
- //高亮
- maskTra = UIManager.Instance.Show("Mask").transform;
- maskTra.SetAsLastSibling();
- go.AddComponent<Canvas>().overrideSorting = true;
- go.AddComponent<GraphicRaycaster>();
- //设置监听
- EventTriggerListener.GetListener(go).onPointerClick += CancelHightLight;
- }
- }
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System;
public class GuideManager : MonoSingletion<GuideManager> {
private Transform maskTra;
private string fileDir = "GuideFile/";
private string nowCsvFile;
private int nowIndex;
private bool isFinish = false;//是否完成所有的新手引导
private string[] nameArray;
public void Init()
{
//读取进度
string content = Resources.Load<TextAsset>(fileDir + "GuideProgress").ToString();
string[] temp = content.Split(',');
nowCsvFile = temp[0];
nowIndex = int.Parse(temp[1]);
isFinish = bool.Parse(temp[2]);
//读取需要高亮的组件的Hierarchy路径
if (!isFinish)
{
string s = Resources.Load<TextAsset>(fileDir + nowCsvFile).ToString();
nameArray = s.Split(new string[] { "\r\n" }, System.StringSplitOptions.RemoveEmptyEntries);
}
}
void OnDestroy()
{
//退出游戏后的处理
Debug.Log("OnDestroy");
}
public void Next()
{
if (nowIndex < nameArray.Length)
{
ShowHightLight(nameArray[nowIndex]);
nowIndex++;
}
else//加载下一个文件
{
maskTra.gameObject.SetActive(false);
int index = int.Parse(nowCsvFile.Substring(nowCsvFile.Length - 1));
index++;
nowCsvFile = nowCsvFile.Substring(0, nowCsvFile.Length - 1) + index.ToString();
string path = fileDir + nowCsvFile;
string content = null;
try
{
content = Resources.Load<TextAsset>(path).ToString();
}
catch (Exception e)
{
isFinish = true;
Debug.Log("finish");
return;
}
nowIndex = 0;
nameArray = content.Split(new string[] { "\r\n" }, System.StringSplitOptions.RemoveEmptyEntries);
}
}
void ShowHightLight(string name, bool checkIsClone = true)
{
if(checkIsClone && name.Contains("/"))
{
name = name.Insert(name.IndexOf('/'), "(Clone)");
}
StartCoroutine(FindUI(name));
}
void CancelHightLight(GameObject go)
{
Destroy(go.GetComponent<GraphicRaycaster>());
Destroy(go.GetComponent<Canvas>());
Next();
EventTriggerListener.GetListener(go).onPointerClick -= CancelHightLight;
}
IEnumerator FindUI(string name)
{
//寻找目标
GameObject go = UIManager.Instance.Find(name);
while(go == null)
{
yield return new WaitForSeconds(0.1f);
Debug.Log("wait");
go = UIManager.Instance.Find(name);
}
//高亮
maskTra = UIManager.Instance.Show("Mask").transform;
maskTra.SetAsLastSibling();
go.AddComponent<Canvas>().overrideSorting = true;
go.AddComponent<GraphicRaycaster>();
//设置监听
EventTriggerListener.GetListener(go).onPointerClick += CancelHightLight;
}
}
3.目标UI的查找
首先,我们需要记录一下目标UI有哪些,查找的话,就是找UI的Hierarchy路径。对此,本人做了一个小工具:
这是unitypackage:
http://pan.baidu.com/s/1beSlVC