テクスチャを 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; } }