Unity3D+moba+技能指示器(二)
来源:互联网 发布:淘宝怎样买爱情动作片 编辑:程序博客网 时间:2024/05/28 15:13
2.3指示器图片高亮显示shader
新建shader,代码如下
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 OneMinusSrcAlphaCull Off Lighting Off ZWrite Off BindChannels {Bind "Color", colorBind "Vertex", vertexBind "TexCoord", texcoord}SubShader {Pass {//ZTest AlwaysCGPROGRAM #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 GreaterCGPROGRAM #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代码如下:
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<MeshFilter>(); } 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; /// <summary> /// 创建一个扇形Mesh /// </summary> /// <param name="radius">扇形半价</param> /// <param name="angleDegree">扇形角度</param> /// <param name="segments">扇形弧线分段数</param> /// <param name="angleDegreePrecision">扇形角度精度(在满足精度范围内,认为是同个角度)</param> /// <param name="radiusPrecision"> /// <pre> /// 扇形半价精度(在满足半价精度范围内,被认为是同个半价)。 /// 比如:半价精度为1000,则:1.001和1.002不被认为是同个半径。因为放大1000倍之后不相等。 /// 如果半价精度设置为100,则1.001和1.002可认为是相等的。 /// </pre> /// </param> /// <returns></returns> 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轴为正方向,依次计算每个定点坐标。
//生成顶点数据 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中找对应的坐标数据。
//生成三角形数据 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.当有多个敌人在选择范围内,选择离中心射线最近的
代码如下:
/// <summary> /// 选择提示器 /// </summary> /// <param name="skill"></param> /// <param name="obj"></param> 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<UnitCtrl> listUnit = new List<UnitCtrl>(); foreach (var item in bufCollider) { UnitCtrl unit = item.GetComponentInParent<UnitCtrl>(); 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池的子节点中。代码如下:
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<Renderer>(); hintRenderer.material.SetColor("_Color", Color.red); } else { m_headLock.transform.SetParent(m_prefab.transform); m_headLock.transform.localPosition = new Vector3(0, 0, 0); } }
0 0
- Unity3D+moba+技能指示器(二)
- Unity3D+moba+技能指示器(一)
- 怎么做一个MOBA游戏(武器与技能)?
- Unity3d+moba+UGUI摇杆
- Unity3d+moba+小地图
- Unity3d+moba+草丛视野
- Unity3d开发MOBA游戏类《王者荣耀》记录(一)
- Unity3d开发MOBA游戏类《王者荣耀》记录(一)
- Unity3D+moba+小地图视野
- Unity3D 大型游戏 MOBA类手机游戏 部分重点 登陆过程(17)
- 基于 Unity3D 的 MOBA 游戏架构
- Unity3D自学笔记——星际2技能系统分析(二)Ability(Move, Stop, Attack)
- 【TomoEngine】 第十讲 【MOBA制作日记五】 角色技能响应
- unity3d技能冷却cd(第一篇)
- unity3d技能冷却cd(最后一篇)
- [Unity&]技能指示器skill indicator怎么做
- Mysql基础技能(二)
- unity3d 技能编辑器
- 如何检查Oracle表空间使用情况
- 我学过的java3
- Codeforces Round #352(Div 2)
- 2016之web前端面试题,最全最有用
- 解决DELPHI的程序占内存的代码
- Unity3D+moba+技能指示器(二)
- Swift溢出
- delphi基础开发技巧
- nil / Nil / NULL / NSNull
- String to Integer
- Request.Path HttpRequest.ValidateInputIfRequiredByConfig() 异常
- ToolBar的基本使用
- 成为C++高手之宏与枚举
- 易經大意 121_140