弹弹弹——橡皮效果

http://www.manew.com/thread-140750-1-1.html

挂在需要橡皮效果的物体上:Elastic.shader Elastic.mat ElasticObject.cs

挂在摄像机上:ClickPoint.cs

ElasticObject.cs:

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.5f;
        mesh.material.SetVector(s_nor, v);
        //重置时间
        mesh.material.SetFloat(s_time, Time.time);
    }
}

Elastic.shader

Shader "Yang/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;

ClickPoint.cs


public class ClickPoint : MonoBehaviour {

    // Use this for initialization
    void Start () {
        
    }
    
    // Update is called once per frame
    void Update () {
        if (Input.GetButtonDown("Fire1"))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hitInfo;
            if (Physics.Raycast(ray, out hitInfo, 10000)){
                Debug.Log("hitInfo "+ hitInfo.collider);
                hitInfo.collider.gameObject.GetComponent<ElasticObject>().OnElastic(hitInfo);
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/gepengmiss/article/details/82692327