0%

最近公司项目做到了红点的步骤,之前的项目感觉红点架构感觉不太好用,于是我自己设计了一下。来上代码
先上C# 代码

预制体红点绑定这个 可以绑定lua文件 在lua检测红点条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/**
* 红点物体;
* RedDotItem.cs
**/
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using LuaInterface;

public class RedDotItem : MonoBehaviour
{
/// <summary>
/// lua文件;
/// </summary>
public string luaClassName;
/// <summary>
/// 红点物体;
/// </summary>
public GameObject Go_RedDot;
/// <summary>
/// 红点类型;
/// </summary>
public List<RedDotType> redDotTypes;
[SerializeField] private string curShowType;

private bool _isInit;
private LuaTable luaObj;
private LuaFunction fnCheckRedDot;
private int leftTime = -1;

public bool isInit
{
get
{
return this._isInit;
}
}

void Awake(){

if (luaClassName == null)
luaClassName = "MainRedDotHelp";
LuaBehaviourProxy obj = LuaBehaviourProxy.CreateLuaProxy(this.gameObject,luaClassName);
luaObj = obj.luaObj;
fnCheckRedDot = luaObj["CheckRedDot"] as LuaFunction;


if (Go_RedDot == null)
return;

this.Init();
}

void Start()
{
//设置红点;
this.CheckRedDot();
this.MoveTime();
}

public void Init()
{
if (_isInit)
return;
_isInit = true;

RedDotManager.Instance.RegisterRedDot(redDotTypes, this);

//设置红点;
this.CheckRedDot();
this.MoveTime();
}

public void Reset()
{
// 取消注册红点;
RedDotManager.Instance.UnRegisterRedDot(this);
// 清除类型
this.redDotTypes.Clear();
// 清除红点标记
this.Go_RedDot = null;
// 重新初始化
_isInit = false;
}

void OnDestroy()
{
//取消注册红点;
RedDotManager.Instance.UnRegisterRedDot(this);

//取消注册lua函数
if (fnCheckRedDot != null)
{
fnCheckRedDot.Dispose();
}
fnCheckRedDot = null;
luaObj = null;
}

public void MoveTime()
{
if (!this.isInit)
return;

if (leftTime > 0)
{
leftTime--;
}
this.SetData(leftTime == 0);
}

/// <summary>
/// 设置红点显示;
/// </summary>
/// <param name="bRedDot"></param>
public void SetData(bool bRedDot, bool bForceRefresh = false)
{
if (bForceRefresh && Go_RedDot.active != bRedDot)
{
Go_RedDot.SetActive(bRedDot);
return;
}

if (Go_RedDot.active != bRedDot)
{
Go_RedDot.SetActive(bRedDot);
}
}
/// <summary>
/// 获取当前物体挂载的所有红点;
/// </summary>
/// <returns></returns>
public List<RedDotType> GetRedDotTypes()
{
return this.redDotTypes;
}

/// 添加当前物体挂载的红点类型;
public void AddRedDotType(RedDotType rt = RedDotType.None)
{
if (rt != RedDotType.None){

if (redDotTypes == null)
redDotTypes = new List<RedDotType>();

if (!redDotTypes.Contains(rt))
{
redDotTypes.Add(rt);
}
CheckRedDot();
}
}

// 设置红点样式
public void SetRedDotNode(GameObject goRedDot)
{
this.Go_RedDot = goRedDot;
}

/// <summary>
/// 调用lua方法;
/// </summary>
/// <returns></returns>
public int CheckRedDot(RedDotType redDotType)
{
string rt = redDotType.ToString();

fnCheckRedDot.BeginPCall();
fnCheckRedDot.Push(luaObj);
fnCheckRedDot.Push(rt);
fnCheckRedDot.PCall();
int state = (int)fnCheckRedDot.CheckNumber();
fnCheckRedDot.EndPCall();

return state;
}

//检测单前对象所有类型红点
public void CheckRedDot()
{
if (!this.isInit)
return;

this.curShowType = "";
List<RedDotType> redDotTypes = this.GetRedDotTypes();
int tmpTime = -1;
for(int i = 0; i < redDotTypes.Count; i++)
{

int time = this.CheckRedDot(redDotTypes[i]);
if (time == 0)
{
this.leftTime = 0;
this.curShowType = redDotTypes[i].ToString();
return;
}

if (time > 0)
{
if (tmpTime == -1)
tmpTime = time;

if (tmpTime > time)
tmpTime = time;
}
}
this.leftTime = tmpTime;
}

/// <summary>
/// 检测红点返回值;
/// </summary>
/// <returns></returns>
public void ShowRedDot(RedDotType redDotType)
{

}
}


