抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

简介

使用有限状态机构造的连招系统,支持技能连招、分支技能、打断、变招、长按技能、蓄力技能。

演示

原理

在 Update 中持续判断状态切换,并根据当前状态执行对应的操作。

状态机分为五个状态,Idle、Running、Holding、Charging 以及 Waiting。其中 Running 为非长按技能释放状态;Holding 为长按技能;Charging 为蓄力技能。

技能树

本系统维护一个技能列表,技能列表中保存自定义的技能树。

SkillTree
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
using System.Collections.Generic;
using UnityEngine;

public class SkillTree
{
/// <summary>
/// 技能名称
/// </summary>
public string name { get; set; }
/// <summary>
/// 技能id 一系列技能使用同一id
/// </summary>
public int id { get; set; }
/// <summary>
/// 键位需求
/// </summary>
public KeyCode key { get; set; }
/// <summary>
/// 下一连招列表
/// </summary>
public List<SkillTree> next { get; set; }
/// <summary>
/// 技能持续时间
/// </summary>
public float skillTime { get; set; }
/// <summary>
/// 是否正在释放技能
/// </summary>
public bool isRunSkill { get; set; }
/// <summary>
/// 连招超时时间
/// </summary>
public float outOfTime { get; set; }
/// <summary>
/// 是否可以强制打断技能
/// </summary>
public bool isCanForceStop { get; set; }
/// <summary>
/// 强制打断次数
/// </summary>
public int forceTimes { get; set; }
/// <summary>
/// 默认强制打断次数
/// </summary>
public int defaultForceTimes { get; set; }
/// <summary>
/// 强制打断重置时间
/// </summary>
public float forceResetTime { get; set; }
/// <summary>
/// 技能类型
/// </summary>
public SkillType skillType { get; set; }
/// <summary>
/// 长按/蓄力时间
/// </summary>
public float holdingTime { get; set; }
/// <summary>
/// 进度条颜色
/// </summary>
public Color progressColor { get; set; }

public SkillTree() {
skillType = SkillType.Click;
progressColor = Color.white;
next = new List<SkillTree>();
}
}

本系统还维护当前使用的技能、输入间隔时间、技能持续时间、蓄力/长按时间。这些数据是连招判定的相关数据。

连招判定方法

我们在技能树中保存了需要按下的按键,只要判断输入事件是否和所需要的键位相同即可。

连招判定分为两个部分,一个是从根技能(即起手式)的情况,一个是判定连招的情况。

根技能的情况下有两种判断,一个是技能打断的判断,一个是开始放技能的判断。我们只要检测最近有无放过技能就能分辨是什么情况的判断。

连招的情况下也有两种情况,一种是连招成功,那么我们就保存当前的技能为连招的技能;另一种是连招失败,即下一个键位不是连招的键位,那么我们就返回一个错误连招的状态。

判定连招键位的时候我们遍历键位列表,即可做出分支攻击。

