unity弹弹效果

Shader "Elastic"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _Position("xyz:position,w:range",vector) = (0,0,0,1)
        _Normal("xyz:normal,w:intensity",vector) = (0,1,0,0)
        _PointTime("point time",float) = 0
        _Duration("duration",float) = 2
        _Frequency("frequency",float) = 5
    }
        SubShader
        {
            Tags { "RenderType" = "Opaque" }
            LOD 100
 
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                // make fog work
                #pragma multi_compile_fog
 
                #include "UnityCG.cginc"
 
                struct appdata
                {
                    float4 vertex : POSITION;
                    float2 uv : TEXCOORD0;
                };
 
                struct v2f
                {
                    float2 uv : TEXCOORD0;
                    UNITY_FOG_COORDS(1)
                    float4 vertex : SV_POSITION;
                };
 
                sampler2D _MainTex;
                float4 _MainTex_ST;
                float4 _Position;
                float4 _Normal;
                float _PointTime;
                float _Duration;
                float _Frequency;
                v2f vert(appdata v)
                {
                    v2f o;
                    float t = _Time.y - _PointTime;
                    if (t>0&&t<_Duration)
                    {
                        float r = 1 - saturate(length(v.vertex.xyz - _Position.xyz) / _Position.w);
                        float l = 1 - t / _Duration;
                        v.vertex.xyz += r * l * _Normal.xyz * _Normal.w * cos(t * _Frequency);
                    }
                        o.vertex = UnityObjectToClipPos(v.vertex);
                        o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                        UNITY_TRANSFER_FOG(o, o.vertex);
                    return o;
                }
 
                fixed4 frag(v2f i) : SV_Target
                {
                    fixed4 col = tex2D(_MainTex, i.uv);
                    UNITY_APPLY_FOG(i.fogCoord, col);
                    return col;
                }
            ENDCG
        }
        }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

interface IElastic
{
    void OnElastic(RaycastHit hit);
}
[RequireComponent(typeof(MeshRenderer))]
public class ElasticObject : MonoBehaviour, IElastic
{
    private static int s_pos, s_nor, s_time;
    static ElasticObject()
    {
        s_pos = Shader.PropertyToID("_Position");
        s_nor = Shader.PropertyToID("_Normal");
        s_time = Shader.PropertyToID("_PointTime");
    }
    private MeshRenderer mesh;
    private void Start()
    {
        mesh = GetComponent<MeshRenderer>();
    }
    //调用该方法
    public void OnElastic(RaycastHit hit)
    {
        //反弹的坐标
        Vector4 v = transform.InverseTransformPoint(hit.point);
        //受影响顶点范围的半径
        v.w = 0.6f;
        mesh.material.SetVector(s_pos, v);
        //法线方向,该值为顶点偏移方向,可自己根据需求传。
        v = transform.InverseTransformDirection(hit.normal.normalized);
        //反弹力度
        v.w = 0.2f;
        mesh.material.SetVector(s_nor, v);
        //重置时间
        mesh.material.SetFloat(s_time, Time.time);
    }

    private void Update()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if (Input.GetMouseButtonDown(0))
        {
            if (Physics.Raycast(ray, out hit))
            {
                OnElastic(hit);
            }
        }
      
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_41995872/article/details/86014720