红点管理器可以导出lua之后调用更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/**
* 红点系统管理类;
* RedDotManager.cs
**/
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RedDotManager
{
private static RedDotManager _instance;
public static RedDotManager Instance
{
get
{
if (null == _instance)
{
_instance = new RedDotManager();
GameVars.tickUtils.SetInterval(1, _instance.UpdateAll);
}
return _instance;
}
}

/// <summary>
/// 红点物体;
/// </summary>
Dictionary<RedDotType, List<RedDotItem>> RedDotObjDict = new Dictionary<RedDotType, List<RedDotItem>>();
/// <summary>
/// 初始化红点系统(注意只需要初始化一次);
/// </summary>
public void Initilize()
{

}

/// <summary>
/// 注册红点;
/// </summary>
/// <param name="redDotType"></param>
/// <param name="item"></param>
public void RegisterRedDot(List<RedDotType> redDotTypes, RedDotItem item)
{
for (int i = 0; i < redDotTypes.Count; i++)
{
RegisterRedDot(redDotTypes[i], item);
}
}

/// <summary>
/// 通过gameObject注册红点;
/// </summary>
/// <param name="rt"> 类型</param>
/// <param name="item"> 添加的节点</param>
/// <param name="goRedDot"> 红点物体</param>
public void LuaRegisterRedDot(string rt, GameObject item,GameObject goRedDot)
{
RedDotType redDotType = (RedDotType)Enum.Parse(typeof(RedDotType),rt);
RedDotItem rItem = item.GetComponent<RedDotItem>();
if (rItem == null)
{
rItem = item.AddComponent<RedDotItem>();
rItem.AddRedDotType(redDotType);
rItem.SetRedDotNode(goRedDot);
}
else
{
if (!rItem.isInit)
{
rItem.Reset();
rItem.AddRedDotType(redDotType);
rItem.SetRedDotNode(goRedDot);
}
else
{
rItem.AddRedDotType(redDotType);
RegisterRedDot(redDotType,rItem);
}
}
}

/// <summary>
/// 取消注册红点;
/// </summary>
/// <param name="item"></param>
public void UnRegisterRedDot(RedDotItem item)
{
Dictionary<RedDotType, List<RedDotItem>>.Enumerator itor = RedDotObjDict.GetEnumerator();
while (itor.MoveNext())
{
List<RedDotItem> redDotItems = itor.Current.Value;
if (redDotItems.Contains(item))
{
redDotItems.Remove(item);
break;
}
}
}

// lua 调用
public void LuaNotifyAll(string rt, object obj = null)
{
RedDotType cc = (RedDotType)Enum.Parse(typeof(RedDotType),rt);
NotifyAll(cc);
}

private void UpdateAll(object obj)
{
var enumerator = this.RedDotObjDict.GetEnumerator();
while (enumerator.MoveNext())
{
for (int i = 0; i < enumerator.Current.Value.Count; i++)
{
RedDotItem item = enumerator.Current.Value[i];
if (item != null)
{
item.MoveTime();
}
}
}
}

/// <summary>
/// 更新该类型的所有红点组件;
/// </summary>
/// <param name="redDotType"></param>
/// <returns></returns>
private void NotifyAll(RedDotType redDotType)
{
if (RedDotObjDict.ContainsKey(redDotType))
{
for (int i = 0; i < RedDotObjDict[redDotType].Count; i++)
{
RedDotItem item = RedDotObjDict[redDotType][i];
if (item != null)
{
item.CheckRedDot();
}
}
}
}
#region private
/// <summary>
/// 添加红点界面;
/// </summary>
/// <param name="redDotType"></param>
/// <param name="item"></param>
private void RegisterRedDot(RedDotType redDotType, RedDotItem item)
{
if (RedDotObjDict.ContainsKey(redDotType))
{
if (!RedDotObjDict[redDotType].Contains(item))
{
RedDotObjDict[redDotType].Add(item);
}
}
else
{
List<RedDotItem> items = new List<RedDotItem>();
items.Add(item);
RedDotObjDict.Add(redDotType, items);
}
}
#endregion
}


枚举值可在预制体选择那个类型

1
2
3
4
5
6
7
8
9
10
/**
* 红点类型的枚举;
* RedDotType.cs
**/
public enum RedDotType
{
None = 0,
MainUI_EmailRedDot = 1,
MainUI_SignInRedDot = 2,
}

lua方面的代码介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
MainRedDotHelp = newClass("MainRedDotHelp",LuaBehaviour);
function MainRedDotHelp:CheckRedDot(type)
-- 检测状态 RedDotType
if self[type] then
return self[type]()
end
end

-- 邮件红点
function MainRedDotHelp:MainUI_EmailRedDot()

local state = GameData.mailData:GetRedDotTag()
return state
end

-- 签到红点
function MainRedDotHelp:MainUI_SignInRedDot()

local state = GameData.welfareData:GetSignInRedDotTag()
return state
end

好啦大概就这样了 用起来还行

1 什么是烘焙,有什么用

析度/具体数据加工为低维/低解析度/特化数据的过程,通常是为了生成近似算法所需的数据,以提高运行时效率。

2 光照贴图烘焙

你把物体模型放进了场景里之后, 引擎会计算光线,光线照到你的物体的表面形成反光和阴影。 如果不烘焙, 游戏运行的时候,这些反光和阴影都是由显卡和CPU计算出来的。
你烘焙之后,这些反光和阴影都记录到了你的模型里,变成了新的贴图了,运行的时候,显卡和CPU不需要进行对环境光效果的运算了。如前面的回答,节约CPU资源。

3 Lighting Mode(光照模式)

3.1 指定 Unity 对场景中的所有混合光照使用哪种光照模式

3.2 Baked Indirect(烘焙间接)
    如果场景中的灯光模式设置为Mixed,那么这些灯光会给场景提供直接光照,间接光照信息则被烘焙到光照贴图和光照探针中。

3.3 Shadowmask(遮罩)
    如果场景中的灯光模式设置为Mixed,灯光会给场景提供直接光照,间接光照烘焙到光照贴图和光照探针中。Shadowmask和光照探针遮挡信息会被烘焙到阴影信息中。

3.4 Subtractive(减法)
    场景中的直接光照,间接光照和阴影信息都会烘焙到光照贴图中。适合对性能敏感的平台比如移动端平台。

3.5 支持的渲染管线:
    1. 内置渲染管线(Built-in Render Pipeline):支持Baked Indirect,Subtractive和Shadowmask光照模式。

    2. 通用渲染管线(Universal Render Pipeline,简称URP):支持Baked Indirect,Subtractive和Shadowmask光照模式。

    3. 高清渲染管线(High Definition Render Pipeline,简称HDRP):支持Baked Indirect和Shadowmask光照模式。

4 Lightmapper(光照贴图系统)

使用该选项来指定使用哪种光照计算方式来计算场景中的光照贴图。选项有:Progressive 和 Enlighten(遗弃)。默认选项是 Progressive。新增了 CUP 和GPU类型   ,影响烘焙效率

5 Prioritize View(优先视图)

