2013-01-10 14:49:05 yangchenghuan 阅读数 1173

using UnityEngine;

using System.Collections;

 

public class classAnimateTiledTexture :MonoBehaviour

{

    public int columns = 5;

    public int rows = 3;

 

    void Start()

    {

        StartCoroutine(updateTiling());

 

        //set thetile size of the texture (in UV units), based on the rows and columns

        Vector2 size = new Vector2(1f/ columns, 1f / rows);

        renderer.sharedMaterial.SetTextureScale("_MainTex", size);

    }

 

    private IEnumerator updateTiling()

    {

        while(true)

        {

            for(int i = rows-1; i >-1; i--)

            {

                for(int j = 0; j<columns; j++)

                {

                    Vector2 offset = new Vector2((float)j / columns,(float)i / rows);

                    renderer.sharedMaterial.SetTextureOffset("_MainTex",offset);

                    yield return new WaitForSeconds(1f);

                }

            }

        }

    }

}

把图片和脚本拖拽到目标对象,设置rows为3,columns为5
目标物体需要加上 Mesh Renderer
把存放图片的Materials给Mesh Renderer的Materials就可以了
2014-12-08 14:02:46 wolf96 阅读数 2991
精灵动画,顾名思义是一种动画效果,我们用到的贴图是类似胶卷一样的,把每一帧都放在一张图上,

然后通过变换uv值进行位移切换,

如果你之前没有进行过uv相关的变换,可以查看上一篇文章 unity3d 纹理贴图移动特效


首先我们需要一个张这样的贴图


然后建立一个shader


先声明变量
_TexWidth  贴图总宽度
_CellAmount  一张图上包含几个动作(有几个小图片)
_Speed  动画的速度


	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_TexWidth ("Sheet Width", float) = 0.0
		_CellAmount ("Cell Amount", float) = 0.0//有几个画面
		_Speed ("Speed", Range(0.01, 32)) = 12
	}

主要的操作也是在surf函数中进行
需要一点数学的知识。。。。

先浏览一下局部变量

float2 spriteUV   贴图的uv坐标
float cellPixelWidth     贴图中的一个小画面的宽度
        
float cellUVPercentage     小画面占整个贴图的比率,小画面个数越少比率越大
    
float timeVal    当前该显示的小图片位数(就是该显示哪个小图片了)
float xValue   贴图uv中的x坐标值


		void surf (Input IN, inout SurfaceOutput o) {

			float2 spriteUV = IN.uv_MainTex;
			float cellPixelWidth = _TexWidth/_CellAmount;//一个小画面的宽度
			float cellUVPercentage = cellPixelWidth/_TexWidth;//小画面占大画面比率,个数越少比率越大
			float timeVal = fmod(_Time.y * _Speed, _CellAmount);
			timeVal = ceil(timeVal);//向上取整,得到一个小于CellAmount的整数
			float xValue = spriteUV.x;			xValue += cellUVPercentage * timeVal * _CellAmount;//
			xValue *= cellUVPercentage;//对uv进行缩放
			spriteUV = float2(xValue, spriteUV.y);
			half4 c = tex2D (_MainTex, spriteUV);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}

一个小画面的宽度
 = 总宽度 / 小图片数目
cellPixelWidth = _TexWidth/_CellAmount;


小画面占整个贴图的比率 = 一个小画面的宽度 / 整个贴图宽度
cellUVPercentage = cellPixelWidth/_TexWidth


对时间*速度与小图片数目取余,得到的就是一个小于小图片数目的数,正好就是当前该显示的图片位数
fmod(x,y)取余函数,返回一个x/y 的浮点型余数
timeVal = fmod(_Time.y * _Speed, _CellAmount)
    
但是是fmod()得到的是一个浮点数值,不是一个整数值,
我们就用ceil()这个函数对它进行向上取整
timeVal = ceil(timeVal)

初始化xValue贴图uv中的x坐标值
float xValue = spriteUV.x

进行偏移,得到当前小图片的uv位置        
xValue += cellUVPercentage * timeVal * _CellAmount

然后必须对uv进行缩放才能看到一张小图片
xValue *= cellUVPercentage

然后得到最终uv值进行纹理渲染


最终得到这样的结果:




shader代码如下:



Shader "Custom/testShader" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_TexWidth ("Sheet Width", float) = 0.0
		_CellAmount ("Cell Amount", float) = 0.0//有几个画面
		_Speed ("Speed", Range(0.01, 32)) = 12
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200

			CGPROGRAM
