如何不绑定脚本且不继承MonoBehaviour做U3D的开发
要点:我们把脚本绑在对象上为什么不把对象抓到脚本里殴打呢?
问题:那不继承Mono的话,协同以及实例化,以及每帧运算该怎么去做呢?
最近看到一个做技能冷却的话题,所以也想去尝试一下。
1.这是界面2D和3D摄像机
2.这是对象排布
3.代码
(1)主要负责UI的界面
[AppleScript] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
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
|
<
font
color
=
"#696969"
>
<
font
color
=
"#333333"
>
<
font
style
=
"color:rgb(51, 51, 51)"
>
using
Assets.Classes.com.system;
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
UnityEngine;
namespace Assets.Classes.com.
view
.ui
{
enum SKILLTYPE
{
Q_SKILL
=
10
,
/
/
→_→代表该技能的冷却时间
W_SKILL
=
20
,
E_SKILL
=
30
,
R_SKILL
=
100
}
class
SkillsMenu_UI
{
private SKILLTYPE skillType;
/
/
技能类型
private bool isSkill
=
false
;
/
/
是否正在释放技能
private bool isCooling
=
false
;
/
/
是否正在冷却
private float coolingTime;
/
/
冷却时间
private GameObject currentObj;
public SkillsMenu_UI
(
GameObject skillsObj
)
{
/
/
GameObject go
=
(
GameObject
)
GameObject.Instantiate
(
skillsObj
)
;
/
/
new
PanelHandler
(
)
.RootHandler
(
skillsObj
)
;
HandlerListener
(
"Q_Skill"
,
skillsObj
)
;
HandlerListener
(
"W_Skill"
,
skillsObj
)
;
HandlerListener
(
"E_Skill"
,
skillsObj
)
;
HandlerListener
(
"R_Skill"
,
skillsObj
)
;
}
private void HandlerListener
(
string
skillName
,
GameObject go
)
{
Transform Skill
=
go.transform.FindChild
(
skillName
)
;
UIEventListener.Get
(
Skill.gameObject
)
.onClick
=
OnClick;
}
private void OnClick
(
GameObject go
)
{
Debug.Log
(
"点击了技能按钮 : "
+
go.
name
)
;
switch
(
go.
name
)
{
case
"Q_Skill"
:
skillType
=
SKILLTYPE.Q_SKILL; HandlerSkill
(
skillType
,
go
)
; break;
case
"W_Skill"
:
skillType
=
SKILLTYPE.W_SKILL; HandlerSkill
(
skillType
,
go
)
; break;
case
"E_Skill"
:
skillType
=
SKILLTYPE.E_SKILL; HandlerSkill
(
skillType
,
go
)
; break;
case
"R_Skill"
:
skillType
=
SKILLTYPE.R_SKILL; HandlerSkill
(
skillType
,
go
)
; break;
}
}
private void HandlerSkill
(
SKILLTYPE type
,
GameObject go
)
{
if
(
!isCooling || !isSkill
)
/
/
是否冷却或者是否有技能没有释放
{
currentObj
=
go;
skillType
=
type;
isSkill
=
true
;
isCooling
=
true
;
HandlerCoolingTimer
(
type
)
;
Debug.Log
(
"可以释放该技能了"
)
;
}
else
{
Debug.Log
(
"不可释放技能"
)
;
}
}
private void HandlerCoolingTimer
(
SKILLTYPE type
)
{
coolingTime
=
(
float
)
type;
currentObj.transform.FindChild
(
"Fore"
)
.gameObject.GetComponent
<
UISprite
>
(
)
.fillAmount
=
1
;
GameController.getInstance
(
)
.addInterval
(
TimerCutting
)
;
Debug.Log
(
"开始倒计时"
)
;
}
private void TimerCutting
(
float t
)
{
currentObj.transform.FindChild
(
"Fore"
)
.gameObject.GetComponent
<
UISprite
>
(
)
.fillAmount
-
=
(
1.0
f
/
coolingTime
)
*
Time.deltaTime;
float tempTime
=
currentObj.transform.FindChild
(
"Fore"
)
.gameObject.GetComponent
<
UISprite
>
(
)
.fillAmount;
Debug.Log
(
"------------coolingTime : "
+
tempTime
)
;
if
(
tempTime
<
=
0.0
1
f
)
{
isSkill
=
false
;
isCooling
=
false
;
GameController.getInstance
(
)
.removedInterval
(
TimerCutting
)
;
}
}
}
}
<
/
font
>
<
/
font
>
<
/
font
>
|
设计思想:外界需要处理这个界面的时候,只需要声明对象new 这个类的有参构造函数即可,然后默认进行一系列初始化动作。
这个是替代自带的OnClick()事件,采用事件事件监听机制。
其他略。
(2)
如果我需要每帧去计算的要求我该怎么办?
那就写一个可以控制全局的每帧运算。
[AppleScript] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
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
|
<
font
color
=
"#696969"
>
/
*
[
/
color][
/
p]
*
游戏主循环
*
/
private static GameController m_instance;
List
<
Action
<
float
>
>
intervalCallFuns;
public void mainLoop
(
)
{
interval
(
Time.deltaTime
)
;
}
public void interval
(
float t
)
{
List
<
Action
<
float
>
>
tempIntervalCallFuns
=
intervalCallFuns;
foreach
(
Action
<
float
>
intervalCallFun
in
tempIntervalCallFuns
)
{
intervalCallFun
(
t
)
;
}
tempIntervalCallFuns
=
null;
}
/
*
*
添加每帧回调
*
@param
:
需要回调的函数
*
/
public void addInterval
(
Action
<
float
>
callFun
)
{
if
(
!intervalCallFuns.Equals
(
callFun
)
)
{
intervalCallFuns.Add
(
callFun
)
;
}
else
{
Debug.LogWarning
(
"add interval already exists!"
)
;
}
}
/
*
*
移除每帧回调函数
*
@param
:
需要移除的回调函数
*
/
public void removedInterval
(
Action
<
float
>
callFun
)
{
List
<
Action
<
float
>
>
tempIntervalCallFuns
=
new
List
<
Action
<
float
>
>
(
)
;
foreach
(
Action
<
float
>
tempFun
in
intervalCallFuns
)
{
if
(
tempFun !
=
callFun
)
tempIntervalCallFuns.Add
(
tempFun
)
;
}
intervalCallFuns
=
tempIntervalCallFuns;
tempIntervalCallFuns
=
null;
}
<
/
font
>
|
设计思想:这个类用字典去存储需要进行每帧运算的函数,然后默认去每帧遍历,并带有从字典中移除函数的功能。
(3)启动程序,启动游戏主循环。
Main类挂在一个GameObject上,负责游戏启动,只负责游戏的主循环,不管其他的操作。
[AppleScript]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
|
<
font
style
=
"color:rgb(51, 51, 51)"
>
using
UnityEngine;
public
class
Main
:
MonoBehaviour
{
void Start
(
)
{
}
void Update
(
)
{
GameController.getInstance
(
)
.mainLoop
(
)
;
}
}
<
/
font
>
|
test.cs在他需要的时候去new SkillsMenu_UI(Skills对象)。
new SkillsMenu_UI(gameObject.transform.FindChild(“Skills”).gameObject);
整个程序就可完美启动起来。
总结,这样的设计多用于解耦和模块的划分。
不用频繁绑定脚本,给public对象绑定对象,一些都在代码中完成。