Unity3D自定义按钮—OnGUI

本文详细介绍了在塔防游戏中如何自定义按钮,包括创建GUIButton类、设置状态、缩放、激活状态等,以及如何在游戏场景中应用这些自定义按钮来创建防守单位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

接下来我们将创建一个自定义的按钮,虽然使用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 = newVector3(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); 
   
                returnm_ID; 
            }
            else
                SetState(StateID.FOCUS); 
   
        }
        else
        {
            if(m_isOnActiv)
                SetState(StateID.ACTIV); 
            else
                SetState(StateID.NORMAL); 
        }
   
        returnresult; 
    }
   
    // 设置按钮状态 
    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 = newRect(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 = newRect(m_screenPosition.x, m_screenPosition.y, w, h); 
    }
        
// 设置激活状态 
    public virtual void SetOnActiv(bool isactiv)
    {
        if(isactiv)
            SetState(StateID.ACTIV); 
        elseif (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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值