技能打断限制次数,每次打断都会减少次数,并且开启一个协程等待恢复技能打断次数。本系统的逻辑为第一次打断开始计时,时间到了就恢复次数,不论重置前使用多少次,也不会向后推延倒计时。

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
/// <summary>
/// 检测连招是否成功
/// </summary>
/// <param name="isRoot"></param>
/// <returns></returns>
private ComboState CheckSkillKey(bool isRoot)
{
if (Input.anyKeyDown)
{

if (isRoot)
{
if (_curSkill != null)
{
//存在最近技能,并且从技能起手式开始检测 该情况为打断检测
for (int i = 0, len = _skills.Count; i < len; i++)
{
SkillTree skill = _skills[i];
if (skill.isCanForceStop && skill.forceTimes > 0 && Input.GetKeyDown(skill.key))
{
Debug.Log("打断并强制开始连招" + skill.key);

StopCoroutine(_skillCo);

if (skill.name != _curSkill.name)
{
_curSkill.isRunSkill = false;
//_curSkill.forceTimes = _curSkill.defaultForceTimes;
}
_curSkill = skill;
--_curSkill.forceTimes;

bool reset;
_forceReset.TryGetValue(_curSkill.id, out reset);
if (!reset)
{
StartCoroutine(WaitForForceTimesReset(_curSkill));
}

return ComboState.Success;
}
}
}
else
{
//查找连招起手式
for (int i = 0, len = _skills.Count; i < len; i++)
{
SkillTree skill = _skills[i];
if (Input.GetKeyDown(skill.key))
{
Debug.Log("开始连招" + skill.key);
_curSkill = skill;
return ComboState.Success;
}
}
}
}
else
{
//检测连招分支
for (int i = 0, len = _curSkill.next.Count; i < len; i++)
{
SkillTree skill = _curSkill.next[i];
if (Input.GetKeyDown(skill.key))
{
//连招成功
_curSkill = _curSkill.next[i];
return ComboState.Success;
}
}

//连错招 重置
Debug.Log("连招重置");
return ComboState.Wrong;
}
}

return ComboState.Fail;
}

状态切换

Idle

待机状态,这个状态为初始状态,负责接收技能的起手式按键。如果玩家按下的按键是某一技能的起手式,那么当前状态就置为 Running、Holding 和 Charging 中的一种(根据技能树设置)。

Running

技能执行状态,这个状态负责执行技能等待协程和技能打断判定。

该状态会开启一次技能等待协程,重置技能时间。该状态下会持续增加技能等待时间。技能等待协程执行完毕会自动切换为 Waiting 状态并且重置技能的执行状态。

如果技能打断成功,则我们就重置输入间隔时间。由于这个时候技能变为了新的,因此会重新执行一次上述行为。

Holding

长按技能状态,按住按键技能就一直释放,按键放下就结束并转为 Waiting 状态。

该状态持续增加长按时间,一旦键位不再持续输入或者超过最大持续时间,就会置状态为 Waiting。考虑到按键一松开就会结束长按状态,因此这个状态没有判断技能打断。

Charging

蓄力状态,按住按键技能开始蓄力,按键放下就结束并转为 Idle 状态。

该状态持续增加蓄力时间,一旦键位停止输入,则打断蓄力。由于蓄力未完成,连招中断,因此进入 Idle 状态。考虑到按键一松开就会结束蓄力状态,所以这个状态没有判断技能打断。

当蓄力时间超过技能所需时间,则转换为 Running 状态,执行 Running 状态的技能释放,这时候和普通点按技能释放的效果一样。

总的来说,蓄力技能就是在技能释放状态之前,增加了一个蓄力过程,其他和点按技能一致。

Waiting

等待状态,负责技能连招之间的等待输入。该状态下每帧都会增加输入间隔时间,如果输入间隔时间小于技能最大的连招等待时间,并且玩家有输入操作的情况下,就开始判定连招。

连招正确的情况下,重置输入间隔时间,改变连招状态为 Running;连招错误的情况下,判断是否有对应按键的起手式,有就立刻转为新的连招并改变状态为 Running,否则就置为 Idle。

超时的情况下,重置输入间隔时间,并置 Idle。

状态执行

根据各个状态执行对应的功能即可。该部分只负责实现,不参与控制。

代码

技能树
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
using System.Collections.Generic;
using UnityEngine;


