一週小結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:以後完成消息訂閱的功能,或者事件冒泡

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