美文网首页Unity
Unity3D+moba+技能指示器(二)

Unity3D+moba+技能指示器(二)

作者: 某人在 | 来源:发表于2018-03-26 19:13 被阅读50次

    2.3指示器图片高亮显示shader

    新建shader,代码如下

    [csharp] view plain copy

    Shader "Custom/SkillHintBg" {  

    Properties {  

    _MainTex ("Base Texture", 2D) = "white" {}  

    _Color ("Main Color", Color) = (1,1,1,1)    

    }  

    Category {  

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

        Blend SrcAlpha OneMinusSrcAlpha  

        Cull Off   

        Lighting Off   

        ZWrite Off   

        BindChannels {  

    Bind"Color", color  

    Bind"Vertex", vertex  

    Bind"TexCoord", texcoord  

        }  

        SubShader {  

            Pass {  

    //ZTest Always  

                CGPROGRAM     

                    #pragma vertex vert    

                    #pragma fragment frag  

                    #include "UnityCG.cginc"     

    struct v2f {     

                        float4 pos : SV_POSITION;     

                        float2 uv : TEXCOORD0;     

                    };     

                    v2f vert(appdata_tan v)     

                    {     

                        v2f o;     

                        o.pos = mul (UNITY_MATRIX_MVP, v.vertex);    

                        o.uv = v.texcoord;   

    return o;      

                    }     

                    sampler2D _MainTex;    

                    float4 _Color;   

                    half4 frag (v2f i) : COLOR     

                    {     

                        half4 result = tex2D (_MainTex, i.uv);   

                        result*=_Color;  

    return result;   

                    }      

                ENDCG   

            }  

            Pass {  

            ZTest Greater  

                CGPROGRAM     

                    #pragma vertex vert    

                    #pragma fragment frag  

                    #include "UnityCG.cginc"     

    struct v2f {     

                        float4 pos : SV_POSITION;     

                        float2 uv : TEXCOORD0;     

                    };     

                    v2f vert(appdata_tan v)     

                    {     

                        v2f o;     

                        o.pos = mul (UNITY_MATRIX_MVP, v.vertex);    

                        o.uv = v.texcoord;   

    return o;      

                    }     

                    sampler2D _MainTex;    

                    float4 _Color;   

                    half4 frag (v2f i) : COLOR     

                    {     

                        half4 result = tex2D (_MainTex, i.uv);   

                        result*=_Color;  

                        result.a /= 3;  

    return result;   

                    }      

                ENDCG   

            }  

        }  

    }  

    }  

    原来使用的shader

    形成的效果

    使用高亮shader后

    2.4 扇形范围指示器

    这里是要动态生成一个扇形mesh,通过设置角度和半径达到要显示的效果。动态生成扇形mesh代码如下:

    [csharp] view plain copy

    using UnityEngine;  

    using System.Collections;  

    [RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))]  

    public class MeshFan : MonoBehaviour  

    {  

    public float radius = 2;  

    public float angleDegree = 100;  

    public int segments = 10;  

    public int angleDegreePrecision = 1000;  

    public int radiusPrecision = 1000;  

    private MeshFilter meshFilter;  

    private SectorMeshCreator creator = new SectorMeshCreator();  

    private Mesh m_mesh;  

        [ExecuteInEditMode]  

    private void Awake()  

        {  

            meshFilter = GetComponent();  

        }  

    private void Update()  

        {  

            meshFilter.mesh = creator.CreateMesh(radius, angleDegree, segments, angleDegreePrecision, radiusPrecision);  

        }  

    void OnDrawGizmos()  

        {  

            Gizmos.color = Color.gray;  

            DrawMesh();  

        }  

    void OnDrawGizmosSelected()  

        {  

            Gizmos.color = Color.green;  

            DrawMesh();  

        }  

    private void DrawMesh()  

        {  

            Mesh mesh = creator.CreateMesh(radius, angleDegree, segments, angleDegreePrecision, radiusPrecision);  

    int[] tris = mesh.triangles;  

    for (int i = 0; i < tris.Length; i += 3)  

            {  

                Gizmos.DrawLine(convert2World(mesh.vertices[tris[i]]), convert2World(mesh.vertices[tris[i + 1]]));  

                Gizmos.DrawLine(convert2World(mesh.vertices[tris[i]]), convert2World(mesh.vertices[tris[i + 2]]));  

                Gizmos.DrawLine(convert2World(mesh.vertices[tris[i + 1]]), convert2World(mesh.vertices[tris[i + 2]]));  

            }  

        }  

    private Vector3 convert2World(Vector3 src)  

        {  

    return transform.TransformPoint(src);  

        }  

    private class SectorMeshCreator  

        {  

    private float radius;  

    private float angleDegree;  

    private int segments;  

    private Mesh cacheMesh;  

    ///   

    /// 创建一个扇形Mesh  

    ///   

    /// 扇形半价  

    /// 扇形角度  

    /// 扇形弧线分段数  

    /// 扇形角度精度(在满足精度范围内,认为是同个角度)  

    ///   

    /// 

      

    /// 扇形半价精度(在满足半价精度范围内,被认为是同个半价)。  

    /// 比如:半价精度为1000,则:1.001和1.002不被认为是同个半径。因为放大1000倍之后不相等。  

    /// 如果半价精度设置为100,则1.001和1.002可认为是相等的。  

    ///   

    ///   

    ///   

    public Mesh CreateMesh(float radius, float angleDegree, int segments, int angleDegreePrecision, int radiusPrecision)  

            {  

    if (checkDiff(radius, angleDegree, segments, angleDegreePrecision, radiusPrecision))  

                {  

                    Mesh newMesh = Create(radius, angleDegree, segments);  

    if (newMesh != null)  

                    {  

                        cacheMesh = newMesh;  

    this.radius = radius;  

    this.angleDegree = angleDegree;  

    this.segments = segments;  

                    }  

                }  

    return cacheMesh;  

            }  

    private Mesh Create(float radius, float angleDegree, int segments)  

            {  

    if (segments == 0)  

                {  

                    segments = 1;  

    #if UNITY_EDITOR  

    Debug.Log("segments must be larger than zero.");  

    #endif  

                }  

    Mesh mesh =new Mesh();  

    Vector3[] vertices =new Vector3[3 + segments - 1];//全部的顶点数据  

    vertices[0] =new Vector3(0, 0, 0);  

    float angle = Mathf.Deg2Rad * angleDegree;  

    float currAngle = angle / 2;  

    float deltaAngle = angle / segments;  

                currAngle = Mathf.Deg2Rad * (90 + angleDegree / 2);  

    //生成顶点数据  

    for (int i = 1; i < vertices.Length; i++)  

                {  

    vertices[i] =new Vector3(Mathf.Cos(currAngle) * radius, 0, Mathf.Sin(currAngle) * radius);  

                    currAngle -= deltaAngle;  

                }  

    //生成三角形数据  

    int[] triangles = new int[segments * 3];//有segments个三角形,每3个数据构成一个三角形  

    for (int i = 0, vi = 1; i < triangles.Length; i += 3, vi++)  

                {  

                    triangles[i] = 0;  

                    triangles[i + 1] = vi;  

                    triangles[i + 2] = vi + 1;  

                }  

                mesh.vertices = vertices;  

                mesh.triangles = triangles;  

    //纹理坐标  

    Vector2[] uvs =new Vector2[vertices.Length];  

    for (int i = 0; i < uvs.Length; i++)  

                {  

    uvs[i] =new Vector2(vertices[i].x, vertices[i].z);  

                }  

                mesh.uv = uvs;  

    return mesh;  

            }  

    private bool checkDiff(float radius, float angleDegree, int segments, int angleDegreePrecision, int radiusPrecision)  

            {  

    return segments != this.segments || (int)((angleDegree - this.angleDegree) * angleDegreePrecision) != 0 ||  

    (int)((radius - this.radius) * radiusPrecision) != 0;  

            }  

        }  

    }  

    Mesh :网格组件,主要用于设置外形和外表。3d模型都是由N个三角形构成,而mesh就是保存描述信息的集合,创建mesh网格:应该按照以下顺序:1)分配顶点2)分配三角形.

    如图所示:

    生成一个扇形Mesh,由10个小三角形构成。顶点总数数为12.第0个顶点坐标为(0,0,0),然后以z轴为正方向,依次计算每个定点坐标。

    [csharp] view plain copy

    //生成顶点数据  

    for (int i = 1; i < vertices.Length; i++)  

                {  

    vertices[i] =new Vector3(Mathf.Cos(currAngle) * radius, 0, Mathf.Sin(currAngle) * radius);  

                    currAngle -= deltaAngle;  

                }  

    有了所有顶点坐标后,分配三角形。mesh.triangles为一个int[],数量一定是3的倍数,每3个为一组,每个值为索引号到mesh.vertices中找对应的坐标数据。

    [csharp] view plain copy

    //生成三角形数据  

    int[] triangles = new int[segments * 3];//有segments个三角形,每3个数据构成一个三角形  

    for (int i = 0, vi = 1; i < triangles.Length; i += 3, vi++)  

                {  

                    triangles[i] = 0;  

                    triangles[i + 1] = vi;  

                    triangles[i + 2] = vi + 1;  

                }  

    最后根据技能的施法距离和影响半径设置扇形mesh参数。

    2.5选择性技能指示器

    这类和扇形一样,就是不需要设置度数,使用一个默认的选择度数,例如60度。当有1个敌人在这个选择扇形的60度之内,他就是目标。如果有多个敌人在范围之内,选取离中心射线夹角最近的。如图所示:

    1.当选择指示器的扇形范围内没敌人

    2.当选择指示器的扇形范围内有一个敌人,那个选中的敌人头上显示红柱子(后期使用上帝之光来做)

    3.当有多个敌人在选择范围内,选择离中心射线最近的

    代码如下:

    [csharp] view plain copy

    ///   

    /// 选择提示器  

    ///   

    ///   

    ///   

    public UnitCtrl tarSelect(SkillCtrl skill,GameObject obj)  

        {  

    UnitCtrl unitSelect =null;  

    float fRadius = 0.0f;  

    fRadius = skill.m_disRange;//技能的半径  

            Vector3 pos = transform.position;  

    Collider[] bufCollider = Physics.OverlapSphere(pos, fRadius);//获取周围成员  

    List listUnit =new List();  

    foreach (var item in bufCollider)  

            {  

                UnitCtrl unit = item.GetComponentInParent();  

    if (unit != null)  

                {  

    if (!MainMgr.self.isWe(unit.m_camp) && unit.isAlive && unit.m_isVisible)//非我方,活着,可见  

                    {  

                        listUnit.Add(unit);  

                    }      

                }  

            }  

    float minDegree = m_selectDegree/2.0f;  

    //在大圆范围内的再进行筛选  1.满足选择范围夹角,2.离中心射线夹角最小的  

    foreach (var unit in listUnit)  

            {  

                Vector3 unitVec = unit.transform.position - obj.transform.position;  

                Vector3 selectVec = obj.transform.forward;  

    float degree = Vector3.Angle(unitVec, selectVec);  

    if (degree <= minDegree)  

                {  

                    minDegree = degree;  

                    unitSelect = unit;  

                }  

            }  

    if (unitSelect != null)  

            {  

    UIMgr.self.headLockSet(true, unitSelect);  

            }  

    else  

            {  

    UIMgr.self.headLockSet(false, unitSelect);  

            }  

    return unitSelect;  

    }  

    其中要注意的是选中的红柱子,场景内只能有一个(选中型技能一次只能攻击一个人),当我有选择目标时,设置红柱子的父节点为该目标(实现红柱子在选择范围内跟目标走),当我不存在选择目标,红柱子不激活,并且放回pool池的子节点中。代码如下:

    [csharp] view plain copy

    public void headLockSet(bool active,UnitCtrl unit)  

        {  

            m_headLock.SetActive(active);  

    if (active == true)  

            {  

                m_headLock.transform.SetParent(unit.transform);  

    m_headLock.transform.localPosition =new Vector3(0,10,0);  

                Renderer hintRenderer = m_headLock.GetComponent();  

    hintRenderer.material.SetColor("_Color", Color.red);  

            }  

    else  

            {  

                m_headLock.transform.SetParent(m_prefab.transform);  

    m_headLock.transform.localPosition =new Vector3(0, 0, 0);  

            }  

        }  

    相关文章

      网友评论

        本文标题:Unity3D+moba+技能指示器(二)

        本文链接:https://www.haomeiwen.com/subject/lgtdcftx.html