public class SkillTree
{
/// <summary>
/// 技能名称
/// </summary>
public string name { get; set; }
/// <summary>
/// 技能id 一系列技能使用同一id
/// </summary>
public int id { get; set; }
/// <summary>
/// 键位需求
/// </summary>
public KeyCode key { get; set; }
/// <summary>
/// 下一连招列表
/// </summary>
public List<SkillTree> next { get; set; }
/// <summary>
/// 技能持续时间
/// </summary>
public float skillTime { get; set; }
/// <summary>
/// 是否正在释放技能
/// </summary>
public bool isRunSkill { get; set; }
/// <summary>
/// 连招超时时间
/// </summary>
public float outOfTime { get; set; }
/// <summary>
/// 是否可以强制打断技能
/// </summary>
public bool isCanForceStop { get; set; }
/// <summary>
/// 强制打断次数
/// </summary>
public int forceTimes { get; set; }
/// <summary>
/// 默认强制打断次数
/// </summary>
public int defaultForceTimes { get; set; }
/// <summary>
/// 强制打断重置时间
/// </summary>
public float forceResetTime { get; set; }
/// <summary>
/// 技能类型
/// </summary>
public SkillType skillType { get; set; }
/// <summary>
/// 长按/蓄力时间
/// </summary>
public float holdingTime { get; set; }
/// <summary>
/// 进度条颜色
/// </summary>
public Color progressColor { get; set; }

public SkillTree() {
skillType = SkillType.Click;
progressColor = Color.white;
next = new List<SkillTree>();
}
}

连招控制
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
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.UI;

