Unity背景图无限循环

背景无限循环

首先我们导入一张没有被处理过的图片

我们使用图片原来的大小。

让后给这个精灵(我喜欢叫他雪碧,因为这是一个不错的饮料)添加我们的脚本。

组件代码:

/**********
*	author        :  "小白虫||镜子"
*	time          :  "2020-8-27"
*	describe      :  "背景循环流动"
*   unity version :  "2020.3.16"
*   Blog          :  "https://www.cnblogs.com/jzyl"
**********/
using System;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

public enum Direction
{
	[Tooltip("向上流动")]
	UP = 0,
	[Tooltip("向下流动")]
	DOWN,
	[Tooltip("向左流动")]
	LEFT,
	[Tooltip("向右流动")]
	RIGHT,
}

public class BackgroundLoop : MonoBehaviour
{
	[ReadOnly, SerializeField]
	private string 注意 = "图片导入纹理属性Non-Poer of 2 选择None";
	[Tooltip("控制背景移动速度"),Range(0,1000)]	//不支持负值
	public float m_speed = 10.0f;
	[Tooltip("图片从哪个方向流动")]
	public Direction m_direction;


	private GameObject m_preBackground;
	private GameObject m_nextBackground;
	private Vector2 m_size;              //图片长宽
	private Vector3 m_position;          //m_preBackground开始位置
	private Direction m_trackDirection;  //当direction改变时,主要是用于检测这个事件的
	private Vector3 m_limit;             //背景移动的边界。超过就回返回;
	private Vector3 m_removePosition;    //背景重新移动的位置,超过边界后移动到这里。
	// Start is called on the frame when a script is enabled just before any of the Update methods is called the first time.
	protected void Start()
	{
		Init();
	}
	private void Init()
	{
		m_direction = m_trackDirection = Direction.LEFT;
		m_size = transform.GetComponent<SpriteRenderer>().sprite.rect.size / 100;
		m_size.x *= transform.localScale.x;
		m_size.y *= transform.localScale.y;
		m_position = transform.position;
		m_preBackground = this.gameObject;
		m_preBackground.name = "背景00";
		m_nextBackground = new GameObject("背景01");
		m_nextBackground.transform.position = m_position;
		m_nextBackground.transform.localScale = m_preBackground.transform.localScale;
		m_nextBackground.AddComponent<SpriteRenderer>().sprite = m_preBackground.GetComponent<SpriteRenderer>().sprite;
		InitChangeDirection(m_direction);
	}
	// Update is called every frame, if the MonoBehaviour is enabled.
	protected void Update()
	{
		if (m_trackDirection != m_direction)    //检测是否换方向流动。
		{
			m_trackDirection = m_direction;
			InitChangeDirection(m_direction);
		}
		Flow(m_direction);
	}
	private void InitChangeDirection(Direction dir) //初始化,当方向改变时。
	{
		transform.position = m_position;
		switch (dir)
		{
		case Direction.UP:
			m_nextBackground.transform.position = m_position + new Vector3(0, -m_size.y, 0);
			m_limit = m_position + new Vector3(0, m_size.y, 0);
			break;

		case Direction.DOWN:
			m_nextBackground.transform.position = m_position + new Vector3(0, m_size.y, 0);
			m_limit = m_position + new Vector3(0, -m_size.y, 0);
			break;
		case Direction.LEFT:
			m_nextBackground.transform.position = m_position + new Vector3(m_size.x, 0, 0);
			m_limit = m_position + new Vector3(-m_size.x, 0, 0);
			break;
		case Direction.RIGHT:
			m_nextBackground.transform.position = m_position + new Vector3(-m_size.x, 0, 0);
			m_limit = m_position + new Vector3(m_size.x, 0, 0);
			break;
		}
		m_removePosition = m_nextBackground.transform.position;
	}
	private void Flow(Direction dir)
	{
		switch (dir)
		{
		case Direction.UP:
			m_preBackground.transform.position += Vector3.up * Time.deltaTime * m_speed;
			m_nextBackground.transform.position += Vector3.up * Time.deltaTime * m_speed;
			if (m_preBackground.transform.position.y >= m_limit.y)
			{
				m_preBackground.transform.position = m_nextBackground.transform.position - new Vector3(0, m_size.y, 0); //不会产生裂缝
			}
			if (m_nextBackground.transform.position.y >= m_limit.y)
			{
				m_nextBackground.transform.position = m_preBackground.transform.position - new Vector3(0, m_size.y, 0); //不会产生裂缝
			}
			break;

		case Direction.DOWN:
			m_preBackground.transform.position += Vector3.down * Time.deltaTime * m_speed;
			m_nextBackground.transform.position += Vector3.down * Time.deltaTime * m_speed;
			if (m_preBackground.transform.position.y <= m_limit.y)
			{
				m_preBackground.transform.position = m_nextBackground.transform.position + new Vector3(0, m_size.y, 0);
			}
			if (m_nextBackground.transform.position.y <= m_limit.y)
			{
				m_nextBackground.transform.position = m_preBackground.transform.position + new Vector3(0, m_size.y, 0);
			}
			break;
		case Direction.LEFT:
			m_preBackground.transform.position += Vector3.left * Time.deltaTime * m_speed;
			m_nextBackground.transform.position += Vector3.left * Time.deltaTime * m_speed;
			if (m_preBackground.transform.position.x <= m_limit.x)
			{
				m_preBackground.transform.position = m_nextBackground.transform.position + new Vector3(m_size.x, 0, 0);
			}
			if (m_nextBackground.transform.position.x <= m_limit.x)
			{
				m_nextBackground.transform.position = m_preBackground.transform.position + new Vector3(m_size.x, 0, 0);
			}
			break;
		case Direction.RIGHT:
			m_preBackground.transform.position += Vector3.right * Time.deltaTime * m_speed;
			m_nextBackground.transform.position += Vector3.right * Time.deltaTime * m_speed;
			if (m_preBackground.transform.position.x >= m_limit.x)
			{
				m_preBackground.transform.position = m_nextBackground.transform.position - new Vector3(m_size.x, 0, 0);
			}
			if (m_nextBackground.transform.position.x >= m_limit.x)
			{
				m_nextBackground.transform.position = m_preBackground.transform.position - new Vector3(m_size.x, 0, 0);
			}
			break;
		}
	}
}

#region 定义只读Attribute

public class ReadOnlyAttribute : PropertyAttribute
{

}

#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(ReadOnlyAttribute))]
public class ReadOnlyDrawer : PropertyDrawer
{
	public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
	{
		return EditorGUI.GetPropertyHeight(property, label, true);
	}

	public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
	{
		GUI.enabled = false;
		EditorGUI.PropertyField(position, property, label, true);
		GUI.enabled = true;
	}
}
#endif
#endregion

效果演示

微云

posted @ 2021-08-27 17:16  镜子-眼泪  阅读(708)  评论(0)    收藏  举报