Unity3d实现无限循环滚动背景
在游戏项目中我们常常看到商城的广告牌,几张广告图片循环滚动,类似跑马灯,现在我将讨论一种实现方法,并提供一个管理类,大家可以直接使用。
实现原理:背景图片循环滚动的原理很简单:两张图片向一个方向移动,当达某张图片到临界区域时将图片放在后面,依次循环。
在实际项目中,广告牌显示的图片数量不确定,例如某个假期活动会上很多新品,此时我们需要动态的创建显示的图片(一般在配置表读取数据),如果需要显示分类标签还得动态生成分类标签。
综上所述,一个完整的广告牌组件应该具有以下功能:
- 无限循环的滚动背景图片
- 根据读取的数据动态生成图片
- 具有分类标签,根据显示图片动态生成
- *做成一个管理类,方便使用(一个项目中可能多处会用到)
下面谈谈我的方法:
第一步:创建滚动组件AdvertisementScroll,这个组件挂在GameObject上面,接受传递过来的数据,生成显示的图片和分类标签,在Update中实现无限循环滚动。
using System.Collections.Generic; using UnityEngine; namespace Assets.Scripts.Client { public class AdvertisementScroll : MonoBehaviour { private float _timer; private bool _isStart; private Vector3 _toggleCenter; private int delDistance; private int _currentPage; //当前页面 private AdvertisementScrollManager.AdvertisementScrollData _itemData; private List<ToggleData> _toggleList = new List<ToggleData>(); private Vector3 _toLeftPosition;//向左滑动到某个位置 public class ToggleData { public string name; public GameObject go; } public AdvertisementScrollManager.AdvertisementScrollData ItemData { get { return _itemData; } set { _itemData = value; } } public void StartScroll(bool createToggle) { if (!_isStart) { CreateAdvertiseBg(); CreateAdvertiseToggle(createToggle); if (createToggle) { if (ItemData.ToggleItem != null) { ItemData.ToggleItem.GetComponent<UIToggle>().value = true; } } _currentPage = 1; _isStart = true; } } /// <summary> /// 创建需要显示的图片(需要图片数量,图片精灵名称,图片的宽度,图片左边和右边的显示位置) /// </summary> private void CreateAdvertiseBg() { _toLeftPosition = new Vector3(ItemData.LeftPosition.x - ItemData.SpriteWidth, ItemData.LeftPosition.y, ItemData.LeftPosition.z); for (int i = 0; i < ItemData.MaxPage; i++) { GameObject firstSpriteItem; GameObject secondSpriteItem; if (i == 0) { firstSpriteItem = secondSpriteItem = ItemData.SpriteItem.gameObject; } else { firstSpriteItem = ItemData.FirstMoveGo.gameObject.AddChild(ItemData.SpriteItem.gameObject); firstSpriteItem.SetActive(false); secondSpriteItem = ItemData.SecondMoveGo.gameObject.AddChild(ItemData.SpriteItem.gameObject); secondSpriteItem.SetActive(false); } firstSpriteItem.transform.localPosition = secondSpriteItem.transform.localPosition = Vector3.zero; firstSpriteItem.name = secondSpriteItem.name = (i + 1).ToString(); firstSpriteItem.GetComponent<UISprite>().spriteName = secondSpriteItem.GetComponent<UISprite>().spriteName = ItemData.SpriteName[i]; } } /// <summary> /// 创建分页图片,默认不创建(需要分页图片,分页的中间位置,每个分页的间隔) /// </summary> /// <param name="create"></param> private void CreateAdvertiseToggle(bool create = false) { if (create) { _toggleCenter = ItemData.ToggleCenterPos; delDistance = ItemData.ToggleDistance; Vector3 firstpoint = _toggleCenter - new Vector3((ItemData.MaxPage / 2f - 0.5f) * delDistance, 0f, 0f); for (int i = 0; i < ItemData.MaxPage; i++) { GameObject item; ToggleData toggleData = new ToggleData(); if (i == 0) { item = ItemData.ToggleItem.gameObject; } else { item = ItemData.ToggleContainer.gameObject.AddChild(ItemData.ToggleItem.gameObject); } item.transform.localPosition = firstpoint + new Vector3(i*delDistance, 0f, 0f); item.name = "toggle" + i; toggleData.go = item; toggleData.name = item.name; _toggleList.Add(toggleData); } } } void Update() { if (!_isStart) { return; } if (Time.frameCount % (30 * ItemData.MoveTime) == 0 && ItemData.MaxPage > 1) { if (ItemData.FirstMoveGo.localPosition.x < ItemData.LeftPosition.x - 0.5) { ItemData.FirstMoveGo.localPosition = ItemData.RightPosition; } if (ItemData.SecondMoveGo.localPosition.x < ItemData.LeftPosition.x - 0.5) { ItemData.SecondMoveGo.localPosition = ItemData.RightPosition; } Transform leftTran = ItemData.FirstMoveGo.localPosition.x < ItemData.SecondMoveGo.localPosition.x ? ItemData.FirstMoveGo : ItemData.SecondMoveGo; Transform rightTran = ItemData.FirstMoveGo.localPosition.x < ItemData.SecondMoveGo.localPosition.x ? ItemData.SecondMoveGo : ItemData.FirstMoveGo; TweenPosition.Begin(rightTran.gameObject, 0.5f, ItemData.LeftPosition, false); TweenPosition.Begin(leftTran.gameObject, 0.5f, _toLeftPosition, false); _currentPage = FixPage(_currentPage); SetPic(rightTran, _currentPage); //SetBtn(leftTran,false); //SetBtn(rightTran,true); _toggleList[_currentPage - 1].go.GetComponent<UIToggle>().value = true; } } private void SetBtn(Transform tran, bool state) { Transform tf = tran.Find("Icon"); if (tf != null) { tf.gameObject.SetActive(state); } } private void SetPic(Transform tran, int _currentPage) { foreach (Transform t in tran) { if (t.name == _currentPage.ToString()) { t.gameObject.SetActive(true); } else { t.gameObject.SetActive(false); } } } private int FixPage(int page) { page++; if (page > ItemData.MaxPage) { page = 1; } return page; } } }
第二步:创建管理类AdvertisementScrollManager,将它做成一个单例,调用AdvertisementScroll的方法,开始滚动。
using UnityEngine; using System.Collections.Generic; namespace Assets.Scripts.Client { public class AdvertisementScrollManager : Singleton<AdvertisementScrollManager> { public struct AdvertisementScrollData { public bool IsCreateToggle; //是否创建分页标签 public Transform ToggleItem; //分页标签 public Transform ToggleContainer; //分页标签所在的Panel public Vector3 ToggleCenterPos; //分页标签的中间位置 public int ToggleDistance; //分页标签之间的间隔 public Transform FirstMoveGo; //移动的物体 public Transform SecondMoveGo; //移动的物体 public Vector3 LeftPosition; //移动物体的左边位置 public Vector3 RightPosition; //移动物体的右边位置 public Transform SpriteItem; //显示的图片 public int SpriteWidth; //图片的宽度 public string[] SpriteName; //显示的所有图片在图集中的名称 public int MaxPage; //最大的页面 public int MoveTime; //每隔多少秒移动一次 }; public void StartAdvertisementScroll(Transform parentTf, AdvertisementScrollData data,bool createToggle = false) { if (parentTf != null) { UIPanel panel = parentTf.GetComponent<UIPanel>(); if (panel == null) { return; } AdvertisementScroll scroll = null; Transform tf = parentTf.Find("AdvertisementScroll"); if (tf == null) { GameObject go = new GameObject(); go.name = "AdvertisementScroll"; go.transform.parent = parentTf; go.transform.localPosition = Vector3.zero; go.transform.localScale = new Vector3(1, 1, 1); //go.layer = LayerModel.UILayer; tf = go.transform; scroll = tf.gameObject.AddComponent<AdvertisementScroll>(); } else { scroll = tf.gameObject.GetComponent<AdvertisementScroll>(); } scroll.ItemData = data; scroll.ItemData.FirstMoveGo.parent = tf; scroll.ItemData.SecondMoveGo.parent = tf; scroll.StartScroll(createToggle); } } } }
第三步:使用。预制体的制作方法就不说了,代码看懂了自然好弄,后面也会附上工程文件。你在任何一个界面需要使用广告牌组件时只需要先设置好数据,然后调用AdvertisementScrollManager中的StartAdvertisementScroll方法就可以了。
using Assets.Scripts.Client; using UnityEngine; namespace Assets { public class AdvertiseScrollSample : MonoBehaviour { private Transform _firstMoveGo; private Transform _secondMoveGo; private Transform _container; private Transform _toggleContainer; private Transform _spriteItem; private Transform _toggleItem; void Start () { _firstMoveGo = transform.Find("Panel/Container/First"); _secondMoveGo = transform.Find("Panel/Container/Second"); _container = transform.Find("Panel/Container"); _toggleContainer = transform.Find("Panel/ToggleContainer"); _spriteItem = transform.Find("Panel/Container/First/Item"); _toggleItem = transform.Find("Panel/ToggleContainer/ToggleItem"); OnRefreshData(); } void OnRefreshData() { AdvertisementScrollManager.AdvertisementScrollData data = CreateAdvertisementScrollData(); AdvertisementScrollManager.Instance.StartAdvertisementScroll(_container,data,data.ToggleContainer); } private AdvertisementScrollManager.AdvertisementScrollData CreateAdvertisementScrollData() { AdvertisementScrollManager.AdvertisementScrollData data = new AdvertisementScrollManager.AdvertisementScrollData(); //设置显示图片的数量和滑动的时间间隔 data.MoveTime = 10; data.MaxPage = 3; //设置图片的位置信息 data.FirstMoveGo = _firstMoveGo; data.SecondMoveGo = _secondMoveGo; data.SpriteItem = _spriteItem; data.SpriteWidth = 884; data.SpriteName = new string[] { "1", "2", "3" }; data.LeftPosition = Vector3.zero; data.RightPosition = new Vector3(800, 0, 0); //设置分页标签信息(如果不需要分页标签,可以不用赋值) data.IsCreateToggle = true; data.ToggleItem = _toggleItem; data.ToggleContainer = _toggleContainer; data.ToggleCenterPos = new Vector3(0,-200,0); data.ToggleDistance = 30; return data; } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
赞 (0)