【Unity】简单实现生成式电子围栏
三维电子围栏是一种通过使用三维技术和电子设备来建立虚拟围栏,用于监控和控制特定区域的系统。它可以通过使用传感器和摄像头来检测任何越界行为,并及时发出警报。这种技术可以应用于安防领域以及其他需要对特定区域进行监控和防护的场合。
示例下载
实现效果
动态生成
区域标识
警报效果
实现方法
方法很简单下面附上全部代码。通过坐标位置、高度和颜色参数动态生成电子围墙。自由组合,生成多组多样式围栏。
实现代码:
使用两个点的坐标和它们的高度来构建基本网格,然后将其拼接起来形成一整列墙。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
public class ElectronicWallControl : MonoBehaviour
{
public GameObject[] WallPiont;
Vector3[] WallPos;
Dictionary<string, GameObject> WallDic = new Dictionary<string, GameObject>();
GameObject WallFa;
// Start is called before the first frame update
void Start()
{
WallPos = new Vector3[WallPiont.Length];
for (int i = 0; i < WallPiont.Length; i++)
{
//提取gameobjct的坐标
WallPos[i] = WallPiont[i].transform.position+new Vector3(0,0.5f,0);
}
CreateWallMesh("Wall_1", WallPos, 5, Color.blue, 1);
}
public Material WallMat;//参考材质
public void CreateWallMesh(string id, Vector3[] pos, float high, Color colorNew, float intensity = 0.5f)
{
if (!WallDic.ContainsKey(id))
{
GameObject area = new GameObject(id);
if (!WallFa)
{
WallFa = new GameObject();
WallFa.name = "AreaFa";
}
MeshFilter filter = area.AddComponent<MeshFilter>();
MeshRenderer renderer = area.AddComponent<MeshRenderer>();
filter.mesh = CreateMesh(pos, high,out float uvy);//创建网格
Material material = new Material(WallMat);
//float factor = Mathf.Pow(2, intensity);
//material.color = new Color(colorNew.r * factor, colorNew.g * factor, colorNew.b * factor);
material.SetFloat("_UVy", uvy);
material.SetFloat("_High", high);
renderer.sharedMaterial = material;
renderer.receiveShadows = false;
renderer.shadowCastingMode = ShadowCastingMode.Off;
area.transform.parent = WallFa.transform;
WallDic.Add(id, area);
}
else
{
WallDic[id].SetActive(true);
}
}
Mesh CreateMesh(Vector3[] pos, float high,out float dis)
{
int length = pos.Length;
int triLength = length * 6;
Vector3[] vertices = new Vector3[length * 2];
for (int i = 0; i < length; i++)
{
vertices[i] = pos[i];
vertices[i + length] = new Vector3(pos[i].x, pos[i].y + high, pos[i].z);
}
Vector2[] UV = new Vector2[length * 2];
dis = 0;
for (int i = 0; i < length; i++)
{
if (i != 0)
{
dis += Vector3.Distance(vertices[i], vertices[i - 1]);
}
UV[i] = new Vector2(0, dis);
UV[i + length] = new Vector2(high, dis);
}
int[] NewTriangles = new int[triLength];
for (int i = 0; i < length - 1; i++)
{
NewTriangles[i * 6 + 0] = i + length;
NewTriangles[i * 6 + 1] = i + 1;
NewTriangles[i * 6 + 2] = i;
NewTriangles[i * 6 + 3] = i + length + 1;
NewTriangles[i * 6 + 4] = i + 1;
NewTriangles[i * 6 + 5] = i + length;
}
Mesh newMesh = new Mesh();
newMesh.vertices = vertices;
newMesh.triangles = NewTriangles;
newMesh.uv = UV;
return newMesh;
}
}
围栏shader:
Shader "Unlit/EWall"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
[HDR] _Color("Color",Color) = (1,1,1,0)
_Speed("Speed",float) = 1 //幅度
_UVy("UVy",float) = 0 //UV的y值
}
SubShader
{
Tags { "RenderType" = "TransparentCutout" "IgnoreProjector" = "True" "Queue" = "Transparent" }
LOD 100
Cull Off //关闭剔除
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float alpha : TEXCOORD1;
};
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
float _Speed;
float _High;
float _UVy;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.alpha = v.vertex.y / _High;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed2 uv = fixed2(i.uv.x - _Speed * _Time.y,i.uv.y );
fixed4 col = tex2D(_MainTex, uv)* _Color;
fixed speed = _Speed*5 * _Time.w+ uv.y;//围栏生成动画
float lerpVauel;
if (_UVy> speed)
{
lerpVauel = 0;
}
else
{
lerpVauel = 1;
}
fixed4 newcol = lerp(fixed4(1, 1, 1, 0), fixed4(col.xyz, 1-i.alpha), lerpVauel);
return newcol;
}
ENDCG
}
}
}