启用此选项,如果Scene窗口打开,系统会逐步烘焙Scene窗口看到的画面,然后再继续烘焙Scene画面之外的场景区域。
如果你在Scene窗口移动场景中物体,改变物体和灯光属性或者改变Scene窗口画面等操作,烘焙会及时调整,快速逐步烘焙改变后的画面。在使用此选项时记得打开Auto Generate(自动生成)复选框。

6 Multiple ImportanceSampling(多重重要抽样)

(默认是禁用状态)这是针对环境光采样的设置。如果开启,可以缩短光照贴图的生成时间,但是在场景中某些较暗的地方会产生明显的噪点。

7 Direct Samples(直接光照采样)

用于设置从每一个纹素(Texel)射出的采样路径数(针对直接光照)。数值越大效果越好,烘焙时间也越长。

8 Indirect Samples(间接光照采样)

用于设置从每一个纹素(Texel)射出的采样路径数(针对间接光照)。数值越大效果越好,烘焙时间也越长。针对户外场景,指导数值为100。室内场景(包含自发光物体),可以按需增加采样路径数直到看到效果。

9 Environment Samples(环境光照采样)

针对环境光的采样数。数值越大效果越好,烘焙时间也越长。默认数值为500。

10 Light Probe SampleMultiplier(光照探头计算)

如要使用此功能,必须在Project Settings > Editor> Graphics中禁用Use legacy Light Probe sample counts
此数值会被用于分别乘以Direct Samples,Indirect Samples和Environment Samples这三个数值。这三个数值会被应用于LightProbes采样。数值越大效果越好,烘焙时间也越长。

11 Bounces(反射次数)

当追踪路径时,使用该值来指定间接光照反射的次数。对于大多数场景,反射2次应该足够了。而对于一些室内场景,可能需要更多地反射次数。

12 Filtering(过滤)

12.1 
    Filtering区域的设置用于光照贴图的降噪操作。降噪操作本质上是一个针对已经烘焙好的光照贴图做后处理的过程。
    如果启用Filtering功能,系统会在把光照贴图的Direct,Indirect和AmbientOcclusion这三部分信息结合之前,分别为这三个部分应用降噪算法。 

12.2 
    自动:Progressive Lightmapper会自动选择一个当前机器支持的降噪算法应用到光照贴图上(因为规则是固定的,所以具体规则请参考Unity文档)。
    高级:可以为Direct,Indirect和Ambient Occlusion分别选择降噪算法(Denoiser)或者降噪滤镜(Filter)。如果你有支持Nvidia Optix降噪算法的GPU,可以选择Optix;如果有支持RadeonPro降噪算法的GPU,可以选择RadeonPro;在任何情况下,都可以选择基于CPU的降噪算法OpenImageDenoise。这里的Guassian(高斯)滤镜会在降噪算法之后在光照贴图上做进一步的模糊处理,以减少光照贴图中的噪点。  

13 Lightmap Resolution(光照贴图分辨率)

数值单位为texelsper unit(每单位面积的纹素)。
Texel(纹素)有别于Pixel(像素)。像素是图片的基本单位,如果我们在图片编辑软件中把图片放大到足够大,可以看到这些图片由许多正方形的像素组成,所以像素是屏幕空间的概念。纹素则是纹理贴图的基本单位,纹理贴图是应用于模型上的,所以并不是屏幕空间的概念。
在模型被绘制到屏幕上时,纹素会被转换成屏幕上的像素展现出来。我们可以通过网络上找到的这张图来理解像素和纹素之间的对应关系
像素和纹素最大的区别是:像素其实就是图片数据;但是纹素可以代表很多类型的数据,它可以是纹理贴图,也可以是用于计算阴影的深度图。
光照贴图本质上是纹理贴图,因此Progressive Lightmapper在这里用纹素而不是像素来代表光照贴图的分辨率。

14 Lightmap Padding(光照贴图填充)

数值单位为texel(纹素),默认值为2。烘焙好的光照贴图中包含很多Charts。这些Charts可以理解成对应模型上包含烘焙光照信息的UV色块。在游戏运行时,这些色块会与模型网格进行映射,完成最终效果的计算(在模型原先的纹理上叠加烘焙的光照信息)。但是这些“色块”之间必须保持一定的距离才能确保模型上一个部位的颜色不会“渗色”到另一个部位。

15 Lightmap Size(光照贴图尺寸)

数值单位为像素,默认值为1024。根据Lightmap Resolution和Lightmap Padding的参数设定,烘焙出来的光照贴图数量会相应的变化。这里的大小其实代表的是每张光照贴图的最大尺寸。按照实际需求,即使设置了2048,某些光照贴图的尺寸也有可能是1024或者512。

16 Compress Lightmaps(压缩光照贴图)

默认启用,对光照贴图进行压缩操作。虽然压缩过的光照贴图可以减少内存占用,但是也会导致光照贴图质量下降。

17 Ambient Occlusion(环境遮蔽)

环境光遮蔽用于为场景中的某些区域比如裂缝,孔洞,墙面的交界处,或者任何两个物体相邻的区域添加类似于阴影的效果。它会让这些地方变得比其他地方更暗一些。此处的设置会把这些环境光遮蔽信息烘焙入光照贴图中。

18 Directional Mode(方向模式)

Directional:此模式下会生成第二套光照贴图,专门用于保存入射光的主要方向信息。使用法线贴图的材质可以利用这张光照贴图上的方向信息,在计算法线贴图时加入光照贴图中保存的全局光照信息。不过此模式下生成的光照贴图通常比Non-Directional模式下生成的光照贴图大一倍。(此模式下生成的光照贴图无法在SM2.0和GLES2.0硬件上解码使用。在这些硬件上会回退到Non-Directional模式)。
Non-Directional:禁止烘焙时生成第二套用于保存入射光主要方向信息的光照贴图。

19 Indirect Intensity(间接光强度)和Albedo Boost(反照率增强)

