赞
踩
在2d游戏中地图通常需要有一个较大且循环的背景,通过手动一个个拼接是非常消耗性能且费工作量的,为了解决这个问题通过代码实现如下:
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class BackgroundLoop : MonoBehaviour
- {
- private void Start()
- {
- if(_mainCamera == null)
- {
- _mainCamera = Camera.main;
- }
- _cam = _mainCamera.transform;
- _screenBounds = _mainCamera.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, _cam.position.z));
- for(int i = 0; i < _levels.Length; ++i)
- {
- LoadChildObjects(_levels[i]);
- }
- _bInit = true;
- }
-
- private void LoadChildObjects(GameObject go)
- {
- float objWidth = go.GetComponent<SpriteRenderer>().bounds.size.x - _choke;
- int childNeeded = (int)Mathf.Ceil(_screenBounds.x * 2 / objWidth) + 2;
- GameObject clone = Instantiate(go) as GameObject;
- for(int i = 0; i <= childNeeded; ++i)
- {
- GameObject c = Instantiate(clone) as GameObject;
- var targetPos = go.transform.position;
- targetPos.x += objWidth * (i - 1);
- c.transform.position = targetPos;
- c.name = go.name + i;
- c.transform.SetParent(go.transform);
- }
- Destroy(clone);
- Destroy(go.GetComponent<SpriteRenderer>());
- }
-
- private void LateUpdate()
- {
- if (!_bInit) return;
- foreach (GameObject go in _levels)
- {
- RepositionChildObjects(go);
- }
- }
-
- private void RepositionChildObjects(GameObject go)
- {
- if(!_spritesDic.ContainsKey(go))
- {
- _spritesDic.Add(go, new List<Transform>());
- var sprites = go.GetComponentsInChildren<Transform>();
- for(int i = 1; i < sprites.Length; ++i)
- {
- _spritesDic[go].Add(sprites[i]);
- }
- }
-
- var children = _spritesDic[go];
- if(children.Count > 2)
- {
- Transform firstChild = children[0];
- Transform secondChild = children[1];
- Transform lastSecondChild = children[children.Count - 2];
- Transform lastChild = children[children.Count - 1];
- if (!_halfWidthDic.ContainsKey(go))
- {
- _halfWidthDic.Add(go, firstChild.GetComponent<SpriteRenderer>().bounds.extents.x - _choke);
- }
- float halfObjectWidth = _halfWidthDic[go];
- if (_cam.position.x + _screenBounds.x > lastSecondChild.transform.position.x +halfObjectWidth)
- {
- children.Remove(firstChild.transform);
- children.Insert(children.Count, firstChild.transform);
- var targetPos = firstChild.transform.position;
- targetPos.x = lastChild.transform.position.x + halfObjectWidth * 2;
- firstChild.transform.position = targetPos;
- }
- else if(_cam.position.x - _screenBounds.x < secondChild.transform.position.x - halfObjectWidth)
- {
- children.Remove(lastChild.transform);
- children.Insert(0, lastChild.transform);
- var targetPos = lastChild.transform.position;
- targetPos.x = firstChild.transform.position.x - halfObjectWidth * 2;
- lastChild.transform.position = targetPos;
- }
- }
- }
-
- public GameObject[] _levels; // 需要循环的背景层
- public Camera _mainCamera; // 主相机(不设置就自动获取场景中的相机)
- public float _choke = 0f; // 当背景之间出现明显的分隔线时增大此值
-
- Dictionary<GameObject, float> _halfWidthDic = new Dictionary<GameObject, float>();
- Dictionary<GameObject, List<Transform>> _spritesDic = new Dictionary<GameObject, List<Transform>>();
- Transform _cam;
- Vector2 _screenBounds;
- bool _bInit = false; // 是否完成初始化
- }
效果图:
不运行状态
运行状态
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。