Unity中的图片循环滚动实现

Unity中的图片循环滚动实现

1. 单张图片的循环滚动(不仅限于背景的滚动,是SpriteRenderer图片非UI图片)

  • 修改图片模式

在这里插入图片描述

  • 创建材质并添加到SpriteRender中
    在这里插入图片描述
    在这里插入图片描述

  • 实现原理(通过修改material中的offset的值即可实现图片的横向和纵向滚动)

  • 在这里插入图片描述

  • 创建脚本编写代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test_BgScroll : MonoBehaviour
{
    [Tooltip("移动速度"),Range(0.01f,1f)]
    public float moveSpeed;
    private SpriteRenderer render;
    void Start()
    {
        render = GetComponent<SpriteRenderer>();
    }

    // Update is called once per frame
    void Update()
    {
        BgScroll();
    }
    /// <summary>
    /// 单张图片的重复滚动
    /// </summary>
    public void BgScroll()
    {
        //图片模式已设置为repeat,通过代码修改材质中的offset即可实现滚动
        render.material.mainTextureOffset += new Vector2(moveSpeed * Time.deltaTime, 0);
    }
}

  • 效果图
    在这里插入图片描述
    2. 单张图片的循环滚动(UI图片,与1的实现原理基本一致)

  • 实现步骤:
    -1.创建一个RawImage,注意这里不能用Image,因为Image无法修改UVRect。然后将背景图片的Wrap Mode设置成Repeat填入即可。
    在这里插入图片描述
    -2.编写代码修改RawImage的UVRect即可,如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Test_BgScroll : MonoBehaviour
{
    public Vector2 move = new Vector2(0.1f, 0.1f);
    public RawImage ri;
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        RawImageScroll();
    }

    public void RawImageScroll()
    {
        ri.uvRect = new Rect(ri.uvRect.position + move * Time.deltaTime, ri.uvRect.size);
    }
}

3. 多张图片的循环滚动
实现方法:
1.所有背景各自挂载脚本移动,互不干涉,仅在超出边界时充值位置(本文使用的是这种方法)。
2.将所有的背景放到一个列表之中统一管理,仅让第一张背景移动,其他的全部跟随第一个物体,当超出边界后重置位置和第一个物体即可(实现也较简单,感兴趣可尝试)。

  • 自动滚动脚本(挂载在每一个需要滚动的物体上)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AutoMove : MonoBehaviour
{
    public enum TYPE
    {
        BG,
        GROUND
    }
    public TYPE type;
    public float moveSpeed = 1;
    // Update is called once per frame
    void Update()
    {
        BgScroll();
    }

    public void BgScroll()
    {
        switch (type)
        {
            case TYPE.BG:
                if (transform.position.x <= GameManager._instance.bgLeftMoveBorder)
                {
                    GameManager._instance.BgReset(gameObject);
                }
                break;
            case TYPE.GROUND:
                if (transform.position.x<=GameManager._instance.groundLeftMoveBorder)
                {
                    GameManager._instance.GroundReset(gameObject);
                }
                break;
        }
        transform.position += Vector3.left * moveSpeed * Time.deltaTime;
    }
}


  • 管理脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    public static GameManager _instance;
    [Header("背景列表")]
    //需要按照顺序外部拖拽赋值
    public List<GameObject> allBgGo;
    public List<GameObject> allGroundGo;
    //获得图片的宽度
    public float bgWidth;
    public float groundWidth;
    public float bgLeftMoveBorder;
    public float groundLeftMoveBorder;
    // Start is called before the first frame update
    void Start()
    {
        _instance = this;
        bgWidth = allBgGo[0].GetComponent<SpriteRenderer>().size.x;
        groundWidth = allGroundGo[0].GetComponent<SpriteRenderer>().size.x;
    }
    /// <summary>
    /// 背景滚动越界判断,超出边界移到后面
    /// </summary>
    public void BgReset(GameObject go)
    {
        go.transform.position = allBgGo[allBgGo.Count - 1].transform.position + new Vector3(bgWidth, 0, 0);
        allBgGo.Remove(go);
        allBgGo.Add(go);
    }
    /// <summary>
    /// 地面滚动越界判断,超出边界移到后面
    /// </summary>
    public void GroundReset(GameObject go)
    {
        go.transform.position = allGroundGo[allGroundGo.Count - 1].transform.position + new Vector3(groundWidth, 0, 0);
        allGroundGo.Remove(go);
        allGroundGo.Add(go);
    }
}


  • 效果图
    在这里插入图片描述