Indirect Intensity(间接光强度):用于控制光照贴图中保存的间接光强度。数值限定在0到5之间。默认数值为1。数值大于1会增强间接光强度,小于1会减弱间接光强度。
Albedo Boost(反射率增强):用于控制物体表面之间光子弹射的数量。默认数值为1。数值限定在1到10之间。数值越大,物体表面的反射率越趋向于白色。    

最近项目需要写新手指引,不行随便写个耦合很高的。
但是我们用的ngui 没有点击穿透这一说,这就很尴尬了。但是作为一个面向搜索引擎的程序员这有啥怕;
网上我看到了一个方案 把屏幕用4个矩形分开只剩下中间的能点击的部分没有矩形 其他地方加上box。 但是我觉很不友好,突然面向搜索引擎 又发力了
第二个方案用的meshCollider(网格碰撞器) 顺便还有大神写了个轮子 下面我们展示代码

UIMaskWidget.cs 有兴趣的自己看下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class UIMaskWidget : UIWidget
{
[SerializeField, HideInInspector] Texture mTexture;
[SerializeField, HideInInspector] Shader mShader;
[SerializeField, HideInInspector] bool mSliced;
[SerializeField, HideInInspector] Vector4 mBorder;

private MeshCollider mMeshCollider = null;
private Mesh mColliderMesh;
private Vector3[] mColliderMeshVertices = new Vector3[8];
private int[] mColliderMeshTriangles = new int[24];
private Texture mSpareTexture;
//private Material mMat = null;
public override Texture mainTexture
{
get
{
if (mMat != null)
{
return mMat.mainTexture;
}
if (mTexture == null)
{
return spareTexture;
}
return mTexture;
}
set
{
if (mTexture != value)
{
if (drawCall != null && drawCall.widgetCount == 1 && mMat == null)
{
mTexture = value;
drawCall.mainTexture = value;
}
else
{
RemoveFromPanel();
mTexture = value;
MarkAsChanged();
}
}
}
}

public override Material material
{
get
{
return mMat;
}
set
{

}
}

public override Shader shader
{
get
{
if (mMat != null) return mMat.shader;
if (mShader == null) mShader = Shader.Find("Unlit/Transparent Colored");
return mShader;
}
set
{

}
}

public override Vector4 border
{
get
{
return mBorder;
}
set
{
if (mBorder != value)
{
mBorder = value;
MarkAsChanged();
}
}
}

public MeshCollider meshCollider
{
get
{
if (mMeshCollider == null)
{
mMeshCollider = GetComponent<MeshCollider>();
if (mMeshCollider == null)
{
mMeshCollider = gameObject.AddComponent<MeshCollider>();
}
}
return mMeshCollider;
}
}

public Mesh colliderMesh
{
get
{
if (mColliderMesh == null)
{
mColliderMesh = new Mesh();
mColliderMesh.name = "UIMaskWidget";
mColliderMesh.vertices = mColliderMeshVertices;

for (int i = 0; i < 4; i++)
{
int index = i * 6;

mColliderMeshTriangles[index] = i;
mColliderMeshTriangles[index + 2] = (i + 5) > 7 ? i + 1 : i + 5;
mColliderMeshTriangles[index + 1] = i + 4;

mColliderMeshTriangles[index + 3] = i;
mColliderMeshTriangles[index + 5] = (i + 1) > 3 ? i - 3 : i + 1;
mColliderMeshTriangles[index + 4] = (i + 5) > 7 ? i + 1 : i + 5;
}
mColliderMesh.triangles = mColliderMeshTriangles;
}
return mColliderMesh;
}
}

public bool isTextureNull
{
get
{
return mTexture == null;
}
}

public bool isSliced
{
get
{
return mSliced;
}
set
{
if (mSliced != value)
{
mSliced = value;
MarkAsChanged();
}
}
}

private Texture spareTexture
{
get
{
if (mSpareTexture == null)
{
Texture2D tex = new Texture2D(1, 1);
tex.name = "UIMaskWidget";
tex.SetPixel(0, 0, Color.white);
tex.Apply();
mSpareTexture = tex;
}
return mSpareTexture;
}
}

protected override void OnUpdate()
{
base.OnUpdate();
MarkAsChanged();
}

public override void OnFill(List<Vector3> verts, List<Vector2> uvs, List<Color> cols)
{
if (mainTexture == null)
{
return;
}
Fill(verts, uvs, cols);
}

void Fill(List<Vector3> verts, List<Vector2> uvs, List<Color> cols)
{
if (root == null)
return;

verts.Clear();
Vector3 innerLB = new Vector3(width * -pivotOffset.x, height * -pivotOffset.y, 0);
Vector3 innerRT = new Vector3(width * (1 - pivotOffset.x), height * (1 - pivotOffset.y), 0);
Vector3 windowHalfSize = new Vector3(NGUITools.screenSize.x, NGUITools.screenSize.y, 0) * 0.5f;
//Vector3 windowHalfSize = new Vector3(1280, 720, 0) * 0.5f;
Vector3 outerLB = transform.InverseTransformPoint(root.transform.TransformPoint(-windowHalfSize));
Vector3 outerRT = transform.InverseTransformPoint(root.transform.TransformPoint(windowHalfSize));
float[] vxs = new float[4] { outerLB.x, innerLB.x, innerRT.x, outerRT.x };
float[] vys = new float[4] { outerLB.y, innerLB.y, innerRT.y, outerRT.y };
// Rectangle LB
verts.Add(new Vector3(vxs[0], vys[0], 0));
verts.Add(new Vector3(vxs[0], vys[1], 0));
verts.Add(new Vector3(vxs[1], vys[1], 0));
verts.Add(new Vector3(vxs[1], vys[0], 0));
// Rectangle CB
verts.Add(new Vector3(vxs[1], vys[0], 0));
verts.Add(new Vector3(vxs[1], vys[1], 0));
verts.Add(new Vector3(vxs[2], vys[1], 0));
verts.Add(new Vector3(vxs[2], vys[0], 0));
// Rectangle RB
verts.Add(new Vector3(vxs[2], vys[0], 0));
verts.Add(new Vector3(vxs[2], vys[1], 0));
verts.Add(new Vector3(vxs[3], vys[1], 0));
verts.Add(new Vector3(vxs[3], vys[0], 0));
// Rectangle LC
verts.Add(new Vector3(vxs[0], vys[1], 0));
verts.Add(new Vector3(vxs[0], vys[2], 0));
verts.Add(new Vector3(vxs[1], vys[2], 0));
verts.Add(new Vector3(vxs[1], vys[1], 0));
// Rectangle RC
verts.Add(new Vector3(vxs[2], vys[1], 0));
verts.Add(new Vector3(vxs[2], vys[2], 0));
verts.Add(new Vector3(vxs[3], vys[2], 0));
verts.Add(new Vector3(vxs[3], vys[1], 0));
// Rectangle LT
verts.Add(new Vector3(vxs[0], vys[2], 0));
verts.Add(new Vector3(vxs[0], vys[3], 0));
verts.Add(new Vector3(vxs[1], vys[3], 0));
verts.Add(new Vector3(vxs[1], vys[2], 0));
// Rectangle CT
verts.Add(new Vector3(vxs[1], vys[2], 0));
verts.Add(new Vector3(vxs[1], vys[3], 0));
verts.Add(new Vector3(vxs[2], vys[3], 0));
verts.Add(new Vector3(vxs[2], vys[2], 0));
// Rectangle RT
verts.Add(new Vector3(vxs[2], vys[2], 0));
verts.Add(new Vector3(vxs[2], vys[3], 0));
verts.Add(new Vector3(vxs[3], vys[3], 0));
verts.Add(new Vector3(vxs[3], vys[2], 0));

uvs.Clear();
float[] uxs, uys;
if (isSliced)
{
Vector2 texSizeR = new Vector2(1f / mainTexture.width, 1f / mainTexture.height);
uxs = new float[4] { 0, border.x * texSizeR.x, 1 - border.z * texSizeR.x, 1 };
uys = new float[4] { 0, border.y * texSizeR.y, 1 - border.w * texSizeR.y, 1 };
}
else
{
Vector2 screenSizeR = new Vector2(1f / (vxs[3] - vxs[0]), 1f / (vys[3] - vys[0]));
uxs = new float[4] { 0, (vxs[1] - vxs[0]) * screenSizeR.x, (vxs[2] - vxs[0]) * screenSizeR.x, 1 };
uys = new float[4] { 0, (vys[1] - vys[0]) * screenSizeR.y, (vys[2] - vys[0]) * screenSizeR.y, 1 };
}
// Rectangle LB
uvs.Add(new Vector3(uxs[0], uys[0], 0));
uvs.Add(new Vector3(uxs[0], uys[1], 0));
uvs.Add(new Vector3(uxs[1], uys[1], 0));
uvs.Add(new Vector3(uxs[1], uys[0], 0));
// Rectangle CB
uvs.Add(new Vector3(uxs[1], uys[0], 0));
uvs.Add(new Vector3(uxs[1], uys[1], 0));
uvs.Add(new Vector3(uxs[2], uys[1], 0));
uvs.Add(new Vector3(uxs[2], uys[0], 0));
// Rectangle RB
uvs.Add(new Vector3(uxs[2], uys[0], 0));
uvs.Add(new Vector3(uxs[2], uys[1], 0));
uvs.Add(new Vector3(uxs[3], uys[1], 0));
uvs.Add(new Vector3(uxs[3], uys[0], 0));
// Rectangle LC
uvs.Add(new Vector3(uxs[0], uys[1], 0));
uvs.Add(new Vector3(uxs[0], uys[2], 0));
uvs.Add(new Vector3(uxs[1], uys[2], 0));
uvs.Add(new Vector3(uxs[1], uys[1], 0));
// Rectangle RC
uvs.Add(new Vector3(uxs[2], uys[1], 0));
uvs.Add(new Vector3(uxs[2], uys[2], 0));
uvs.Add(new Vector3(uxs[3], uys[2], 0));
uvs.Add(new Vector3(uxs[3], uys[1], 0));
// Rectangle LT
uvs.Add(new Vector3(uxs[0], uys[2], 0));
uvs.Add(new Vector3(uxs[0], uys[3], 0));
uvs.Add(new Vector3(uxs[1], uys[3], 0));
uvs.Add(new Vector3(uxs[1], uys[2], 0));
// Rectangle CT
uvs.Add(new Vector3(uxs[1], uys[2], 0));
uvs.Add(new Vector3(uxs[1], uys[3], 0));
uvs.Add(new Vector3(uxs[2], uys[3], 0));
uvs.Add(new Vector3(uxs[2], uys[2], 0));
// Rectangle RT
uvs.Add(new Vector3(uxs[2], uys[2], 0));
uvs.Add(new Vector3(uxs[2], uys[3], 0));
uvs.Add(new Vector3(uxs[3], uys[3], 0));
uvs.Add(new Vector3(uxs[3], uys[2], 0));

cols.Clear();
for (int i = 0; i < 32; i++)
{
cols.Add(color);
}

FillMeshCollider(vxs, vys);
}

void FillMeshCollider(float[] vxs, float[] vys)
{
if (!Application.isPlaying)
{
return;
}
mColliderMeshVertices[0] = new Vector3(vxs[0], vys[0], 0);
mColliderMeshVertices[1] = new Vector3(vxs[3], vys[0], 0);
mColliderMeshVertices[2] = new Vector3(vxs[3], vys[3], 0);
mColliderMeshVertices[3] = new Vector3(vxs[0], vys[3], 0);

mColliderMeshVertices[4] = new Vector3(vxs[1], vys[1], 0);
mColliderMeshVertices[5] = new Vector3(vxs[2], vys[1], 0);
mColliderMeshVertices[6] = new Vector3(vxs[2], vys[2], 0);
mColliderMeshVertices[7] = new Vector3(vxs[1], vys[2], 0);

colliderMesh.vertices = mColliderMeshVertices;
meshCollider.sharedMesh = mColliderMesh;
}
}

