Reputation: 39881
I wrote the following script:
public class SpriteUV : MonoBehaviour
{
private SpriteRenderer _spriteRenderer;
private Sprite _sprite;
[SerializeField] public Vector2[] _uv = new Vector2 [4]
{
new Vector2(0.4f, 0.5f),
new Vector2(0.6f, 0.5f),
new Vector2(0.4f, 0.35f),
new Vector2(0.6f, 0.35f)
};
void Start ()
{
_spriteRenderer = GetComponent<SpriteRenderer>();
_sprite = _spriteRenderer.sprite;
}
// Update is called once per frame
void Update ()
{
_sprite.uv = _uv;
}
}
BUT this has an error, it turns that Sprite.uv
has no setter (not obvious from the documentation) How can I change the sprite to map different part of the texture?
Upvotes: 3
Views: 9642
Reputation: 910
There is a more direct way now if you add the additional Sprite2D package by Unity:
sprite.SetVertexAttribute<Vector2>(VertexAttribute.TexCoord0, uv);
Only caveat is it requires a native array but you can Dispose() it right after the call. Equivalently there's a Get() method.
Upvotes: 0
Reputation: 39881
I have just used Quad
, for which you can set uvs
, vertices
and triangles
. So basically got all the information (uv, vertices) from Sprite and transfered that to a Quad
.
Upvotes: 0
Reputation: 90852
This is a solution that works with a SpriteRenderer
for atleast selecting a rectangle part of the Sprite you want to show. (How Programmer stated out orrectly in the comments this can not "deform" your UV if you need a complete different mapping.)
Create a new Shader and call it BlendVertexColorWithUV
Open it in VisualStudio (or any text editor) and past in the following code
Source
// unlit, vertex color, alpha blended, offset uv's
// cull off
Shader "BlendVertexColorWithUV"
{
Properties
{
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
}
SubShader
{
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
ZWrite Off Lighting Off Cull Off Fog { Mode Off } Blend SrcAlpha OneMinusSrcAlpha
LOD 110
Pass
{
CGPROGRAM
#pragma vertex vert_vct
#pragma fragment frag_mult
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
struct vin_vct
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f_vct
{
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
v2f_vct vert_vct(vin_vct v)
{
v2f_vct o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.color = v.color;
o.texcoord = TRANSFORM_TEX (v.texcoord, _MainTex);;
return o;
}
fixed4 frag_mult(v2f_vct i) : COLOR
{
fixed4 col = tex2D(_MainTex, i.texcoord) * i.color;
return col;
}
ENDCG
}
}
SubShader
{
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
ZWrite Off Blend SrcAlpha OneMinusSrcAlpha Cull Off Fog { Mode Off }
LOD 100
BindChannels
{
Bind "Vertex", vertex
Bind "TexCoord", texcoord
Bind "Color", color
}
Pass
{
Lighting Off
SetTexture [_MainTex] { combine texture * primary }
}
}
}
Create a new Material
Drag the BlendVertexColorWithUV
onto this material
assign this material to the Object that uses the SpriteRenderer
Set the SpriteRenderer
's DrawMode
to Tiled
Set the TileMode
to Continous
Note: I actually made a mistake while grabbing: You assign the Sprite
to the SpriteRenderer
not to the material! You can leave the material Blanc actually and just adjust the Tiling
and Offset
values.
Now you can adjust the offset of the sprite in the material e.g. by using a script
public Material textureToAnimate;
public Vector2 uvOffset;
....
textureToAnimate.mainTextureOffset = uvOffset;
Upvotes: 4