Unity3d实现无限循环滚动背景

Maren ·
更新时间:2024-11-14
· 1336 次阅读

在游戏项目中我们常常看到商城的广告牌,几张广告图片循环滚动,类似跑马灯,现在我将讨论一种实现方法,并提供一个管理类,大家可以直接使用。

实现原理:背景图片循环滚动的原理很简单:两张图片向一个方向移动,当达某张图片到临界区域时将图片放在后面,依次循环。

在实际项目中,广告牌显示的图片数量不确定,例如某个假期活动会上很多新品,此时我们需要动态的创建显示的图片(一般在配置表读取数据),如果需要显示分类标签还得动态生成分类标签。

综上所述,一个完整的广告牌组件应该具有以下功能:

- 无限循环的滚动背景图片
- 根据读取的数据动态生成图片
- 具有分类标签,根据显示图片动态生成
- *做成一个管理类,方便使用(一个项目中可能多处会用到)

下面谈谈我的方法:

第一步:创建滚动组件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;     } } }



循环 unity3d unity

需要 登录 后方可回复, 如果你还没有账号请 注册新账号