继续显示我们的自己的逻辑
由于我想写个基本由策划自己配置就行的指引不需要程序自己操心的!!! 哈哈哈
就想到了给按钮BOX加委托 下面是我们自己的逻辑

GuideData.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
-- 新手指引
module ('m__' .. ..., package.seeall)
local GuideData = newClass("GuideData", BaseData)
function GuideData:Init()

self:ConstructMember()
self:InitMember()
end

function GuideData:Clear()

end

function GuideData:ConstructMember()

self.m_stepCfg = {} -- 按照大阶段的数据
self.m_stepIndex = 0 -- 主步骤
self.m_subIndex = 1 -- 子步骤
self.m_stepStartIndex = {} -- 开始的第一步保存
self.m_subEndIndex = {} -- 结束的第一步保存
end

function GuideData:InitMember()

if not self.m_timer then
self.m_timer = CountTimer.New()
self.m_timer:AddEventListener(CountTimer.EVENT_TIMER, self, function() self:TimerCheckJudge() end)
end
end

-- 服务器记录值同步
function GuideData:InitData()

if not LuaGameVars.CanPlayGuide then
return
end

local temp = {}
for i, v in ipairs(DBData.guidBaseCfg) do
self.m_stepCfg[v.main_step] = self.m_stepCfg[v.main_step] or {}
self.m_stepCfg[v.main_step][v.index] = v

