做个简单的公告栏

简介

该博客通过使用Unity自带的UI系统以及碰撞盒实现一个简单的公告栏。

对象处理

制作思路是这样的,当点击按钮时,公告就会弹出,然后因为他们都有碰撞盒的属性,所以他们会互相排斥,从而达到一个展开的效果。再次点击时,则需要复原,这里就通过获取公告栏展开的情况来通过Update函数来更新位置。
先生成一个Canvas
这里写图片描述
大概就是这样,Panel用来搭载背景,Button就是用来实现按钮功能,Image用来放公告内容,而Panel(1)用来存放整个公告栏,Main对象用来挂载Button的控制器。
给每一个Image加入碰撞盒和刚体的挂件,使得它能被挤开。
这里写图片描述
注意,碰撞盒的大小跟物体一样大或者大一点,否则碰撞的判定就只有一个点了。
Button加入碰撞盒挂件。
这里写图片描述
注意点跟上面一样。

代码部分

先生成一个BoardManager.cs来控制Button,挂在Main对象上面

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Events;
using UnityEngine.UI;

public class BoardManager : MonoBehaviour {
    public GameObject Panel;
    public void Controller(GameObject obj) {  
        bool button = obj.GetComponent<Board>().Button;  
        button = !button;  
        obj.GetComponent<Board>().Button = button;  
        obj.SetActive(button);
    }

    void Start () {
        List<string> btnsName = new List<string>();
        btnsName.Add("Button1");
        btnsName.Add("Button2");
        btnsName.Add("Button3");

        foreach(string btnName in btnsName) {
            GameObject btnObj = GameObject.Find(btnName);
            Button btn = btnObj.GetComponent<Button>();
            btn.onClick.AddListener(delegate() {
                this.OnClick(btnObj); 
            });
        } 
    }

    public void OnClick(GameObject sender) {
        GameObject Image;
        switch (sender.name) {
        case "Button1":
            Image = Panel.transform.Find("Image1").gameObject;
            Controller (Image);
            break;
        case "Button2":
            Image = Panel.transform.Find("Image2").gameObject;
            Controller (Image);
            break;
        case "Button3":
            Image = Panel.transform.Find("Image3").gameObject;
            Controller (Image);
            break;
        default:
            break;
        }
    }
}  

这里我给每一个按钮都加入了一个监听器,去监听按钮的情况。假如被选中的话,就显示对应的公告。这里需要注意的一点是,我是通过设置active来设置公告的隐藏和显示的,但问题是,一旦一个对象的active被设为false,那么find函数就会找不到他,这里给出的处理方法是,获得它的父对象,然后通过查询子对象的形式获得它,这个方式应该也是最常用的一种方法。
然后给每一个Image挂一个board.cs,用来记录它的active情况。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Events;
using UnityEngine.UI;

public class Board : MonoBehaviour {
    public bool Button=false;
}

再是每一个Button的代码:
Button1不需要移动,但他必须保证Image与它的相对位置相同。
Button1_Move.cs

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Events;
using UnityEngine.UI;

public class Button1_Move : MonoBehaviour {  
    public GameObject Panel;  
    private float cur_x = 0; 
    private float cur_y = 140;  
    void Update() {
        Panel.transform.Find("Image1").gameObject.GetComponent<RectTransform>().localPosition = new Vector3(cur_x, cur_y - 55, 0);
    }
}  

而Button2跟Button3则需要回弹,所以要遍历回弹的距离以及公告的跟随。
Button2_Move.cs

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Events;
using UnityEngine.UI;

public class Button2_Move : MonoBehaviour {  
    public GameObject Panel;
    private float x = 0; 
    private float y = 85;
    private float cur_x;
    private float cur_y; 

    void Start() {  
        cur_x = x;  
        cur_y = y;
    }  

    void Update() {  
        if (Panel.transform.Find("Image1").gameObject.activeSelf == false) Back();//回退
        Panel.transform.Find("Image2").gameObject.GetComponent<RectTransform>().localPosition = new Vector3(cur_x, cur_y - 55, 0);//公告跟随
    }

    void Back() {
        GetComponent<RectTransform>().localPosition = new Vector3(x, y, 0);//返回  
        cur_y = y;//更新
    }

    void OnCollisionEnter2D(Collision2D coll) {
        RectTransform coll_Tranform = coll.gameObject.GetComponent<RectTransform>();  
        GetComponent<RectTransform>().localPosition = new Vector3(x, y - coll_Tranform.sizeDelta.y, 0);//移动一个公告的高度
        cur_y = y - coll_Tranform.sizeDelta.y;//更新
    }  
}  

Button3_Move.cs

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Events;
using UnityEngine.UI;

public class Button3_Move : MonoBehaviour {  

    public GameObject Panel;  
    private float cur_x;  
    private float cur_y;
    private float x = 0;  
    private float y = 30;  
    private float x1 = 0;  
    private float y1 = -20;  

    void Start() {  
        cur_x = x;  
        cur_y = y;  
    }  

    void Update() {
        if (Panel.transform.Find ("Image1").gameObject.activeSelf != Panel.transform.Find ("Image2").gameObject.activeSelf)
            Back2 ();
        if (Panel.transform.Find("Image1").gameObject.activeSelf == false) {  
            if (Panel.transform.Find("Image2").gameObject.activeSelf == false) Back1();  
        }
        Panel.transform.Find("Image3").gameObject.GetComponent<RectTransform>().localPosition = new Vector3(cur_x, cur_y - 55, 0);//实时更新Image3,保证Image3在Button3下方  
    }  

    void Back1() {  
        GetComponent<RectTransform>().localPosition = new Vector3(x, y, 0);  
        cur_y = y;
    }  

    void Back2() {  
        GetComponent<RectTransform>().localPosition = new Vector3(x1, y1, 0);  
        cur_y = y1;
    }  

    void OnCollisionEnter2D(Collision2D coll) {  
        RectTransform coll_Tranform = coll.gameObject.GetComponent<RectTransform>();
        GetComponent<RectTransform> ().localPosition = new Vector3 (cur_x, cur_y - coll_Tranform.sizeDelta.y, 0);
        cur_y = cur_y - coll_Tranform.sizeDelta.y;
    }  
}

至于剩下背景图片什么的,都需要自己去找啦。
效果如下:
这里写图片描述
还算可以吧。。有空的话,就再改改。
这次就到这里啦。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值