我們經常可以看到,遊戲中會有消息列表這樣一個彈框,我們可以很自然聯想到用scrollview來實現,但如何實現動態生成一條一條的消息記錄呢?很簡單,預製體(prefab)
首先感謝這位大神的文章給予我的啓發以及他的腳本代碼:http://www.unity.5helpyou.com/3193.html
這我所做的消息框實現效果:
okay,首先我們需要創建消息框主體scrollview,這裏有幾點需要注意:
1.我們都知道消息列表都是可以上下滑動,因此把橫向移動取消勾選,當然如果你橫向移動的需求這條就不必了
2.scrollview的content需要和界面等寬,它的rect transform需要如下設置:
這樣可以保證在不同分辨率下的正常顯示,還是我們代碼動態控制content大小的一大保證
要動態生成物體,prefab無疑是最好的選擇,接下來我們需要製作消息列表中的列表項,然後將它製作成預製體,以下的我做的預製體:
這裏要注意這個列表項需要有剛體控件,否則在動態生成時會造成無法顯示的後果(content最好也加上這一控件)
做完這些就該爲它添加腳本了,這裏我把代碼放出來供大家參考(c#):
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
public class initMessage : MonoBehaviour {
List<GameObject> messages = new List<GameObject>();
public GameObject item;
GameObject myMessage;
GameObject parent;
Vector3 itemLocalPos;
Vector2 contentSize;
float itemHeight;
void Start()
{
parent = GameObject.Find("Content");
contentSize = parent.GetComponent<RectTransform>().sizeDelta;
itemHeight = item.GetComponent<RectTransform>().rect.height;
itemLocalPos = item.transform.localPosition;
for(int i = 0; i < 8; i++){
AddItem ();
}
}
//添加列表項
public void AddItem()
{
GameObject a = Instantiate(item) as GameObject;
a.transform.FindChild ("Text").GetComponent<Text> ().text = "asd";
a.transform.FindChild ("cancel").GetComponent<Button> ().onClick.AddListener(
delegate() {
RemoveItem(a);
}
);
a.GetComponent<Transform>().SetParent(parent.GetComponent<Transform>(),false);
a.transform.localPosition = new Vector3(itemLocalPos.x, itemLocalPos.y - messages.Count * itemHeight, 0);
messages.Add(a);
if (contentSize.y <= messages.Count * itemHeight)//增加內容的高度
{
parent.GetComponent<RectTransform>().sizeDelta = new Vector2(contentSize.x, messages.Count * itemHeight);
}
}
//移除列表項
public void RemoveItem(GameObject t)
{
int index = messages.IndexOf(t);
messages.Remove(t);
Destroy(t);
for (int i = index; i < messages.Count; i++)//移除的列表項後的每一項都向前移動
{
messages[i].transform.localPosition += new Vector3(0, itemHeight, 0);
}
if (contentSize.y <= messages.Count * itemHeight)//調整內容的高度
parent.GetComponent<RectTransform>().sizeDelta = new Vector2(contentSize.x, messages.Count * itemHeight);
else
parent.GetComponent<RectTransform>().sizeDelta = contentSize;
}
public void CancleOnClick(){
RemoveItem (this.gameObject);
}
}