[Unity] Simple implementation of generative electronic fence

[Unity] Simple implementation of generative electronic fence

Three-dimensional electronic fence is a system that uses three-dimensional technology and electronic equipment to build a virtual fence for monitoring and controlling specific areas. It can detect any out-of-bounds behavior by using sensors and cameras and issue timely alerts. This technology can be used in the security field and other situations where specific areas need to be monitored and protected.

Sample download
Realization effect

Dynamically generated

area identification

Alert effect

Implementation

The method is very simple and the entire code is attached below. Dynamically generate electronic fences through coordinate position, height and color parameters. Free combination to generate multiple sets of fences of various styles.

Implementation code:

Use the coordinates of two points and their heights to build a basic grid, which is then stitched together to form an entire column of walls.

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;
    }
}

Fence 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
        }
    }
}

Guess you like

Origin blog.csdn.net/dxs1990/article/details/135015615