简介
该博客通过使用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;
}
}至于剩下背景图片什么的,都需要自己去找啦。
效果如下:
还算可以吧。。有空的话,就再改改。
这次就到这里啦。