temp[v.main_step] = temp[v.main_step] or {}
table.insert(temp[v.main_step],v)
end

-- 大步骤的开始第一步
for main_step = 1, 1000 do
local cfg = temp[main_step]
if not cfg then
break
end
table.sort(cfg,function(a,b) return a.index < b.index end)

local startInfo,endInfo = cfg[1],cfg[#cfg]
self.m_stepStartIndex[main_step] = startInfo.index
self.m_subEndIndex[main_step] = endInfo.index
end

-- 同步数据
local guide_index = GameData.playerData:GetValue(role_ids.guide_index)

self.m_stepIndex = (guide_index == 0) and 1 or guide_index
self.m_subIndex = self.m_stepStartIndex[self.m_stepIndex]
--self.m_subIndex = 0

--开始timer
if self.m_timer then
self.m_timer:start(-1, 0.2)
end
end

-- 获取当前阶段的配置
function GuideData:GetCurStepCfg()

if not self.m_stepCfg[self.m_stepIndex] or not self.m_stepCfg[self.m_stepIndex][self.m_subIndex] then
return
end

return self.m_stepCfg[self.m_stepIndex][self.m_subIndex]
end

-- 间隔检测
function GuideData:TimerCheckJudge()

if MainView.ins:CheckUIIsShow(ModuleName.GuideModuleUI) then
return
end

if not self:CheckJudge() then
UIHelps.CloseWindow(ModuleName.GuideModuleUI)
return
end

UIHelps.OpenWindow(ModuleName.GuideModuleUI)
end

-- 增加步骤值
function GuideData:AddStepIndex()

local curCfg = self:GetCurStepCfg()
if curCfg.end_step then
self.m_stepIndex = self.m_stepIndex + 1
end
self.m_subIndex = curCfg.next_index


if self.m_stepIndex > table.nums(self.m_stepCfg) then
-- 暂停计时器
if self.m_timer then
self.m_timer:stop()
self.m_timer:dispose()
end
self.m_timer = nil
end

-- 发给服务器记录
local info = {guide_index = self.m_stepIndex}
LuaAppFacade.getIns():SendNotification(NoticeConst.ROLE_SAVE_GUIDE_INDEX,info)
end

-- 检查条件
function GuideData:CheckJudge()

if not self.m_stepCfg[self.m_stepIndex] or not self.m_stepCfg[self.m_stepIndex][self.m_subIndex] then
return
end

local cfg = self.m_stepCfg[self.m_stepIndex][self.m_subIndex]
if not cfg or cfg.main_step ~= self.m_stepIndex then
return
end

-- 检测初始位置是主界面 还是挂机的指引
if cfg.index == self.m_stepStartIndex[cfg.main_step] then
local nextInfo = DBData.guidBaseCfg[cfg.next_index]
if nextInfo.ModuleName == "BattleHomeModuleUI" then
if MainView.ins:CheckUIIsShow(nextInfo.ModuleName) then
self:AddStepIndex()
return
end
end
end
-- 检查UI是否打开 要放在后面
local ModuleName = cfg.ModuleName
if not MainView.ins:CheckUIIsShow(ModuleName) then
return
end

-- 指引检查
if self.m_stepIndex == 1 then
-- 剧情体验战斗
elseif self.m_stepIndex == 2 then
-- 主线战斗1
return self:CheckBaseJudge1(1)
elseif self.m_stepIndex == 3 then
-- 卡牌升级和穿戴装备
return self:CheckBaseJudge2()
elseif self.m_stepIndex == 4 then
-- 补给抽奖
return self:CheckBaseJudge3()
elseif self.m_stepIndex == 5 then
-- 主线战斗2
return self:CheckBaseJudge1(2)
end

-- 没有大步骤检测只有子步骤
if cfg.other_fun_index then
return self:CheckOtherFunIndex()
end

return true
end

-- 主线战斗1 2
function GuideData:CheckBaseJudge1(needSection)

local cfg = self:GetCurStepCfg()
-- 检测主线战斗1
if cfg.index == self.m_stepStartIndex[cfg.main_step] then

if curCfg.chapter > 0 and curCfg.section >= needSection then
self.m_stepIndex = cfg.main_step + 1
self.m_subIndex = self.m_stepStartIndex[self.m_stepIndex]
return
end
end

return self:CheckOtherFunIndex()
end

-- 卡牌升级
function GuideData:CheckBaseJudge2()

-- 检测卡牌升级和穿戴装备
local cfg = self:GetCurStepCfg()
if cfg.index == self.m_stepStartIndex[cfg.main_step] then
local items = GameData.bagData:GetContainerItems(global.system_cfg.bag_type.card_bag)
for _, item in pairs(items) do
local equips = item:Get_Equips()
if item:Level() > 1 and table.nums(equips) > 1 then
self.m_stepIndex = cfg.main_step + 1
self.m_subIndex = self.m_stepStartIndex[self.m_stepIndex]
return
end
end
end

return self:CheckOtherFunIndex()
end

-- 补给抽奖
function GuideData:CheckBaseJudge3()

local cfg = self:GetCurStepCfg()
if cfg.index == self.m_stepStartIndex[cfg.main_step] then

if not isFree then
self.m_stepIndex = cfg.main_step + 1
self.m_subIndex = self.m_stepStartIndex[self.m_stepIndex]
return
end
end

return self:CheckOtherFunIndex()
end
--------------------------------------------------------------------- 淫荡分更新 ------------------------------------------------------
-- 检测子步骤
function GuideData:CheckOtherFunIndex()

local cfg = self:GetCurStepCfg()
if cfg.other_fun_index == 1 then
-- 检测卡牌有没有升级
return self:CheckCardUpLevel()
elseif cfg.other_fun_index == 2 then
-- 检测主线有没有出战上阵
return self:CheckEmBattleSlot()
elseif cfg.other_fun_index == 3 then
-- 检测个人演习有没有出战上阵
return self:CheckEmBattleExercise()
elseif cfg.other_fun_index == 4 then
-- 检测剧情演示副本角色能量是否已满
return self:CheckStoryStageEnergy()
end

return true
end

--检测卡牌升级
function GuideData:CheckCardUpLevel()

end

-- 检测主线有没有出战上阵
function GuideData:CheckEmBattleSlot()

end

-- 检测个人演习有没有出战上阵
function GuideData:CheckEmBattleExercise()

end

-- 检测剧情演示副本角色能量是否已满
function GuideData:CheckStoryStageEnergy()

end
--------------------------------------------------------------------- 淫荡分更新 ------------------------------------------------------

表现层
GuideModuleUI.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
module ('m__' .. ..., package.seeall)

local GuideModuleUI = newClass("GuideModuleUI", LuaWindowModule)
function GuideModuleUI:ModuleAwake( ... )

self:SuperCall(GuideModuleUI, "ModuleAwake");

self:ConstructMember()
self:InitMember()
end

-- 声明变量
function GuideModuleUI:ConstructMember()

UIStorage.FillTableAttr(self)

self.m_dicNoticeHandle = {} -- 辅助监听回调
self.m_OnClickBtn = nil
self.m_OnClickEvent = nil
self.m_timer = nil
self.m_timerDelay = nil
self.m_countDownTime = 50 -- 倒计时时间
self.m_cfg = {} -- 配置表
self.m_curMeshColliderPos = nil -- 保存的设置位置
end

-- 初始化成员
function GuideModuleUI:InitMember()

LuaUIEventListener.AddEvent_OnClick(self.meshCollider.gameObject, function() self:OnClick() end)

if not self.m_timer then
self.m_timer = CountTimer.New()
self.m_timer:AddEventListener(CountTimer.EVENT_TIMER, self, function() self:UpdateTimer() end)
self.m_timer:start(-1, 1)
end
end

-- 打开
function GuideModuleUI:Show(body)

self.m_cfg = GameData.guideData:GetCurStepCfg()
self.meshCollider.gameObject:SetActive(true)
-- 显示
self:UpdateGuidUI()
end

-- 关闭
function GuideModuleUI:Close()

if self.m_timer then
self.m_timer:dispose()
self.m_timer = nil
end

if self.m_timerDelay then
self.m_timerDelay:dispose()
self.m_timerDelay = nil
end
end

-- 释放委托
function GuideModuleUI:ReleaseEvent()

if self.m_OnClickBtn and self.m_OnClickEvent then
LuaUIEventListener.ReleaseEvent_OnClick(self.m_OnClickBtn,self.m_OnClickEvent)
end
self.m_OnClickBtn = nil
self.m_OnClickEvent = nil
end

-- 获取对应界面按钮
function GuideModuleUI:GetButton()

if self.m_cfg.isSceneNode and GameObject.Find(self.m_cfg.targe_node) then
return GameObject.Find(self.m_cfg.targe_node)
end

local ViewContainerType = {"UIPopupView","UIBaseView","UITopView"}
for k, type in pairs(ViewContainerType) do
local objParentObj = MainView.ins:GetViewContainer(type)
local buttonTrans = objParentObj.transform:Find(self.m_cfg.targe_node)
if buttonTrans and buttonTrans.gameObject and buttonTrans.gameObject.activeInHierarchy then
return buttonTrans.gameObject
end
end

return printError("填写的节点位置不对请仔细检查:" .. self.m_cfg.targe_node)
end

-- 获取对应的位置
function GuideModuleUI:GetTargetPos()

if not self.m_OnClickBtn then return end

if self.m_cfg.isSceneNode then
-- 场景按钮
local scenePos = self.m_OnClickBtn.transform.position
local x,y,z = UIHelps.ChangeScenePosToUIPos(scenePos.x,scenePos.y, scenePos.z)
local guideLocalPos = self.bg.transform.parent:InverseTransformPoint(Vector3.New(x, y, 1))
guideLocalPos.x = guideLocalPos.x
guideLocalPos.y = guideLocalPos.y
return guideLocalPos
else
local widget = self.m_OnClickBtn:GetComponent("UIWidget")
local labPivotX = widget.pivotOffset.x --0.5
local labPivotY = widget.pivotOffset.y --0.5

local guideLocalPos = self.bg.transform.parent:InverseTransformPoint(self.m_OnClickBtn.transform.position)
guideLocalPos.x = guideLocalPos.x + (0.5 - labPivotX) * widget.width + (self.m_cfg.offsetX or 0)
guideLocalPos.y = guideLocalPos.y + (0.5 - labPivotY) * widget.height + (self.m_cfg.offsetY or 0)

return guideLocalPos
end
end

-- 更新位置
function GuideModuleUI:UpdateMeshCollider()

if not self.m_OnClickBtn then return end

local guideLocalPos = self:GetTargetPos()
self.meshCollider.transform.localPosition = guideLocalPos
self.m_curMeshColliderPos = guideLocalPos
self.meshCollider.width = self.m_cfg.radius * 2
self.meshCollider.height = self.m_cfg.radius * 2

-- 显示圆形裁剪坐标
local sp = self.bg:GetComponent("UISprite")
local m_Material = Material.New(Shader.Find("UI/CircleGuide"))
m_Material:SetVector("_Center",Vector4.New(guideLocalPos.x, guideLocalPos.y, 0, 0))
m_Material:SetFloat("_Slider",self.m_cfg.radius)
sp.material = m_Material

-- 圆形特效
self.arrowEffect.transform.localPosition = guideLocalPos
self.arrowEffect:SetActive(true)
end

-- 更新对话框
function GuideModuleUI:UpdateDialogue()

if not self.m_cfg or not self.m_cfg.dialog_direction then
return
end

self.dialogueLeftNode:SetActive(self.m_cfg.dialog_direction == 1)
self.dialogueRightNode:SetActive(self.m_cfg.dialog_direction == 2)
if self.m_cfg.dialog_direction == 1 then

self.text_left_jueseming.text = self.m_cfg.name
self.text_left_wenbenneirong.text = self.m_cfg.dialog_dec

local to = self.dialogueLeftNode.transform.localPosition
local from = {x = to.x - 1500, y = to.y, z = to.z}
self.dialogueLeftNode.transform.localPosition = from
self.dialogueLeftNode.transform:DOLocalMoveX(to.x, 0.5):OnComplete(function()
self.act_left_wenbenneirong:SetCharsPerSecond(12)
self.act_left_wenbenneirong:ResetToBeginning()
end)
else
self.text_right_jueseming.text = self.m_cfg.name
self.text_right_wenbenneirong.text = self.m_cfg.dialog_dec

local to = self.dialogueRightNode.transform.localPosition
local from = {x = to.x + 1500, y = to.y, z = to.z}
self.dialogueRightNode.transform.localPosition = from
self.dialogueRightNode.transform:DOLocalMoveX(to.x, 0.5):OnComplete(function()

self.act_right_wenbenneirong:SetCharsPerSecond(12)
self.act_right_wenbenneirong:ResetToBeginning()
end)
end
end

-- 检测位置坐标 防止位置错误
function GuideModuleUI:CheckTargePos()

local guideLocalPos = self:GetTargetPos()
if self.m_curMeshColliderPos and self.m_curMeshColliderPos ~= guideLocalPos then
self:UpdateMeshCollider()
end
end

-- 刷新这个界面
function GuideModuleUI:UpdateGuidUI()

-- 释放
self:ReleaseEvent()

self.m_OnClickBtn = self:GetButton()
if not self.m_OnClickBtn then
UIHelps.CloseWindow(ModuleName.GuideModuleUI)
return
end

-- 按钮增加委托
if not self.m_cfg.isSceneNode then
self.m_OnClickEvent = LuaUIEventListener.AddEvent_OnClick2(self.m_OnClickBtn, function() self:ShowNext() end)
else
-- 场景按钮直接增加
GameData.guideData:AddStepIndex()
end

-- 更新对话
self:UpdateDialogue()

-- 更新手指位置
if self.m_cfg.delay_time then
-- 延迟显示手指
self.m_timerDelay = CountTimer.New()
self.m_timerDelay:AddEventListener(CountTimer.EVENT_TIMERCOMPLETE, self, function()
self:UpdateMeshCollider()
end)
self.m_timerDelay:start(1, self.m_cfg.delay_time)
else
self:UpdateMeshCollider()
-- 检测手指最终位置对不对
self.m_timerDelay = CountTimer.New()
self.m_timerDelay:AddEventListener(CountTimer.EVENT_TIMERCOMPLETE, self, function()
self:CheckTargePos()
end)
self.m_timerDelay:start(1,3)
end
end

-- 显示下一个
function GuideModuleUI:ShowNext()

-- 释放
self:ReleaseEvent()
-- 下一个步骤
GameData.guideData:AddStepIndex()
-- 走重新打开界面
UIHelps.CloseWindow(ModuleName.GuideModuleUI)
end

function GuideModuleUI:UpdateTimer()

if self.m_countDownTime then
self.m_countDownTime = self.m_countDownTime - 1
if self.m_countDownTime < 0 then
self.m_timer:stop()
self:ShowNext()
end
end
end

-- 点击关闭
function GuideModuleUI:OnClickClose()

UIHelps.CloseWindow(ModuleName.GuideModuleUI)
end

-- 点击背景
function GuideModuleUI:OnClick()

end

-- 注册监听
function GuideModuleUI:listNotificationInterests()
return {

}
end

-- 监听回调
function GuideModuleUI:handleNotification(notification )

local msgName = notification:getName()
local body = notification:getBody()

local handle = self.m_dicNoticeHandle[msgName]
if handle ~= nil then
handle(self, body)
end
end

看我们的配置表

大功告成
。。。
。。

UnityIOS打包流程图 下载查看全图