先说一下为什么要说是小贴士系统,因为这个东西是额外功能,虽然你可以说它附属于其他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();
}
}
}
资源工程图如下;
这样就可以了,效果还是很不错,性能也不是很浪费,你值得一试!