テクスチャを UV スクロールする方法として
* Shader を使う
* スクリプトを使う
の2種類がある
Shader で UV スクロールしてる記事はあったが、スクリプトで UVスクロールしてる記事は見かけなかった

Shader でUVスクロール
GPU を利用して UVスクロールを行うため、CPU負荷がない
UV スクロールの処理を頂点シェーダかフラグメントシェーダを選べるようにしたので、
頂点が少ない場合は、頂点シェーダ (Vertex)
頂点が多く描画範囲が狭い場合は、フラグメントシェーダ (Fragment)
を利用すると低負荷で UV スクロールが行えます

Shader "Unlit/UVScroll"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_ScrollX("ScrollX", float) = 0
_ScrollY("ScrollY", float) = 0
[KeywordEnum(Vertex, Fragment)] _Target ("Calc Target", Float) = 0
}
SubShader
{
Tags { "RenderType" = "Opaque" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _TARGET_VERTEX _TARGET_FRAGMENT
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
fixed _ScrollX, _ScrollY;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
#ifdef _TARGET_VERTEX
o.uv = o.uv + fixed2(frac(_ScrollX * _Time.y), frac(_ScrollY * _Time.y));
#endif
return o;
}
fixed4 frag(v2f i) : SV_Target
{
#ifdef _TARGET_FRAGMENT
i.uv = fixed2(frac(i.uv.x + _ScrollX * _Time.y), frac(i.uv.y + _ScrollY * _Time.y));
#endif
return tex2D(_MainTex, i.uv);
}
ENDCG
}
}
}
スクリプトでUVスクロール
GPU 側では無く、CPU 側で処理を行う
Shader を変える必要がないので、
他の Shader を使いながら UV スクロールをすることが可能
using UnityEngine; public class UVScroll : MonoBehaviour { [SerializeField] private Material _targetMaterial; [SerializeField] private float _scrollX; [SerializeField] private float _scrollY; private Vector2 offset; private void Awake() { offset = _targetMaterial.mainTextureOffset; } private void Update() { offset.x += _scrollX * Time.deltaTime; offset.y += _scrollY * Time.deltaTime; _targetMaterial.mainTextureOffset = offset; } }