美文网首页
Unity_一个关于自蔓延性的神经元功能

Unity_一个关于自蔓延性的神经元功能

作者: UnityLin | 来源:发表于2017-11-03 15:26 被阅读0次
    效果图.png

    如图:随意点击一个按键,开启检测,当连线触发到另外一个按键的时候,会检测他需要连接的其他物体。这种功能类似我们的大脑神经元。废话不多说,直接上代码(需要用到Vectrosity插件,下载地址:链接:http://pan.baidu.com/s/1hs7u7cg 密码:zq1w):
    1.新建一个脚本,这个脚本用来计时,并且整个系统的初始化方法也在这

    using System.Collections;
    using UnityEngine;
    ///游戏控制器,挂载在摄像机上
    public class GameMgr : MonoBehaviour
    {
        private static GameMgr instance;
    
        public static GameMgr Instance
        {
            get
            {
                return instance;
            }
        }
    
        /// <summary>
        /// 计时器
        /// </summary>
        private float timer = 0.1f;
        /// <summary>
        /// 时长
        /// </summary>
        private float duration = 0.1f;
    
        private void Awake()
        {
            instance = this;
        }
    
        private void Update()
        {
            timer += Time.deltaTime;
            if (timer >= duration)
            {
                GlobalData.running = true;
                timer = 0;
            }
            else
            {
                GlobalData.running = false;
            }
        }
        /// <summary>
        /// 神经元路径初始化
        /// </summary>
        public IEnumerator NeurePathReset()
        {
            Debug.Log("重置神经元路径");
            yield return new WaitForSeconds(3f);
            GlobalData.connectStart = false;
            GlobalData.connectOver = false;
            for (int i = 0; i < GlobalData.connectPath.Count; i++)
            {
                GameObject obj = GlobalData.connectPath[i].gameObject;
                GlobalData.connectPath[i].ResetNeure();
                ObjectPools.Instance.IntoPool(obj, "Path");
            }
        }
    
    }
    

    2.在写一个对象池,挂载在摄像机上(画线的物体使用对象池,减少消耗)

    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 对象池(用路径来创建池)
    /// </summary>
    public class ObjectPools : MonoBehaviour
    {
        private static ObjectPools instance;
    
        /// <summary>
        /// 对象池管理字典{池名 : 池内对象 }
        /// </summary>
        Dictionary<string, List<GameObject>> PoolController = new Dictionary<string, List<GameObject>>() { };
    
        public static ObjectPools Instance
        {
            get
            {
                return instance;
            }
    
            set
            {
                instance = value;
            }
        }
    
        void Awake()
        {
            instance = this;
        }
    
        /// <summary>
        /// 对象池名字
        /// </summary>
        /// <param name="poolName">对象池的名字为该物体Resources下路径</param>
        /// <returns></returns>
        public GameObject GetPool(string poolName)
        {
            GameObject obj;
            if (PoolController.ContainsKey(poolName) && PoolController[poolName].Count > 0)
            {            
                obj = PoolController[poolName][0];
                PoolController[poolName].RemoveAt(0);//把第一个位置释放;
            }
            else if (PoolController.ContainsKey(poolName) && PoolController[poolName].Count <= 0)
            {
    
                obj = Instantiate(Resources.Load<GameObject>(poolName));
            }
            else 
            {
                obj = Instantiate(Resources.Load<GameObject>(poolName));
                PoolController.Add(poolName, new List<GameObject>() { });
            }
            obj.SetActive(true);
            return obj;
        }
    
        /// <summary>
        /// 放入池子中的方法
        /// </summary>
        /// <param name="go"></param>
        public void IntoPool(GameObject obj,string key)
        {
            obj.transform.parent = null;
            obj.SetActive(false);
            PoolController[key].Add(obj);
        }
    
    }
    
    1. 新建一个脚本,存储数据
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public static class GlobalData
    {
        /// <summary>
        /// 开启连接检测?
        /// </summary>
        public static bool connectStart = false;
        /// <summary>
        /// 连接线是否开始  --  经纬度画线控制
        /// </summary>
        public static bool running;
        /// <summary>
        /// 所有相关联的连接是否完成
        /// </summary>
        public static bool connectOver;
        /// <summary>
        /// 连接路径
        /// </summary>
        public static List<Path> connectPath = new List<Path>();
    }
    
    

    4.新建一个类,用来管理Tag值

    public class Tags
    {
        /// <summary>
        /// 神经元标签
        /// </summary>
        public const string Neure = "Neure";
        /// <summary>
        /// 路径标签
        /// </summary>
        public const string Path = "Path";
    }
    

    5.接下来是重点:新建一个脚本,神经元脚本,这个脚本挂载在每一个需要检测的物体身上(改物体的Tag值为:Neure)

    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class Neure : MonoBehaviour
    {
        private Button OnClick;
        /// <summary>
        /// 是否被触发
        /// </summary>
        [HideInInspector]
        public bool isTrigger = false;
        /// <summary>
        /// 检测其他神经元
        /// </summary>
        List<Neure> checkNeure = new List<Neure>();
    
        private void Awake()
        {
            OnClick = transform.GetComponent<Button>();
            OnClick.onClick.AddListener(
                ()=>
                {
                    GlobalData.connectStart = true;
                    CheckOtherNeure();
                });
        }
    
        /// <summary>
        /// 检测其他神经元网络
        /// </summary>
        public void CheckOtherNeure()
        {
            if (GameObject.FindGameObjectsWithTag(Tags.Neure).Length <= 1)
            {
                return;
            }
            checkNeure.Clear();
            this.isTrigger = true;
            for (int i = 0; i < GameObject.FindGameObjectsWithTag(Tags.Neure).Length; i++)
            {
                Neure neure = GameObject.FindGameObjectsWithTag(Tags.Neure)[i].GetComponent<Neure>();
                if (neure.isTrigger == false)
                {
                    checkNeure.Add(neure);
                }
            }
            if (checkNeure.Count != 0)
            {
                StartConnectOtherNeure();
            }
        }
    
        /// <summary>
        /// 开始连接其他神经元
        /// </summary>
        private void StartConnectOtherNeure()
        {
            for (int i = 0; i < checkNeure.Count; i++)
            {
                GameObject obj = ObjectPools.Instance.GetPool("Path");
                obj.transform.SetParent(transform);
                obj.transform.localPosition = Vector3.zero;
                obj.transform.localScale = new Vector3(1, 1, 1);
                obj.GetComponent<Path>().sponsorNeure = this;
                obj.GetComponent<Path>().ConnectOtherNeure(checkNeure[i]);
            }       
        }
    }
    
    

    6.新建一个空物体,放到Resources文件夹下(Tag值为Path)


    LGFGR99M@8F8SM@VP7@QYI0.png
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using Vectrosity;
    
    public class Path : MonoBehaviour
    {
        /// <summary>
        /// 两点之间的距离
        /// </summary>
        private int DistanceBetweenPoints = 1;
        /// <summary>
        ///  发起者神经元
        /// </summary>
        [HideInInspector]
        public Neure sponsorNeure;
        /// <summary>
        /// 目标点
        /// </summary>
        [HideInInspector]
        public Neure targetNeure;
        /// <summary>
        /// 路径
        /// </summary>
        private VectorLine pathLine;
        /// <summary>
        /// 画线材质
        /// </summary>
        public Material lineMaterial;
        /// <summary>
        /// 方向向量
        /// </summary>
        private Vector3 direction;
        /// <summary>
        /// 偏移向量
        /// </summary>
        private Vector3 offsetDirection;
        /// <summary>
        /// 路径被分割的点
        /// </summary>
        private int pathCount = 0;
        /// <summary>
        /// 下标
        /// </summary>
        private int index = 0;
    
        private bool isCallBack = false;
        private void Update()
        {
            if (GlobalData.connectStart == false)
            {
                return;
            }
            if (index >= pathCount)  // 该条神经元连接完毕
            {
                if (isCallBack == false)
                {
                    isCallBack = true;
                    GlobalData.connectPath.Add(this);
                    ConnectSuccseCallBack();
                    targetNeure.CheckOtherNeure();
                }
                return;
            }
            if (GlobalData.running && pathCount != 0)
            {
                index++;
                transform.position = index * direction / pathCount - offsetDirection;
                pathLine.points3.Add(transform.position);
                pathLine.Draw();
            }
        }
    
        /// <summary>
        /// 链接其他神经元
        /// </summary>
        public void ConnectOtherNeure(Neure neure)
        {
            targetNeure = neure;
            direction = targetNeure.transform.position - transform.position;
            offsetDirection = Vector3.zero - transform.position;
            pathCount = (int)(Vector3.Distance(transform.position, neure.transform.position) / DistanceBetweenPoints);
            index = 0;
            pathLine = new VectorLine("Path", new List<Vector3>(), lineMaterial, 12.0f, LineType.Continuous);
            pathLine.textureScale = 1.0f;
            pathLine.points3.Add(transform.position);
        }
    
        /// <summary>
        /// 连接成功回调
        /// </summary>
        private void ConnectSuccseCallBack()
        {
            for (int i = 0; i < GameObject.FindGameObjectsWithTag(Tags.Path).Length; i++)
            {
                if (GameObject.FindGameObjectsWithTag(Tags.Path)[i].GetComponent<Path>().isCallBack == false)
                {
                    Debug.Log("还未链接完毕");
                    break;
                }
                if (i == GameObject.FindGameObjectsWithTag(Tags.Path).Length - 1)
                {
                    GlobalData.connectOver = true;
                    StartCoroutine(GameMgr.Instance.NeurePathReset());
                    Debug.Log("链接完毕");
                }
            }
        }
    
        /// <summary>
        /// 清空该条神经元上的所有数据
        /// </summary>
        public void ResetNeure()
        {
            isCallBack = false;
            index = 0;
            pathCount = 0;
            sponsorNeure.isTrigger = false;
            targetNeure.isTrigger = false;
            pathLine.points3.Clear();
            pathLine.Draw();
        }
    }
    
    

    相关文章

      网友评论

          本文标题:Unity_一个关于自蔓延性的神经元功能

          本文链接:https://www.haomeiwen.com/subject/igutmxtx.html