一周小结2016/8/15--21_Navmesh_事件回调

用NavmeshAgent寻路的时候,如果目标点不能到达的时候,想换个目标点的话,用agent.pathStatus来判断并不合适,可以用CalculatePath来事先判断,然后将得到的NavMeshPath交给agent即可

     

         NavMeshPathpath=newNavMeshPath();
       if(agent.CalculatePath( oldPosition,path))      //判断这个点是否可以到达
        {
           agent.SetPath(path);
        }
       else
        {
           agent.SetDestination(newPosition);
        }

暂停寻路和继续寻路使用 agent.Stop();  agent.Resume();
agent.SamplePathPosition()用来采样位置,根据你传入的目标点,计算在这个点周围多少半径内,是否有可寻路网格         ps:待测



事件回调的一个例子,将事件的监听派发抽离成模块,方便使用

/
// <summary>
/// 事件消息类型
/// </summary>
public enum EventType
{
    None=0,
    Name=1,
}


public class EventManager<T>
{
    private static Dictionary<EventType, List<Action<T>>> m_eventListeners;
    public static Dictionary<EventType, List<Action<T>>> EventListeners
    {
        get
        {
            if (m_eventListeners == null)
            {
                m_eventListeners = new Dictionary<EventType, List<Action<T>>>();
            }
            return m_eventListeners;
        }
    }

    public static void AddEventListener(EventType eventType, Action<T> Function)
    {
        if (EventListeners.ContainsKey(eventType))
        {
            List<Action<T>> eventListener = EventListeners[eventType];
            if(!eventListener.Exists(x=>x==Function))
            {
                eventListener.Add(Function);
            }
        }
        else
        {
            List<Action<T>> eventListener=new List<Action<T>>();
            eventListener.Add(Function);


            EventListeners.Add(eventType,eventListener);
        }
    }

    public static void RemoveEventListener(EventType eventType)
    {
        if (EventListeners.ContainsKey(eventType))
        {
            EventListeners.Remove(eventType);
        }
    }


    public static void RemoveEventListener(EventType eventType, Action<T> Function)
    {
        if (EventListeners.ContainsKey(eventType))
        {
            if (EventListeners[eventType].Contains(Function))
            {
                EventListeners[eventType].Remove(Function);
            }
        }
    }


    public static void DispatchEvent(EventType eventType, T arg)
    {
        if (EventListeners.ContainsKey(eventType))
        {
            List<Action<T>> eventListener = EventListeners[eventType];
            int leng = eventListener.Count;
            for (int i = 0; i < leng; i++)
            {
                Action<T> callBack = eventListener[i];
                callBack(arg);
            }
        }
    }
}



其他脚本里订阅事件,派发事件

<pre name="code" class="csharp">public class EventManagerExercise : MonoBehaviour
{
    void Awake()
    {
        EventManager<bool>.AddEventListener(EventType.Name, PlayerName);
        EventManager<bool>.AddEventListener(EventType.Name, EnemyName);
    }

    private void EnemyName(bool obj)
    {
        if (obj)
        {
            Debug.Log("Enemy的名字");            
        }
    }
    void Start()
    {
        EventManager<bool>.DispatchEvent(EventType.Name, true);
    }
    private void PlayerName(bool obj)
    {
        if (obj)
        {
            Debug.Log("Player的名字");
        }
    }

}

以上的代码订阅事件,派发事件都是全局的,没有实现定向派发事件,加上定向派发事件会增加复杂度。
传递参数的消息传递,直接上代码
public delegate void OnNotificationDelegate(Notification note);
public class NotificationDelegCenter
{
    private static NotificationDelegCenter instance = null;
    private Dictionary<NotificationType, OnNotificationDelegate> eventListerners = new Dictionary<NotificationType, OnNotificationDelegate>();
 
    public static NotificationDelegCenter Instance()
    {
        if (instance == null)
        {
            instance = new NotificationDelegCenter();
            return instance;
        }
        return instance;
    }
  
    //添加监听事件
    public void AddEventListener(NotificationType type, OnNotificationDelegate listener)
    {
        if (!eventListerners.ContainsKey(type))
        {
            OnNotificationDelegate deleg = null;
            eventListerners[type] = deleg;
        }
        eventListerners[type] += listener;
    }

    //移除监听事件
    public void RemoveEventListener(NotificationType type, OnNotificationDelegate listener)
    {
        if (!eventListerners.ContainsKey(type))
        {
            return;
        }
        eventListerners[type] -= listener;
    }

    //移除某一类型所有的监听事件
    public void RemoveEventListener(NotificationType type)
    {
        if (eventListerners.ContainsKey(type))
        {
            eventListerners.Remove(type);
        }
    }


    //派发数据
    public void DispatchEvent(NotificationType type, Notification note)
    {
        if (eventListerners.ContainsKey(type))
        {
            eventListerners[type](note);
        }
    }

    //派发无数据
    public void DispatchEvent(NotificationType type)
    {
        DispatchEvent(type, null);
    }

    //查找是否有当前类型事件监听
    public Boolean hasEventListener(NotificationType type)
    {
        return eventListerners.ContainsKey(type);
    }
}
<pre name="code" class="csharp">public class Notification
{

    public Component sender;
    public String name;
    public object data;

    public Notification(Component aSender, String aName) { sender = aSender; name = aName; data = null; }

    public Notification(Component aSender, String aName, object aData) { sender = aSender; name = aName; data = aData; }
}

public enum NotificationType
{
    Name = 0,
    Sex  = 1,
}

public class NotificationExercise : MonoBehaviour
{
    void Awake()
    {
        NotificationDelegCenter.Instance().AddEventListener(NotificationType.Name,CreatPlayerName);
    }

    void Start()
    {
         object[] objs=new object[2];
        objs[0] = "0";
        objs[1] = 1;
        Notification notifi = new Notification(this, "name", objs);
        NotificationDelegCenter.Instance().DispatchEvent(NotificationType.Name,notifi);
        Debug.Log("开始派发消息");
    }

    private void CreatPlayerName(Notification notification)
    {
        object[] tmpObj = (object[]) notification.data;
        if (tmpObj[0]=="0")
        {
            Debug.Log("派发消息成功了");
        }
    }
}




上面订阅消息和派发消息可以传递参数

ps:以后完成消息订阅的功能,或者事件冒泡

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章