Author Topic: UITexture.uvRect affects all textures in a material, not just mainTex  (Read 3992 times)

madruse

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 4
    • View Profile
When modifying an UITexture's uvRect, ALL textures in a material are affected.  I assume for most people this is fine, but my UITexture has a custom shader that takes 2 texture inputs, one for diffuse, one for an alpha mask clip.  When animating the UITexture's uvRect, the mask also animates. 

How do I only animate one texture's uv offset?

This is super simple outside of NGUI because I can specify which texture I want to offset, with NGUI you can not.  :-\ Feature request?

I'm using NGUI 3.7.3

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UITexture.uvRect affects all textures in a material, not just mainTex
« Reply #1 on: September 27, 2014, 07:00:39 PM »
When you modify the UV rect, it changes the vertex texture coordinates. I don't know what you're doing in your shader, but my guess is that you are using them as-is.

Create a custom uniform float2 then set it on the material via the texture's onRender callback.

madruse

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 4
    • View Profile
Re: UITexture.uvRect affects all textures in a material, not just mainTex
« Reply #2 on: September 30, 2014, 11:53:19 AM »
Here is the shader:
  1. Shader "TextureMaskMultiply"
  2. {
  3.    Properties
  4.    {
  5.       _Color ("Main Color", Color) = (1,1,1,1)
  6.       _MainTex ("Base (RGB)", 2D) = "white" {}
  7.       _Mask ("Culling Mask", 2D) = "white" {}
  8.       _Cutoff ("Alpha Cutoff", Range (0,1)) = 0.1
  9.    }
  10.    SubShader
  11.    {
  12.       Tags {"Queue"="Transparent"}
  13.       Lighting Off
  14.       ZWrite Off
  15.       Color [_Color]
  16.       AlphaTest GEqual [_Cutoff]
  17.       Blend SrcAlpha OneMinusSrcAlpha
  18.       Pass
  19.       {
  20.          SetTexture [_Mask] {
  21.             constantColor [_Color]
  22.                 combine texture * constant
  23.          }
  24.          SetTexture [_MainTex] {
  25.             combine previous * texture
  26.          }
  27.       }
  28.    }
  29. }
  30.  
Create a material using this shader with a texture and a mask texture.
Then create an UITexture in your GUI that uses the material you created.
Then animate the uvRect:
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class NGUIAnimateUV : MonoBehaviour {
  5.        
  6.         public UITexture UITextureRef;
  7.         public Vector2 ScrollSpeed = new Vector2(0.5f, 0);
  8.  
  9.         private void Update() {
  10.                 if (UITextureRef) {
  11.                         UITextureRef.uvRect = new Rect(Time.time * ScrollSpeed.x % 1, Time.time * ScrollSpeed.y % 1, UITextureRef.uvRect.width, UITextureRef.uvRect.height);
  12.                         UITextureRef.MarkAsChanged();
  13.                 }
  14.         }
  15. }
  16.  
Both the texture and the mask animate.

How do I only animate the texture and not the mask?
If I try to access the UITexture's material and set the texture offset, it offsets once, but does not animate.
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class NGUIAnimateUV : MonoBehaviour {
  5.        
  6.         public UITexture UITextureRef;
  7.         public Vector2 ScrollSpeed = new Vector2(0.5f, 0);
  8.  
  9.         private void Update() {
  10.                 if (UITextureRef) {
  11.                         Vector2 offset = new Vector2(Time.time * ScrollSpeed.x % 1, Time.time * ScrollSpeed.y % 1);
  12.                         UITextureRef.material.SetTextureOffset("_MainTex", offset);
  13.                         UITextureRef.MarkAsChanged();
  14.                 }
  15.         }
  16. }
  17.  

Maybe I'm not going about this the right way? Is there a better way?  Might be a question for a different forum.
« Last Edit: September 30, 2014, 02:56:32 PM by madruse »

madruse

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 4
    • View Profile
Re: UITexture.uvRect affects all textures in a material, not just mainTex
« Reply #3 on: September 30, 2014, 11:59:24 AM »
Here is how I'm animating it outside of NGUI and it works fine, but I can't layer it in with my GUI.
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class AnimateUV : MonoBehaviour {
  5.         public Vector2 ScrollSpeed = new Vector2(0.5f, 0.5f);
  6.  
  7.         private void Update() {
  8.                 if (renderer) {
  9.                         Vector2 offset = new Vector2(Time.time * ScrollSpeed.x % 1, Time.time * ScrollSpeed.y % 1);
  10.                         renderer.material.SetTextureOffset("_MainTex", offset);
  11.                 }
  12.         }
  13. }
  14.  

madruse

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 4
    • View Profile
Re: UITexture.uvRect affects all textures in a material, not just mainTex
« Reply #4 on: September 30, 2014, 12:48:41 PM »
I noticed in 3.7.3 that you added a texture mask to panels.  So I tried going with that using the mask on the panel, then set my UITexture to just use the Unlit/Transparent Colored shader.  This works, but now the UITexture, in the texture masked panel, ignores the tiling which is x:40, y:22.5 in my material.  :-\  But changing the uvRect width/height worked. ;)
« Last Edit: September 30, 2014, 02:58:36 PM by madruse »