Unity 2d 用两种方式(shader textMeshPro)分别实现文字波浪形态

最近需要波浪形态的文字(水人震怒)
大概就是海面那样上下(左右)摇摆
做了两个 都可以改变摆动速率
一开始用shader来做
结合了这个这个做了一个

Shader "Custom/textWave" {
	Properties{
		_MainTex("Font Texture", 2D) = "white" {}
		_Color("Text Color", Color) = (1,1,1,1)
		_OutlineColor("Outline Color", Color) = (0,0,0,1)
		_StencilComp("Stencil Comparison", Float) = 3.000000
		 _Stencil("Stencil ID", Float) = 1.000000
		 _StencilOp("Stencil Operation", Float) = 0.000000
		 _StencilWriteMask("Stencil Write Mask", Float) = 0.000000
		 _StencilReadMask("Stencil Read Mask", Float) = 1.000000
        _Amplitude ("振幅(最大和最小的幅度)", Range(0, 1)) = 0.3     
        _AngularVelocity ("角速度(圈数)", Range(0, 50)) = 10     
        _Speed ("移动速度", Range(0, 30)) = 10  
	}

		SubShader{

			Tags {
				"Queue" = "Transparent"
				"IgnoreProjector" = "True"
				"RenderType" = "Transparent"
				"PreviewType" = "Plane"
			}

			Lighting Off Cull Off ZTest Always ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha
			Stencil {
				Ref[_Stencil]
				ReadMask[_StencilReadMask]
				WriteMask[_StencilWriteMask]
				Comp[_StencilComp]
				Pass[_StencilOp]
			}
			//ColorMask[_ColorMask]

			//第一个Pass,实现Text内容背景颜色,并向外扩大_OutlineWidth
			Pass {
				CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
				#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
				#include "UnityCG.cginc"

				struct appdata_t {
					float4 vertex : POSITION;
					fixed4 color : COLOR;
					float2 texcoord : TEXCOORD0;
					//UNITY_VERTEX_INPUT_INSTANCE_ID
				};

				struct v2f {
					float4 vertex : SV_POSITION;
					fixed4 color : COLOR;
					float2 texcoord : TEXCOORD0;
					UNITY_VERTEX_OUTPUT_STEREO
				};

				sampler2D _MainTex;
				uniform float4 _MainTex_ST;
				uniform float4 _MainTex_TexelSize;
				uniform fixed4 _Color;
				uniform fixed4 _OutlineColor;


				v2f vert(appdata_t v)
				{
					v2f o;
					UNITY_SETUP_INSTANCE_ID(v);
					UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
					o.vertex = UnityObjectToClipPos(v.vertex);
					o.color = v.color;
					o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
					return o;
				}
				//确定每个像素周围8个像素的坐标。
				static const float2 dirList[9] = {
					float2(-1,-1),float2(0,-1),float2(1,-1),
					float2(-1,0),float2(0,0),float2(1,0),
					float2(-1,1),float2(0,1),float2(1,1)
				};
				//谋取dirList第dirIndex个方位的透明度值。
				float getDirPosAlpha(float index, float2 xy) {
					float2 curPos = xy;
					float2 dir = dirList[index];
					float2 dirPos = curPos + dir * _MainTex_TexelSize.xy *0;
					return tex2D(_MainTex, dirPos).a;
				};
				//对于每个像素,传入片元参数v2f i ,获取次像素周围和自身的共9个像素进行透明度叠加。
				//那么得出的结果就是非透明的区域被放大了,形成了黑边。
				float getShadowAlpha(float2 xy) {
					float a = 0;
					float index = 0;
					a += getDirPosAlpha(index, xy);
					// a += getDirPosAlpha(index++, xy);
					// a += getDirPosAlpha(index++, xy);
					// a += getDirPosAlpha(index++, xy);
					// a += getDirPosAlpha(index++, xy);
					// a += getDirPosAlpha(index++, xy);
					// a += getDirPosAlpha(index++, xy);
					// a += getDirPosAlpha(index++, xy);
					// a += getDirPosAlpha(index++, xy);
					a = clamp(a,0,1);
					return a;
				}

                
                float _Amplitude;     
                float _AngularVelocity;     
                float _Speed;  

				//由于渲染Text内容时,Text字上没有被渲染的区域是透明的,也就是透明度a值是0,
				//所以只要将有内容的区域往外透明度为0的区域扩展一些像素将就能够形成描边效果。
				fixed4 frag(v2f i) : SV_Target
				{
                    i.texcoord.y += (_Amplitude * sin(_AngularVelocity * i.texcoord.x + _Speed * _Time.y));
					fixed4 col = i.color;//_OutlineColor;
					float2 xy = i.texcoord.xy;
					col.a *= getShadowAlpha(xy);
					return col;
				}
				ENDCG
			}
		}
}

没有把这段简化 清理是因为不是很好用 而且有瑕疵 会取到字体的额外材质
在这里插入图片描述
希望有大神能想到怎么用shader达成完美目标

总之 在学习油管之后
写了个比较好的 需要用textMeshPro 反正是免费的 不用白不用

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class textWaveMesh : MonoBehaviour
{
    public TMP_Text tmpText;
    public Mesh mesh;
    public Vector3[] myVecs;


    void Update()
    {
        tmpText.ForceMeshUpdate();
        mesh=tmpText.mesh;
        myVecs=mesh.vertices;
        for (int i = 0; i < tmpText.textInfo.characterCount; i++)
        {
            TMP_CharacterInfo c = tmpText.textInfo.characterInfo[i];

            int index = c.vertexIndex;

            Vector3 offset = Wobble(Time.time + i);
            myVecs[index] += offset;
            myVecs[index + 1] += offset;
            myVecs[index + 2] += offset;
            myVecs[index + 3] += offset;
        }

        mesh.vertices = myVecs;
        tmpText.canvasRenderer.SetMesh(mesh);
        
    }
    Vector2 Wobble(float time) {
        return new Vector2(Mathf.Sin(time*3.3f), 5*Mathf.Cos(time*2.5f));
    }
}

需要改变波浪的形态的
改wobble里面的Mathf.Sin(time3.3f), 5Mathf.Cos(time*2.5f)
前面是x后面是y 不多解释了
最后效果
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值