public class ComboScript : MonoBehaviour
{
/// <summary>
/// 连招状态
/// </summary>
private State _state;
/// <summary>
/// 技能列表
/// </summary>
private List<SkillTree> _skills = new List<SkillTree>();
/// <summary>
/// 当前技能
/// </summary>
private SkillTree _curSkill;
/// <summary>
/// 输入间隔
/// </summary>
private float _inputDelta = 0;
/// <summary>
/// 输入间隔进度条控件
/// </summary>
private RectTransform _skillProgress = null;
/// <summary>
/// 输入间隔进度条图像
/// </summary>
private Image _skillImage;
/// <summary>
/// 技能进度条控件
/// </summary>
private RectTransform _runProgress = null;
/// <summary>
/// 技能进度条图像
/// </summary>
private Image _runImage;
/// <summary>
/// 技能执行时间
/// </summary>
private float _skillTime = 0;
/// <summary>
/// 长按时间
/// </summary>
private float _holdingTime = 0;

private Dictionary<int, bool> _forceReset = new Dictionary<int, bool>();

private Coroutine _skillCo;

private Action _onIdle;

private Action _onRunning;

private Action _onHolding;

private Action _onCharging;

private Action _onWaiting;

void Start()
{
//获取UI
_skillProgress = GameObject.FindGameObjectWithTag("Player").GetComponent<RectTransform>();
_skillProgress.sizeDelta = new Vector2(0, 30);
_skillImage = GameObject.FindGameObjectWithTag("Player").GetComponent<Image>();

_runProgress = GameObject.FindGameObjectWithTag("Finish").GetComponent<RectTransform>();
_runProgress.sizeDelta = new Vector2(0, 30);
_runImage = GameObject.FindGameObjectWithTag("Finish").GetComponent<Image>();

DoChangeState(State.Idle);
}

// Update is called once per frame
void Update()
{
ChangeState();
}

private void OnGUI()
{
if (_curSkill != null)
{
if (_inputDelta == 0)
{
if (_skillProgress.sizeDelta.x != 0)
{
_skillProgress.sizeDelta = new Vector2(0, 30);
}
}
else
{
float ratio = (_curSkill.outOfTime - _inputDelta) / _curSkill.outOfTime;
if (ratio < 0)
{
ratio = 0;
}
_skillProgress.sizeDelta = new Vector2(ratio * 100, 30);
_skillImage.color = _curSkill.progressColor;
}

if (_skillTime == 0)
{
if (_runProgress.sizeDelta.x != 0)
{
_runProgress.sizeDelta = new Vector2(0, 30);
}
}
else
{
float total = _curSkill.skillTime;
if (_curSkill.skillType == SkillType.Charge && _state == State.Charging)
{
total = _curSkill.holdingTime;
}
if (total - _skillTime >= 0)
{
float skillRatio = (total - _skillTime) / total;
_runProgress.sizeDelta = new Vector2(skillRatio * 100, 30);
_runImage.color = _curSkill.progressColor;
}
else
{
_runProgress.sizeDelta = new Vector2(0, 30);
}
}
}
else
{
if (_skillProgress.sizeDelta.x != 0)
{
_skillProgress.sizeDelta = new Vector2(0, 30);
}

if (_runProgress.sizeDelta.x != 0)
{
_runProgress.sizeDelta = new Vector2(0, 30);
}
}
}

/// <summary>
/// 改变状态
/// </summary>
private void ChangeState()
{
switch (_state)
{
case State.Idle:
_curSkill = null;
//起始技能检测
if (CheckSkillKey(true) == ComboState.Success)
{
DoChangeState(CheckSkillType(_curSkill.skillType));
}
break;
case State.Running:
//等待技能执行
if (!_curSkill.isRunSkill)
{
Debug.Log("执行技能 === " + _curSkill.name + ":" + _curSkill.skillTime);
_curSkill.isRunSkill = true;
_skillCo = StartCoroutine(WaitForSkill());
}
_skillTime += Time.deltaTime;
//检测强制打断
if (CheckSkillKey(true) == ComboState.Success)
{
//_inputDelta = 0;
DoChangeState(State.Running);
}
break;
case State.Holding:
_holdingTime += Time.deltaTime;
_skillTime += Time.deltaTime;
if (_holdingTime > _curSkill.holdingTime || !Input.anyKey)
{
Debug.Log("超时或没有长按");
DoChangeState(State.Waiting);
}
else
{
Debug.Log("执行长按技能 === " + _curSkill.name);
}
break;
case State.Charging:
_holdingTime += Time.deltaTime;
_skillTime += Time.deltaTime;
if (Input.anyKey)
{
if (_holdingTime > _curSkill.holdingTime)
{
Debug.Log("蓄力完成");
DoChangeState(State.Running);
}
else
{
Debug.Log("蓄力 === " + _curSkill.name);
}
}
else
{
Debug.Log("停止蓄力");
DoChangeState(State.Idle);
}

break;
case State.Waiting:
//等待中增加间隔时间
_inputDelta += Time.deltaTime;
//连击时间小于技能最大间隔时间
if (_inputDelta <= _curSkill.outOfTime)
{
//连击时间内检测
ComboState res = CheckSkillKey(false);
if (res == ComboState.Success)
{
//连招成功
DoChangeState(CheckSkillType(_curSkill.skillType));
Debug.Log("连招成功");
}
else if (res == ComboState.Wrong)
{
//连招错误 此处选择立即执行当前连招指令 也可以不执行,放下一帧再判断
if (CheckSkillKey(true) == ComboState.Success)
{
//如果有招,直接转为别的连招
DoChangeState(CheckSkillType(_curSkill.skillType));
Debug.Log("转换连招");
}
else
{
//没有别的连招 状态重置
DoChangeState(State.Idle);
Debug.Log("没有新连招");
}
}
}
else
{
//超时重置
DoChangeState(State.Idle);
}
break;
}
}

private State CheckSkillType(SkillType type)
{
switch (type)
{
case SkillType.Click:
return State.Running;
case SkillType.Hold:
return State.Holding;
case SkillType.Charge:
return State.Charging;
}
return State.Running;
}

/// <summary>
/// 执行状态
/// </summary>
private void DoStatus()
{
switch (_state)
{
case State.Idle:
//RunIdle
if (_onIdle != null)
{
_onIdle();
}
break;
case State.Running:
//RunSkill
if (_onRunning != null)
{
_onRunning();
}
break;
case State.Holding:
//HoldingSkill
if (_onHolding != null)
{
_onHolding();
}
break;
case State.Charging:
//HoldingSkill
if (_onCharging != null)
{
_onCharging();
}
break;
case State.Waiting:
//RunWaiting
if (_onWaiting != null)
{
_onWaiting();
}
break;
}
}

private void DoChangeState(State state)
{
_state = state;
_inputDelta = 0;
_skillTime = 0;
_holdingTime = 0;
DoStatus();
Debug.Log("重置计数器");
}

/// <summary>
/// 检测连招是否成功
/// </summary>
/// <param name="isRoot"></param>
/// <returns></returns>
private ComboState CheckSkillKey(bool isRoot)
{
if (Input.anyKeyDown)
{

if (isRoot)
{
if (_curSkill != null)
{
//存在最近技能,并且从技能起手式开始检测 该情况为打断检测
for (int i = 0, len = _skills.Count; i < len; i++)
{
SkillTree skill = _skills[i];
if (skill.isCanForceStop && skill.forceTimes > 0 && Input.GetKeyDown(skill.key))
{
Debug.Log("打断并强制开始连招" + skill.key);

StopCoroutine(_skillCo);

if (skill.name != _curSkill.name)
{
_curSkill.isRunSkill = false;
//_curSkill.forceTimes = _curSkill.defaultForceTimes;
}
_curSkill = skill;
--_curSkill.forceTimes;

bool reset;
_forceReset.TryGetValue(_curSkill.id, out reset);
if (!reset)
{
StartCoroutine(WaitForForceTimesReset(_curSkill));
}

return ComboState.Success;
}
}
}
else
{
//查找连招起手式
for (int i = 0, len = _skills.Count; i < len; i++)
{
SkillTree skill = _skills[i];
if (Input.GetKeyDown(skill.key))
{
Debug.Log("开始连招" + skill.key);
_curSkill = skill;
return ComboState.Success;
}
}
}
}
else
{
//检测连招分支
for (int i = 0, len = _curSkill.next.Count; i < len; i++)
{
SkillTree skill = _curSkill.next[i];
if (Input.GetKeyDown(skill.key))
{
//连招成功
_curSkill = _curSkill.next[i];
return ComboState.Success;
}
}

//连错招 重置
Debug.Log("连招重置");
return ComboState.Wrong;
}
}

return ComboState.Fail;
}

/// <summary>
/// 模拟技能执行时间
/// </summary>
/// <returns></returns>
private IEnumerator WaitForSkill()
{
yield return new WaitForSeconds(_curSkill.skillTime);
if (_curSkill != null)
{
DoChangeState(State.Waiting);
_curSkill.isRunSkill = false;
}
}

private IEnumerator WaitForForceTimesReset(SkillTree obj)
{
Debug.Log("开始重置强制打断次数 :" + obj.forceResetTime);
yield return new WaitForSeconds(obj.forceResetTime);
obj.forceTimes = obj.defaultForceTimes;
_forceReset[obj.id] = false;
Debug.Log("重置强制打断次数");
}

/// <summary>
/// 添加技能
/// </summary>
/// <param name="skill"></param>
public void AddSkill(SkillTree skill)
{
_skills.Add(skill);
}

/// <summary>
/// 获取当前技能
/// </summary>
/// <returns></returns>
public SkillTree GetCurSkill()
{
return _curSkill;
}

public void OnIdle(Action callback)
{
_onIdle = callback;
}

public void OnRunning(Action callback)
{
_onRunning = callback;
}

public void OnHolding(Action callback)
{
_onHolding = callback;
}

public void OnCharging(Action callback)
{
_onCharging = callback;
}

public void OnWaiting(Action callback)
{
_onWaiting = callback;
}
}

