当前位置:   article > 正文

【Unity2D】循环滚动背景实现_unity2d生成的背景不连续

unity2d生成的背景不连续

        在2d游戏中地图通常需要有一个较大且循环的背景,通过手动一个个拼接是非常消耗性能且费工作量的,为了解决这个问题通过代码实现如下:

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. public class BackgroundLoop : MonoBehaviour
  6. {
  7. private void Start()
  8. {
  9. if(_mainCamera == null)
  10. {
  11. _mainCamera = Camera.main;
  12. }
  13. _cam = _mainCamera.transform;
  14. _screenBounds = _mainCamera.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, _cam.position.z));
  15. for(int i = 0; i < _levels.Length; ++i)
  16. {
  17. LoadChildObjects(_levels[i]);
  18. }
  19. _bInit = true;
  20. }
  21. private void LoadChildObjects(GameObject go)
  22. {
  23. float objWidth = go.GetComponent<SpriteRenderer>().bounds.size.x - _choke;
  24. int childNeeded = (int)Mathf.Ceil(_screenBounds.x * 2 / objWidth) + 2;
  25. GameObject clone = Instantiate(go) as GameObject;
  26. for(int i = 0; i <= childNeeded; ++i)
  27. {
  28. GameObject c = Instantiate(clone) as GameObject;
  29. var targetPos = go.transform.position;
  30. targetPos.x += objWidth * (i - 1);
  31. c.transform.position = targetPos;
  32. c.name = go.name + i;
  33. c.transform.SetParent(go.transform);
  34. }
  35. Destroy(clone);
  36. Destroy(go.GetComponent<SpriteRenderer>());
  37. }
  38. private void LateUpdate()
  39. {
  40. if (!_bInit) return;
  41. foreach (GameObject go in _levels)
  42. {
  43. RepositionChildObjects(go);
  44. }
  45. }
  46. private void RepositionChildObjects(GameObject go)
  47. {
  48. if(!_spritesDic.ContainsKey(go))
  49. {
  50. _spritesDic.Add(go, new List<Transform>());
  51. var sprites = go.GetComponentsInChildren<Transform>();
  52. for(int i = 1; i < sprites.Length; ++i)
  53. {
  54. _spritesDic[go].Add(sprites[i]);
  55. }
  56. }
  57. var children = _spritesDic[go];
  58. if(children.Count > 2)
  59. {
  60. Transform firstChild = children[0];
  61. Transform secondChild = children[1];
  62. Transform lastSecondChild = children[children.Count - 2];
  63. Transform lastChild = children[children.Count - 1];
  64. if (!_halfWidthDic.ContainsKey(go))
  65. {
  66. _halfWidthDic.Add(go, firstChild.GetComponent<SpriteRenderer>().bounds.extents.x - _choke);
  67. }
  68. float halfObjectWidth = _halfWidthDic[go];
  69. if (_cam.position.x + _screenBounds.x > lastSecondChild.transform.position.x +halfObjectWidth)
  70. {
  71. children.Remove(firstChild.transform);
  72. children.Insert(children.Count, firstChild.transform);
  73. var targetPos = firstChild.transform.position;
  74. targetPos.x = lastChild.transform.position.x + halfObjectWidth * 2;
  75. firstChild.transform.position = targetPos;
  76. }
  77. else if(_cam.position.x - _screenBounds.x < secondChild.transform.position.x - halfObjectWidth)
  78. {
  79. children.Remove(lastChild.transform);
  80. children.Insert(0, lastChild.transform);
  81. var targetPos = lastChild.transform.position;
  82. targetPos.x = firstChild.transform.position.x - halfObjectWidth * 2;
  83. lastChild.transform.position = targetPos;
  84. }
  85. }
  86. }
  87. public GameObject[] _levels; // 需要循环的背景层
  88. public Camera _mainCamera; // 主相机(不设置就自动获取场景中的相机)
  89. public float _choke = 0f; // 当背景之间出现明显的分隔线时增大此值
  90. Dictionary<GameObject, float> _halfWidthDic = new Dictionary<GameObject, float>();
  91. Dictionary<GameObject, List<Transform>> _spritesDic = new Dictionary<GameObject, List<Transform>>();
  92. Transform _cam;
  93. Vector2 _screenBounds;
  94. bool _bInit = false; // 是否完成初始化
  95. }

效果图:

不运行状态

 运行状态

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/97938
推荐阅读
  

闽ICP备14008679号