当前位置:网站首页>Unity3d+moba+ skill indicator (II)
Unity3d+moba+ skill indicator (II)
2022-07-23 12:53:00 【Sixi Liyu】
2.3 Indicator picture highlights shader
newly build shader, The code is as follows
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
}
}
}
}Originally used shader

Effect of formation

Use highlight shader after

2.4 Sector range indicator
Here is to dynamically generate a sector mesh, Achieve the effect to be displayed by setting the angle and radius . Dynamically generate sectors mesh The code is as follows :
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>
/// Create a sector Mesh
/// </summary>
/// <param name="radius"> Fan half price </param>
/// <param name="angleDegree"> Fan angle </param>
/// <param name="segments"> Segment number of sector arc </param>
/// <param name="angleDegreePrecision"> Sector angle accuracy ( Within the accuracy range , Think it's the same angle )</param>
/// <param name="radiusPrecision">
/// <pre>
/// Sector half price accuracy ( Within the range of half price accuracy , It is considered to be the same half price ).
/// such as : The half price accuracy is 1000, be :1.001 and 1.002 It is not considered the same radius . Because zoom in 1000 Times are not equal .
/// If the half price precision is set to 100, be 1.001 and 1.002 Can be considered equal .
/// </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];// All vertex data
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);
// Generate vertex data
for (int i = 1; i < vertices.Length; i++)
{
vertices[i] = new Vector3(Mathf.Cos(currAngle) * radius, 0, Mathf.Sin(currAngle) * radius);
currAngle -= deltaAngle;
}
// Generate triangle data
int[] triangles = new int[segments * 3];// Yes segments Triangles , Every time 3 Data form a triangle
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;
// Texture coordinates
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 : Grid components , It is mainly used to set the shape and appearance .3d Models are made of N Triangle formation , and mesh It is a collection of description information , establish mesh grid : It should be in the following order :1) Assign vertices 2) Assign triangles .
As shown in the figure :

Generate a sector Mesh, from 10 Three small triangles form . The total number of vertices is 12. The first 0 The coordinates of the two vertices are (0,0,0), And then to z The axis is positive , Calculate the coordinates of each fixed point in turn .
// Generate vertex data
for (int i = 1; i < vertices.Length; i++)
{
vertices[i] = new Vector3(Mathf.Cos(currAngle) * radius, 0, Mathf.Sin(currAngle) * radius);
currAngle -= deltaAngle;
}With all the vertex coordinates , Assign triangles .mesh.triangles For one int[], The quantity must be 3 Multiple , Every time 3 One for a group , Each value is from index number to mesh.vertices Find the corresponding coordinate data in .
// Generate triangle data
int[] triangles = new int[segments * 3];// Yes segments Triangles , Every time 3 Data form a triangle
for (int i = 0, vi = 1; i < triangles.Length; i += 3, vi++)
{
triangles[i] = 0;
triangles[i + 1] = vi;
triangles[i + 2] = vi + 1;
}Finally, set the fan according to the casting distance and influence radius of the skill mesh Parameters .

2.5 Selective skill indicator
This kind is the same as the fan , There is no need to set the degree , Use a default selection degree , for example 60 degree . When there is 1 Enemies in this choice sector 60 Within degrees , He is the target . If there are multiple enemies in range , Select the one closest to the included angle of the central ray . As shown in the figure :
1. When there is no enemy in the sector of the selection indicator

2. When there is an enemy in the sector of the selection indicator , The selected enemy has a red column on his head ( Later use the light of God to do )

3. When there are multiple enemies in the selection range , Select the one closest to the central ray

The code is as follows :
/// <summary>
/// Select the prompt
/// </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;// Skill radius
Vector3 pos = transform.position;
Collider[] bufCollider = Physics.OverlapSphere(pos, fRadius);// Get surrounding members
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)// Not our party , Alive , so
{
listUnit.Add(unit);
}
}
}
float minDegree = m_selectDegree/2.0f;
// Screen again within the large circle 1. Meet the included angle of the selection range ,2. The angle from the center ray is the smallest
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;
}Among them, we should pay attention to the selected red column , There can only be one in the scene ( Selected skills can only attack one person at a time ), When I have a choice of goals , Set the parent node of the red column as the target ( Achieve red pillar to follow the target within the selection range ), When I don't exist, choose a goal , The red column is not activated , And put it back pool In the child nodes of the pool . The code is as follows :
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);
}
}边栏推荐
- C custom set
- Hcip --- BGP --- border gateway protocol
- 学习日记——(路由与交换技术)动态路由(rip协议)和静态路由
- Unity3d:UGUI,UI与特效粒子层级,2018.2以上版本BakeMesh,粒子在两个Image之间且在ScrollView
- Learning diary - (routing and switching technology) dynamic routing (RIP protocol) and static routing
- HCIP---BGP ---边界网关协议
- [Reading Notes "Phoenix architecture" - a large-scale distributed system with reliable architecture. Zhou Zhiming] (I)
- WebSocket 协议讲解
- Htpasswd action
- 围棋能力概念与软件开发能力概念的对应
猜你喜欢

MySQL performance optimization, index optimization

Routing and switching technology - static routing

Unity3d:场景加载 GameObejct上脚本执行顺序

Unity3d:ugui, UI and special effect particle level, bakemesh above 2018.2, particles between two images and in Scrollview

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

学习日记——(路由与交换技术)动态路由(rip协议)和静态路由

DNS域名解析服务

C语言也能写植物大战僵尸

【读书笔记《凤凰架构》- 构架可靠的大型分布式系统.周志明】(一)

WebSocket 协议讲解
随机推荐
Instant messaging websocket
Unity3d: special effect object pool, timeout delete GameObject in the pool, GC weight
[AUTOSAR DCM 1. module introduction (DSL, DSD, DSP)]
Sql Server性能分析,查看慢查询
How to write a web page with a common text editor
HCIP---GRE协议和MGRE环境,以及OSPF协议的相关知识点
学习日记——(路由与交换技术)动态路由(rip协议)和静态路由
Hcip --- mGRE comprehensive experiment
Unity3d:场景加载 GameObejct上脚本执行顺序
Htpasswd action
详解TCP的流量控制机制与拥塞控制机制
Explain the release of TCP connection in detail
How far is the first kind of mistake from us
详解TCP连接的释放
【读书笔记《凤凰架构》- 构架可靠的大型分布式系统.周志明】(一)
C# 自定义双向链表
Unity3d:特效对象池,超时删除池内GameObject,GC权值
在二叉排序树中删除节点
深入解析Redis中的复制
Routing extension configuration of OSPF and rip