连招管理类
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
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 连招状态枚举 空闲|执行中|等待
/// </summary>
public enum State
{
Idle,
Running,
Holding,
Charging,
Waiting
}
/// <summary>
/// 连招检测状态枚举 成功|失败|错误
/// </summary>
public enum ComboState
{
Success,
Fail,
Wrong
}

public enum SkillType {
Click,
Hold,
Charge
}

public class ComboManager
{
private static ComboManager _instance = null;

private ComboScript _comboScript;

public static ComboManager Instance()
{
if(_instance == null)
{
_instance = new ComboManager();
}
return _instance;
}

private ComboManager() { }

public void Init()
{
GameObject root = new GameObject();
root.name = "ComboSystem";
_comboScript = root.AddComponent<ComboScript>();

//初始化技能 此处暂时用代码写死
//实例化技能链
//技能A
SkillTree skillA1 = new SkillTree();
skillA1.key = KeyCode.A;
skillA1.name = "连招A1";
skillA1.id = 1;
skillA1.outOfTime = 0.5f;
skillA1.skillTime = 0.5f;
skillA1.progressColor = Color.red;

SkillTree skillA2 = new SkillTree();
skillA2.key = KeyCode.A;
skillA2.name = "连招A2";
skillA2.id = 1;
skillA2.outOfTime = 0.5f;
skillA2.skillTime = 2f;
skillA2.progressColor = new Color(0.8f, 0, 0, 1);
skillA2.skillType = SkillType.Hold;
skillA2.holdingTime = 2;

SkillTree skillA3 = new SkillTree();
skillA3.key = KeyCode.A;
skillA3.name = "连招A3-1";
skillA3.id = 1;
skillA3.outOfTime = 0.5f;
skillA3.skillTime = 0.5f;
skillA3.progressColor = new Color(0.6f, 0, 0, 1);

SkillTree skillA4 = new SkillTree();
skillA4.key = KeyCode.S;
skillA4.name = "连招A3-2";
skillA4.id = 1;
skillA4.outOfTime = 0.5f;
skillA4.skillTime = 0.5f;
skillA4.progressColor = new Color(0.4f, 0, 0, 1);
skillA4.skillType = SkillType.Charge;
skillA4.holdingTime = 2;

skillA1.next.Add(skillA2);
skillA2.next.Add(skillA3);
skillA2.next.Add(skillA4);

_comboScript.AddSkill(skillA1);

//技能B
SkillTree skillB1 = new SkillTree();
skillB1.key = KeyCode.B;
skillB1.name = "连招B1";
skillB1.id = 2;
skillB1.outOfTime = 0.5f;
skillB1.skillTime = 0.5f;
skillB1.isCanForceStop = true;
skillB1.forceTimes = 1;
skillB1.defaultForceTimes = 1;
skillB1.forceResetTime = 5;
skillB1.progressColor = Color.green;

SkillTree skillB2 = new SkillTree();
skillB2.key = KeyCode.B;
skillB2.name = "连招B2";
skillB2.id = 2;
skillB2.outOfTime = 0.5f;
skillB2.skillTime = 10f;
skillB2.progressColor = new Color(0, 0.8f, 0, 1);

skillB1.next.Add(skillB2);
_comboScript.AddSkill(skillB1);

Debug.Log("初始化完成");
}

/// <summary>
/// 获得当前技能
/// </summary>
/// <returns></returns>
public SkillTree GetCurSkill()
{
return _comboScript.GetCurSkill();
}

/// <summary>
/// Idle函数
/// </summary>
/// <param name="callback"></param>
public void OnIdle(Action callback)
{
_comboScript.OnIdle(callback);
}

/// <summary>
/// Running函数
/// </summary>
/// <param name="callback"></param>
public void OnRunning(Action callback)
{
_comboScript.OnRunning(callback);
}

/// <summary>
/// Holding函数
/// </summary>
/// <param name="callback"></param>
public void OnHolding(Action callback)
{
_comboScript.OnHolding(callback);
}

/// <summary>
/// Charging函数
/// </summary>
/// <param name="callback"></param>
public void OnCharging(Action callback)
{
_comboScript.OnCharging(callback);
}

/// <summary>
/// Waiting函数
/// </summary>
/// <param name="callback"></param>
public void OnWaiting(Action callback)
{
_comboScript.OnWaiting(callback);
}
}

评论