Unity 2d uses two methods (shader textMeshPro) to realize text wave shape respectively

Recently, the text that needs a wave shape (the wrath of the water man)
is probably swaying up and down (left and right) like the sea surface.
You can change the swing speed by doing two.
At the beginning, I used a shader to do it. I
combined this and this to make a

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
			}
		}
}

I didn’t simplify and clean up this section because it’s not very easy to use and if there are flaws, the extra material of the font will be taken.
insert image description here
I hope someone can think of how to use the shader to achieve the perfect goal.

In short, after learning YouTube
, I wrote a better one and needed to use textMeshPro. Anyway, it’s free, so you don’t need it for nothing

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));
    }
}

If you need to change the shape of the wave,
change the Mathf.Sin(time 3.3f), 5 Mathf.Cos(time*2.5f) in the wobble
. The front is x and the back is y. There is not much explanation for
the final effect
insert image description here

Guess you like

Origin blog.csdn.net/weixin_42767868/article/details/123499380