#pragma surface surf Lambert
			float _TexWidth;
		float _CellAmount;
		float _Speed;

		sampler2D _MainTex;


		struct Input {
			float2 uv_MainTex;
		};

		void surf (Input IN, inout SurfaceOutput o) {

			float2 spriteUV = IN.uv_MainTex;
			float cellPixelWidth = _TexWidth/_CellAmount;//一个小画面的宽度
			float cellUVPercentage = cellPixelWidth/_TexWidth;//小画面占大画面比率,个数越少比率越大
			float timeVal = fmod(_Time.y * _Speed, _CellAmount);
			timeVal = ceil(timeVal);//向上取整,得到一个小于CellAmount的整数
			float xValue = spriteUV.x;			xValue += cellUVPercentage * timeVal * _CellAmount;//
			xValue *= cellUVPercentage;//对uv进行缩放
			spriteUV = float2(xValue, spriteUV.y);
			half4 c = tex2D (_MainTex, spriteUV);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
		ENDCG
	} 
	FallBack "Diffuse"
}



                                                                                                             -------- by wolf96

2011-10-16 17:54:31 superherosk123 阅读数 28
unity中shader可以采用cg来书写.
此文演示了如何利用纹理坐标来分段街区纹理.

正常的纹理坐标范围[0..1],坐标超出此范围可以用多种方式来处理,如Wrap,Clamp,Mirror等.
假设纹理分为n段,
则,每段对应的纹理坐标为[0..1]/n + index*1/n;
使用此规则就可以将纹理分段来截取了.

cg代码:
float2 nuv = v.uv;
nuv.x = nuv.x /6;
nuv.x += 1.0/6.0 * _index;
float4 texColor = tex2D(_MainTex,nuv);


如此,便可以在shader中实现纹理动画了.

完全代码:

