欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

unity 鼠标实时画箭头

程序员文章站 2022-05-22 12:41:08
...

pc端的QQ与微信截图里都有个拖拽鼠标画箭头的功能以至于好做标注,其实unity也可以实现这个功能,亲测在webgl端与pc端可用,移动端由于感觉没意义没测试,博主觉得应该没啥问题,主要思路就是:箭头由线段和图片组成,鼠标可以实时改变箭头长短和方向(箭头的方向我暂时只是在2维下画的,绕着z轴实时旋转就行,一点向量基础就行),鼠标按下出现一个三角箭头,鼠标滑动就绘制出线段,线段可跟着你的鼠标变长变短,变粗这块博主很苦恼(因为男人嘛都要粗unity 鼠标实时画箭头),由于最近一直在研究OpenGL,所以线段是用GL画的,性能这块没得说,dc不会随着线段的条数增加,unity没有提供变粗的方法,那就忍忍吧unity 鼠标实时画箭头,bb了这么多看起来很厉害吧!来张图压压惊:

unity 鼠标实时画箭头

效果看了那就直接看脚本了?

using UnityEngine;
using System.Collections;
public class LinesGL : MonoBehaviour
{
    private  Shader shader;
    private static Material m;
    private GameObject g;//便于查看当前点的坐标信息
    public Vector3[] lp;//存储的点
    private Vector3 s;//开始点
    public GameObject JT;
    private GameObject go;
    private Vector3 Vxyz;
    void Start()
    {
        shader = Shader.Find("Yogi3/ImageEffect/Occlusion");
        m = new Material(shader);
        m.SetColor("_MainColor", new Color(1f, 0.01f, 0.1f, 1f));//修改shader颜色
        g = new GameObject("g");
        lp = new Vector3[0];
        Vxyz = new Vector3(2,0,0);//平行于X轴向量
    }

    void Update()
    {
        Vector3 e;//结束点
        if (Input.GetMouseButtonDown(0))
        {
            s = GetNewPoint();
            //显示的z轴看自己需求赋值,只要在相机前面就行
             go=Instantiate(JT, Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.z * -1.0f) ), Quaternion.identity)as GameObject;
            
        }
        //拖拽便于确定箭头方向
        if (Input.GetMouseButton(0))
        {
            e = GetNewPoint();
            lp = AddLine(lp, s, e, true);
            go.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.z * -1.0f));
            Vector3 Vangle = lp[lp.Length-1] - lp[lp.Length - 2];//最后一条线段
            float angle = Vector3.Angle(Vangle,Vxyz)-90;//三角箭头绕着Z轴旋转 那么就限制与X轴夹角为旋转角度吧
            if (Vangle.y > 0)
            {
                go.transform.eulerAngles = new Vector3(0, 0, angle);
            }
            else
            {
                go.transform.eulerAngles = new Vector3(0, 0, 180-angle);
            }
        }
        if (Input.GetMouseButtonUp(0))
        {
            e = GetNewPoint();
            lp = AddLine(lp, s, e, false);

        }
    }
    //判断最后一个点是否鼠标抬起确定了,确定了就存储起来,没有就删除,但是都会绘制出来(绘制了就删除刷新)
    Vector3[] AddLine(Vector3[] l, Vector3 s, Vector3 e, bool tmp)
    {
        int vl = l.Length;
        if (!tmp || vl == 0) l = resizeVertices(l, 2);
        else vl -= 2;

        l[vl] = s;
        l[vl + 1] = e;
        return l;
    }
    //处理拖拽的线条,实时更新
    Vector3[] resizeVertices(Vector3[] ovs, int ns)
    {
        Vector3[] nvs = new Vector3[ovs.Length + ns];
        for (int i = 0; i < ovs.Length; i++) nvs[i] = ovs[i];
        return nvs;
    }
    //反转坐标
    Vector3 GetNewPoint()
    {
        return g.transform.InverseTransformPoint(
            Camera.main.ScreenToWorldPoint(
                new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.z * -1.0f)
            )
        );
    }
    void OnPostRender()
    {
        m.SetPass(0);
        GL.PushMatrix();
        GL.MultMatrix(g.transform.transform.localToWorldMatrix);
        GL.Begin(GL.LINES);
        for (int i = 0; i < lp.Length; i++)
        {
            GL.Vertex3(lp[i].x, lp[i].y, lp[i].z);
        }
        GL.End();
        GL.PopMatrix();
    }

}



其实我想说说shader的在看看效果:

unity 鼠标实时画箭头

线段shader的是自己写的,图片的shader是默认的,是的没错,线段是透视的,不会被物体挡住的,但是会被UI挡住,最近迷上了图形学,捣鼓了大变天实现了屎样的效果,简直了,顺便贴出shader,

Shader "Yogi3/ImageEffect/Occlusion"  
{  
    Properties  
    {  
        _MainTex("Base (RGB)", 2D) = "white" {}  
        _DepthMap("DepthMap (RGB)", 2D) = "white" {}  
        _OcclusionMap("OcclusionMap (RGB)", 2D) = "white" {}  
        _Intensity("Intensity", Float) = 0.0  
        _Tiling("Tiling", Vector) = (1.0, 1.0, 0.0, 0.0)  
		_MainColor("MainsColor",Color)=(1,1,1,1)
    }  
  
    SubShader  
    {  
        Pass  
        {  
            ZTest Always  
            ZWrite Off  
            Cull Off  
            Fog{ Mode Off }  
  
            CGPROGRAM  
            #include "UnityCG.cginc"  
            #pragma vertex vert  
            #pragma fragment frag  
            #pragma fragmentoption ARB_precision_hint_fastest  
  
            sampler2D _MainTex;  
            sampler2D _DepthMap;  
            sampler2D _OcclusionMap;  
            sampler2D _CameraDepthNormalsTexture;  
            fixed4 _MainTex_TexelSize;  
            fixed _Intensity;  
            fixed _Power;  
            fixed4 _Tiling;  
			fixed4 _MainColor;

            struct a2v  
            {  
                fixed4 vertex : POSITION;  
                fixed2 texcoord : TEXCOORD0;  
            };  
  
            struct v2f  
            {  
                fixed4 vertex : SV_POSITION;  
                fixed2 uv : TEXCOORD0;  
            };  
  
            v2f vert(a2v v)  
            {  
                v2f o;  
                o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);  
                o.uv = v.texcoord.xy;  
  
                return o;  
            }  
  
            fixed4 frag(v2f i) : SV_Target  
            {  
                fixed4 c = tex2D(_MainTex, i.uv);  
  
                fixed4 depthMap = tex2D(_DepthMap, i.uv);  
                fixed depth = DecodeFloatRG(depthMap.zw);  
                fixed3 normal = DecodeViewNormalStereo(depthMap);  
  
                fixed4 cameraDepthMap = tex2D(_CameraDepthNormalsTexture, i.uv);  
                fixed cameraDepth = DecodeFloatRG(cameraDepthMap.zw);  
  
                fixed4 o = c;  
                if (depth > 0  
                    && cameraDepth < depth)  
                {  
                    fixed2 uv = i.uv * _Tiling.xy + _Tiling.zw;  
                    fixed3 color = tex2D(_OcclusionMap, uv);  
                    fixed nf = saturate(dot(normal, fixed3(0, 0, 1)));  
                    nf = pow(nf, _Intensity);  
                    o.rgb = lerp(color, c.rgb, nf)+_MainColor;  
                }  
				
                return _MainColor;  
				//return o;
            }  
  
            ENDCG  
        }  
    }  
  
    Fallback off  
}