设计模式——中介者(Unity3d中的应用)

在Unity3D中的感知系统使用的便是一个中介者模式,感知包括视觉感应器、听觉感应器、视觉触发器、听觉触发器等,感应器触发器之间的交互交由中介者来完成,最大程度上实现感应器、触发器直接的解耦。

听觉感应器:

[RequireComponent(typeof(NavMeshAgent))]
    public class HearingSensor:AbstractSensor
    {
        public float hearingDistance;
        public bool IsCheckCover;
        private NavMeshPath path;
        private NavMeshAgent navMeshAgent;
        private Vector3? targetPosition;

        public new void Start()
        {
            base.Start();
            navMeshAgent = GetComponent<NavMeshAgent>();
        }

        public override bool CheckTrigger(AbstractTrigger trigger)
        {
            if (trigger.triggerType == TriggerType.Hearing)
            {
                var tempTrigger = trigger as HearingTrigger;
                float toDistance = tempTrigger.spreadDistance + hearingDistance;
                if (!tempTrigger.IsSounding) return false;
                bool result = tempTrigger.IsSounding && toDistance > 
                    Vector3.Distance(this.transform.position,trigger.gameObject.transform.position);
                if(IsCheckCover && targetPosition != trigger.gameObject.transform.position)
                {
                    targetPosition = trigger.gameObject.transform.position;
                    result = toDistance > PathLength(targetPosition.Value);
                }
                return result;
            }
            return false;
        }

        private float PathLength(Vector3 targetPosition) {
            NavMeshPath path = new NavMeshPath();
            navMeshAgent.CalculatePath(targetPosition, path);
            if (path.corners.Length < 2)
                return 0;
            Vector3 previousCorner = path.corners[0];
            float lengthSoFar = 0.0F;
            int i = 1;
            while (i < path.corners.Length) {
                Vector3 currentCorner = path.corners[i];
                lengthSoFar += Vector3.Distance(previousCorner, currentCorner);
                previousCorner = currentCorner;
                i++;
            }
            return lengthSoFar;
        }

        private void OnDisable()
        {
            targetPosition = null;
        }
    }
}

听觉触发器:

 public class HearingTrigger:AbstractTrigger
    {
        public float spreadDistance;
        private Coroutine coroutine;
        public bool IsSounding;
        public float continueTime;

        public new void Start()
        {
            base.Start();
            triggerType = TriggerType.Hearing;    
        }

        private void OnEnable()
        {
            StartCoroutine(Timer());
        }

        private IEnumerator Timer()
        {
            IsSounding = true;
            yield return new WaitForSeconds(continueTime);
            IsSounding = false;
        }

        private void OnDisable()
        {
            IsSounding = false;
        }
    }
}

中介者:触发器与感应器管理类

public class SensorTriggerManager:MonoSingleton<SensorTriggerManager>
    {
        private List<AbstractSensor> listSensor = new List<AbstractSensor>();
        private List<AbstractTrigger> listTrigger = new List<AbstractTrigger>();
        private float CheckInterval = 1.0f;
        public void AddSensor(AbstractSensor sensor)
        {
            if (!listSensor.Contains(sensor))
                listSensor.Add(sensor);
        }

        public void RemoveSensor(AbstractSensor sensor)
        {
            if (listSensor.Contains(sensor))
                listSensor.Remove(sensor);
        }

        public void AddTrigger(AbstractTrigger trigger)
        {
            if (!listTrigger.Contains(trigger))
                listTrigger.Add(trigger);
        }

        public void RemoveTrigger(AbstractTrigger trigger)
        {
            if (listTrigger.Contains(trigger))
                listTrigger.Remove(trigger);
        }

        private void OnEnable()
        {
            InvokeRepeating("CheckSensor", 0, CheckInterval);
        }

        private void OnDisable()
        {
            CancelInvoke("CheckSeneor");
        }

        private void CheckSensor()
        {
            List<AbstractTrigger> tempList = new List<AbstractTrigger>();
            for (int i = 0; i < listSensor.Count; i++)
            {
                tempList.Clear();
                if (!listSensor[i].enabled)
                    continue;
                for (int j = 0; j < listTrigger.Count; j++)
                {
                    if (listTrigger[j].enabled &&
                        listSensor[i].gameObject != listTrigger[j].gameObject &&
                        listSensor[i].CheckTrigger(listTrigger[j]))
                        tempList.Add(listTrigger[j]);
                }
                if (0 < tempList.Count)
                    listSensor[i].OnSenorInfoNotity(tempList);
                else
                    listSensor[i].OnNoSenorInfoNotity();
            }
        }

    }

当需要扩展感知系统时,比如视觉感知,只需要添加视觉感应器和视觉触发器就可以了。

总结:
中介者模式解决了多对多的情况的耦合问题,而与之相似的观察者则是解决一对多的解耦问题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值