先說一下爲什麼要說是小貼士系統,因爲這個東西是額外功能,雖然你可以說它附屬於其他UI等模塊,但是確是獨立於他們的,另一方面做成一個單獨系統也是爲了擴展性。畢竟這個可複雜,也可簡單。
我們這個表現形式爲 上滾 顯示一條,隨機輪播,而且要保證我所有的提示都顯示一遍之後再循環。
首先,實現滾動的方式是很多的,這裏還是採用unity自帶的系統 ScrollRect ,可以百度,有很多關於這個使用教程,我的思路是控制它的verticalNormalizedPosition,因爲這個值有兩個臨街狀態,0代表的是顯示框下底重合遮罩下底,1代表顯示框上底重合遮罩上底,那我就可以控制它的值來實現移動
public class ScrollRectCtr : MonoBehaviour
{
public ScrollRect rect;
private float Speed = 1;
private Action onComplete;
/// <summary>
/// 開始漂浮
/// </summary>
/// <param name="speed"></param>
/// <param name="onend"></param>
public void StartFloat(float speed,Action onend)
{
Speed = speed;
onComplete = onend;
}
// Update is called once per frame
void Update()
{
if (rect.verticalNormalizedPosition > 0.1f)
{
rect.verticalNormalizedPosition -= Time.deltaTime * Speed;
}else
{
if(onComplete !=null)
{
onComplete.Invoke();
onComplete = null;
}
rect.verticalNormalizedPosition = 1;
rect.enabled = false;
}
}
}
當我移動到0了之後,要進行重置爲1,這裏有不同坐法,可以將上部的哪個設置排序位,讓他在當前顯示的下方,或者把他挪走,設置到其他物體下,然後在放下一個要展示的在當前的下方,我採用 的是第二個。所以要在回到執行後在設置爲1,因爲這時候顯示框下有兩個,一個是當前顯示的,一個是下次要展示的。
到這就實現了滑動輪播,然後是隨機展示和去重,這裏方法也很多,結合我上邊的選擇,我採用 將所有要展示的都先存在一個隱藏的空物體下邊,每次展示過的都設置它下邊,最後一位,然後頂一個額int值來標記當前還沒展示的物體的最大位置,然後隨機一個,再講這個int值-1,因爲位於該值後邊的都是展示過的,所以科研保證不會在其他沒展示的出現之前出現。
/// <summary>
/// 小貼士系統
/// </summary>
public class ShowTip : MonoBehaviour
{
public ScrollRectCtr srCtr;//滾屏控制器
public VerticalLayoutGroup Grid;//存放展示物品的格子
public float WaitTime = 4;//每個間隔
public Transform HasShowed;//存放要展示的
public int Index;//當前展示的標誌位 位於該值後的是展示過的
private float usedTime = 0;//計時
private void Start()
{
Index = HasShowed.childCount;
}
/// <summary>
/// 展示小貼士
/// </summary>
public void Show()
{
gameObject.SetActive(true);
usedTime = 0;
if (Index < 0)
{
Index = HasShowed.childCount;//循環
}
int index = Random.Range(0, Index);//從當前剩餘的裏邊隨機一個來展示
Index--;
Debug.Log(index);
srCtr.enabled = true;
srCtr.StartFloat(1,()=>
{
Debug.Log("guiwei-------------------- "+index );
Transform target = HasShowed.GetChild(index);
target.SetParent(Grid.transform);
Grid.enabled = true;//啓用排序
//把上次展示的歸位
Grid.transform .GetChild(0).SetParent(HasShowed);
srCtr.enabled = false;
});
}
/// <summary>
/// 停止展示S
/// </summary>
public void Stop()
{
gameObject.SetActive(false);
}
private void Update()
{
if(usedTime <WaitTime)
{
usedTime += Time.deltaTime;
}else
{
Show();
}
}
}
資源工程圖如下;
這樣就可以了,效果還是很不錯,性能也不是很浪費,你值得一試!