Shader "Level4/alpha1"{
Properties{
_MainTex("base rgb",2d) = ""{}
_alpha("alpha",range(0,1)) = 0.5
_index("index",float) = 0
}

CGINCLUDE
#include "UnityCG.cginc"
sampler2D _MainTex;
float _alpha;
float _index;

struct v2f{
float4 pos:POSITION;
float2 uv:TEXCOORD;
};
v2f vert(appdata_full v):POSITION{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
o.uv = v.texcoord.xy;
return o;
}

float4 frag(v2f v):COLOR{
float2 nuv = v.uv;
nuv.x = nuv.x /6;
nuv.x += 1.0/6.0 * _index;
float4 texColor = tex2D(_MainTex,nuv);
texColor.a = _alpha;
return texColor;
}

ENDCG

SubShader{
Tags { "Queue" = "Transparent" }
// ZWrite Off
Blend SrcAlpha DstAlpha
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
}
2015-08-03 15:54:22 teng_ontheway 阅读数 3610

开发背景

游戏中一些背景能采用UV动画,效果更佳。eg.星空、墙壁

因为gif的原因有卡顿,起始播放纹理动画的时候是不会有卡顿的。
这里写图片描述

Unity的NGUI采用纹理动画

NGUI的UITexture允许使用一张纹理
这里写图片描述

有了这个,我们便可以扩展一个脚本来影响【UV Rect】参数了


/**
    基于NGUI的UITexture的纹理动画

    1.图片首尾相接的UITexture,可以播放UV纹理动画
    2.可以根据定制UV动画方向、速度
    3.图片属性: 【Texture Type】:Texture  【Wrap Mode】:Repeat, 图片属性必须基于纹理,不能是Sprite(2D 或 UI)

    Added by Teng.      
 **/
using UnityEngine;
using System.Collections;
public class UVTextureMove : MonoBehaviour
{
    // 纹理对象
    public UITexture uiTexture;

    // 移动速度
    public float speedX = 0.1f;
    public float speedY = 0.1f;

    private float offset_x = 0.0f;
    private float offset_y = 0.0f;
    private float uv_w = 0;
    private float uv_h = 0;

    void Start()
    {
        if (uiTexture == null) {
            uiTexture = gameObject.GetComponent<UITexture>();
        }

        if (uiTexture == null) {
            Debug.LogError("UITexture not exist!");
        }

        uv_w = uiTexture.uvRect.width;
        uv_h = uiTexture.uvRect.height;
    }

    void Update ()
    {
        offset_x += Time.deltaTime * speedX;
        offset_y += Time.deltaTime * speedY;

        uiTexture.uvRect = new Rect(offset_x, offset_y, uv_w, uv_h);
    }
}

注意细节

  1. UITexture 图片属性: 【Texture Type】:Texture 【Wrap Mode】:Repeat, 图片属性必须基于纹理,不能是Sprite(2D 或 UI)
  2. 纹理要做到首尾相接,否则会巨难看

效果预览

这里写图片描述
这里写图片描述

2015-01-31 19:05:00 weixin_30813225 阅读数 8

不知道大家有没有玩过赛车游戏

赛车游戏的跑道有路标,如下图

玩过赛车游戏的都知道,大多数赛车游戏的路标是会动的,如上图,它会从右往左运动

不会发动态图,大家脑补一下吧

没有玩过赛车游戏的也不要紧,大家见过游戏中的瀑布或者湖面吗?如下图:高山流水

 

当然,我这个贴图的效果不是很好,不过我这里要说的是原理,不妨碍,我们继续

图中的瀑布从上往下流动

我们都知道,如果用粒子的话,有几百个瀑布,在手机上肯定是非常卡的

差一点的手机说不定游戏刚打开就未响应了

除非要求是非常逼真的那种水才用粒子系统,能不用尽量不用

用纹理动画的话虽然达不到粒子那么逼真,但是也是一种不错的解决方案

纹理动画耗费资源还是粒子动画耗费资源呢?我们一探究竟

小二,上图

好勒客官,马上来

 

这是瀑布的材质球,我们手动修改OffsetX

按每次+0.1这样修改:0.1,0.2,0.3,0.4....

我们会发现,每修改一次材质球就会相应的变动

现在我们归零,修改一下OffsetY,依旧和修改X一样的方法

我们会发现材质球也会有相应的变动,但是方向不一样

如果只观察材质球感觉不容易看出来,那就把材质球挂到物体上,这样看的清楚一些

好了,我们知道如果让材质球动起来了,修改offset即可,那么我们就开始敲代码吧

 

创建一个 TextureAnimation.cs

定义一个变量:public float XSpeed = 0.1f;//X轴移动速度

然后有了下面的代码

1      public float XSpeed = 0.1f;//X轴移动速度
2  
3      void FixedUpdate()
4      {
5          renderer.material.mainTextureOffset = new Vector2(Time.time * XSpeed, renderer.material.mainTextureOffset.y);    
6      }

 我们挂到瀑布上,然后运行,我们发现瀑布动起来了,但是似乎移动方向和速度不对劲

没关系,我们刚才修改的是X轴,我们在加上Y轴和移动速度不就行了?

依法炮制得出下面的完整代码:

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 /// 纹理动画 <summary>
 5 /// 纹理动画
 6 /// </summary>
 7 public class TextureAnimation : MonoBehaviour
 8 {
 9     public bool MoveX = false;//是否移动X
10     public bool ToUp = false;//往上移动
11     public float XSpeed = 0.1f;//X轴移动速度
12     private float offsetX = 0;
13     
14     public bool MoveY = false;//是否移动Y
15     public bool ToLeft = false;//往左移动
16     public float YSpeed = 0.1f;//Y轴移动速度
17     private float offsetY = 0;
18 
19     
20     void FixedUpdate()
21     {
22         if (MoveX)
23         {
24             offsetX = Time.time * XSpeed;
25             if (ToUp) offsetX *= -1;
26         }
27 
28         if (MoveY)
29         {
30             offsetY = Time.time * YSpeed;
31             if (ToLeft) offsetY *= -1;
32         }
33 
34         renderer.material.mainTextureOffset = new Vector2(offsetX, offsetY);    
35     }
36 }

 

我就不多解释了,房东一会儿过来收房租了

真烦,我都租了大半年了,想在续租一个月,因为还有一个月我才上班

原来房租是850一个月,现在居然想收我900一个月

原因是我只续租一个月

我教了一千块押金,他怕我跑了不给水电费,非要我在给一千块

我让他来收电费他也不来,说太冷了。。。。

什么人啊这是。。。

不说了,我先闪了

 

本文链接:http://www.cnblogs.com/shenggege/p/4264463.html

转载于:https://www.cnblogs.com/shenggege/p/4264463.html

Unity3d Shader UV移动

阅读数 5651

没有更多推荐了,返回首页