Unity3D自定义按钮—OnGUI

在塔防游戏中,防守单位都是动态创建的,通常游戏中将提供若干个按钮,当选中其中一个按钮后,这个按钮将保持激活状态,这时在场景中选择位置按下鼠标,即可创建一个防守单位,同时也会扣除一些用于创建防守单位的资金或点数。

接下来我们将创建一个自定义的按钮,虽然使用OnGUI创建按钮更容易,但OnGUI的效率较低,也不利于制作布局复杂或有特殊需求的UI,更难为它制作动画。

1)创建角本GUIButton.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
using UnityEngine; 
using System.Collections; 
   
public class GUIButton : MonoBehaviour  
{
     // 按钮状态 
     protected enum StateID 
     {
         NORMAL=0,   // 正常 
         FOCUS,       //  高亮 
         ACTIV,       //  选中 
     }
     protected StateID m_state = StateID. NORMAL; 
     // 按钮的贴图 
     public Texture[] m_ButtonSkin; 
   
     // 按钮的ID 
     public int m_ID = 0; 
   
     // 按钮是否处于激活状态 
     protected bool m_isOnActiv = false
   
     // 按钮的缩放 
     public float m_scale = 1.0f; 
   
     // 按钮的屏幕位置 
     Vector2 m_screenPosition; 
     
    // 按钮的当前贴图 
     public GUITexture m_texture; 
   
    // 初始化按钮 
     void Awake()
     {
         //  获得贴图 
         m_texture = this .guiTexture; 
   
         // 获得位置 
         m_screenPosition = new Vector3(m_texture.pixelInset.x, m_texture.pixelInset.y, 0); 
   
         // 设置默认状态 
         SetState(StateID.NORMAL); 
     }
   
     //更新按钮状态,选中按钮,返回它的ID 
     public int UpdateState(bool mouse,Vector3 mousepos)
     {
         int result = -1; 
   
         if (m_texture.HitTest(mousepos))
         {
             if (mouse)
             {
                 SetState(StateID.ACTIV); 
   
                 return m_ID; 
             }
             else
                 SetState(StateID.FOCUS); 
   
         }
         else
         {
             if (m_isOnActiv)
                 SetState(StateID.ACTIV); 
             else
                 SetState(StateID.NORMAL); 
         }
   
         return result; 
     }
   
     // 设置按钮状态 
     protected virtual void SetState(StateID state)
     {
         if (m_state == state)
             return
   
         m_state = state; 
   
         m_texture.texture = m_ButtonSkin[(int)m_state]; 
   
         float w = m_ButtonSkin[(int)m_state].width * m_scale; 
         float h = m_ButtonSkin[(int)m_state].height * m_scale; 
   
         m_texture.pixelInset = new Rect( this .m_screenPosition.x, m_screenPosition.y, w, h); 
     }
   
     // 设置按钮缩放 
     public virtual void SetScale(float scale)
     {
         m_scale = scale; 
   
         float w = m_ButtonSkin[0].width * scale; 
         float h = m_ButtonSkin[0].height * scale; 
   
         m_screenPosition.x *= scale; 
         m_screenPosition.y *= scale; 
   
         m_texture.pixelInset = new Rect(m_screenPosition.x, m_screenPosition.y, w, h); 
     }
        
// 设置激活状态 
     public virtual void SetOnActiv(bool isactiv)
     {
         if (isactiv)
             SetState(StateID.ACTIV); 
         else if (m_isOnActiv)
             SetState(StateID.NORMAL); 
   
         m_isOnActiv = isactiv; 
     }
}

在这个脚本中,Awake函数初始化了按钮的状态,按钮一共有三种状态,包括正常、高亮和激活。

在UpdateState函数中,判断是否选中按钮,如果选中,则返回按钮的ID。

SetState函数用来设置按钮的状态,实际上是在更新按钮的贴图。

SetScale函数用来设置按钮的缩放,在手机平台,因为机器设备的分辨率不统一,所以在不同平台对按钮进行相应缩放是必要的。

SetOnActiv函数会将按钮设为激活状态,当按钮处于这种状态,即使鼠标从按钮上移开,按钮的状态也不会改变。

2)在Project窗口的GUI文件夹中找到ui_turret_n.png,确定它处于选择状态,在菜单栏选择【GameObject】→【Create Other】→【GUI Texture】创建一个显示有UI贴图的游戏体,然后为它指定角本GUIButton.cs,在Button Skin中设置对应按钮三种状态的贴图,将按钮的ID设为1,如图4-27所示。

3)我们将不使用3d坐标改变按钮的位置,将按钮的Position设为0,然后将Pixel Inset的X和Y设为5,如图4-27所示,按钮将出现在屏幕坐标(5,5)的位置,如图4-28所示。

4)将按钮命名为button_0,并设为GameManager的子物体,如图4-29所示。

5)打开GameManager.cs,加入按钮等相关属性如下,然后将前面创建的防守单位与m_guardPrefab关联。新建一个名为ground的Layer,将m_groundlayer与其关联。

(此处省略××××××字,包括源代码)

8)将地面的Layer设为ground,使射线可以与地面碰撞。

运行游戏,按一下屏幕上的按钮,然后在地面上点一下,即可创建一个防守单位。

这个塔防游戏到这里就结束了,它还非常简陋,但具备了塔防游戏的基本要素,如果添加更多的细节和更好的画面,相信它可以变成一款不错的游戏。

来自:51cto

你可能感兴趣的:(Unity3d_技术类)