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

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

形成的效果

Unity3D+moba+技能指示器(二)_第1张图片

使用高亮shader后

Unity3D+moba+技能指示器(二)_第2张图片

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)分配三角形.

如图所示:

Unity3D+moba+技能指示器(二)_第3张图片

生成一个扇形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参数。

Unity3D+moba+技能指示器(二)_第4张图片

2.5选择性技能指示器

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

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

Unity3D+moba+技能指示器(二)_第5张图片

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

Unity3D+moba+技能指示器(二)_第6张图片

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

Unity3D+moba+技能指示器(二)_第7张图片

代码如下:

[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+技能指示器(二))