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

形成的效果

使用高亮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);  

        }  

    }  

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容