#게임unity-VR장면로밍#리셋 함수-관찰자 모드 통합 관리

16722 단어 플레이unityvr
우리는 위와 같은 작업을 카운터인 Timer (이 이름은 적당하지 않을 수도 있음) 로 만들고, 알림을 받아야 하는 사람을 관찰자인 Oberver로 만들고, 다운로드 관리자와 같은 대상을 주제인 Subject로 만들었다.
우선, 우리는 관찰자와 주제의 대상을 정의한다.TimerObserverOrSubject.cs는 다음과 같습니다.
using UnityEngine;  
using System.Collections;  

public class TimerObserverOrSubject : MonoBehaviour {  

    virtual protected void OnDestroy ()  
    {  
        if(Singleton.IsCreatedInstance("TimerController"))  
        {  
            (Singleton.getInstance("TimerController") as TimerController).ClearTimer(this);  
        }  
    }  
}  

TimerObserverOrSubject.cs의 내용은 매우 간단합니다. 이 스크립트가 분석될 때, 카운터 관리자에서 이 대상과 관련된 모든 Timer를 제때에 삭제합니다.
카운터 관리자의 스크립트 - TimerController.cs는 다음과 같습니다.
using UnityEngine;  
using System.Collections;  
using System.Collections.Generic;  

public class TimerController : MonoBehaviour {  

    public delegate void OnCallBack(object arg);  
    public delegate bool OnIsCanDo(object arg);  

    public class Timer {  
        public TimerObserverOrSubject m_Observer;  
        public OnCallBack m_Callback = null;  
        public object m_Arg = null;  

        public TimerObserverOrSubject m_Subject;  
        public OnIsCanDo m_IsCanDoFunc = null;   
        public object m_ArgForIsCanDoFunc = null;  

        public float m_PassTime = 0;  

        public Timer(TimerObserverOrSubject observer, OnCallBack callback, object arg,   
            TimerObserverOrSubject subject, OnIsCanDo isCanDoFunc, object argForIsCanDo) {  
            m_Observer = observer;  
            m_Callback = callback;  
            m_Arg = arg;  

            m_Subject = subject;  
            m_IsCanDoFunc = isCanDoFunc;  
            m_ArgForIsCanDoFunc = argForIsCanDo;  

            m_PassTime = 0;  
                }  

        public Timer(TimerObserverOrSubject observer, OnCallBack callback, object arg, float time) {  
            m_Observer = observer;  
            m_Callback = callback;  
            m_Arg = arg;  

            m_Subject = null;  
            m_IsCanDoFunc = null;  
            m_ArgForIsCanDoFunc = null;  

            m_PassTime = time;  
        }  
        }  
    private List m_Timers = new List();  
    private List m_NeedRemoveTimer = new List();  
    private List m_CurRunTimer = new List();  

    ///   
    /// Sets the timer.  
    ///   
    ///   
    /// The TimerObserverOrSubject you need to listen  
    ///   
    ///   
    /// The callback when condition is true.  
    ///   
    ///   
    /// Argument of the callback.  
    ///   
    ///   
    /// The TimerObserverOrSubject you need to observe  
    ///   
    ///   
    /// The condition function, must return a boolean.  
    ///   
    ///   
    /// Argument for condition function.  
    ///   
    public void SetTimer(TimerObserverOrSubject observer, OnCallBack callback ,object arg,  
        TimerObserverOrSubject subject, OnIsCanDo isCanDoFunc,object argForIsCanDo) {  
        if (observer == null || subject == null || callback == null || isCanDoFunc == null) return;  

        if (isCanDoFunc(argForIsCanDo)) {  
            callback(arg);  
            return;  
        }  

        Timer timer = new Timer(observer, callback, arg, subject, isCanDoFunc, argForIsCanDo);       
        m_Timers.Add(timer);  
    }  

    ///   
    /// Sets the timer.  
    ///   
    ///   
    /// The TimerObserverOrSubject you need to listen  
    ///   
    ///   
    /// The callback when time is up.  
    ///   
    ///   
    /// Argument of the callback.  
    ///   
    ///   
    /// Timepass before calling the callback.  
    ///   
    public void SetTimer(TimerObserverOrSubject observer, OnCallBack callback , object arg, float timepass) {  
        if (observer != null && callback != null) {             
            Timer timer = new Timer(observer, callback, arg, timepass);  
            m_Timers.Add(timer);  
        }  
    }  

    ///   
    /// Clears all Timers of the observer.  
    ///   
    ///   
    /// The TimerObserverOrSubject you need to clear  
    ///   
    public void ClearTimer(TimerObserverOrSubject observer) {  
        List needRemovedTimers = new List();  

        foreach (Timer timer in m_Timers) {  
            if (timer.m_Observer == observer || timer.m_Subject) {  
                needRemovedTimers.Add(timer);  
            }  
        }  

        foreach (Timer timer in needRemovedTimers) {  
            m_Timers.Remove(timer);  
        }  
    }  

        // Update is called once per frame  
        void Update ()   
    {  
        InitialCurTimerDict();  
        RunTimer();  
        RemoveTimer();  
        }  

    private void InitialCurTimerDict() {  
        m_CurRunTimer.Clear();  

        foreach (Timer timer in m_Timers) {  
            m_CurRunTimer.Add(timer);  
        }  
    }  

    private void RunTimer() {  
        m_NeedRemoveTimer.Clear();  

        foreach (Timer timer in m_CurRunTimer) {          
            if (timer.m_IsCanDoFunc == null) {  
                timer.m_PassTime =  timer.m_PassTime - Time.deltaTime;  
                if (timer.m_PassTime < 0) {  
                    timer.m_Callback(timer.m_Arg);  
                    m_NeedRemoveTimer.Add(timer);  
                }  
            } else {  
                if (timer.m_IsCanDoFunc(timer.m_ArgForIsCanDoFunc)) {  
                    timer.m_Callback(timer.m_Arg);  
                    m_NeedRemoveTimer.Add(timer);  
                }  
            }     
        }  
    }  

    private void RemoveTimer() {  
        foreach (Timer timer in m_NeedRemoveTimer) {  
            if (m_Timers.Contains(timer)) {  
                m_Timers.Remove(timer);  
            }  
        }  
    }  

}  

定义了回调函数的类型:

public delegate void OnCallBack(object arg);  
public delegate bool OnIsCanDo(object arg);  

카운터에 대한 정보를 저장하기 위한 데이터 형식 Timer를 정의했습니다.
다음은 TimerController의 두 가지 중요한 SetTimer 함수입니다.첫 번째 SetTimer 함수를 살펴보겠습니다.
public void SetTimer(TimerObserverOrSubject observer, OnCallBack callback ,object arg,  
    TimerObserverOrSubject subject, OnIsCanDo isCanDoFunc,object argForIsCanDo) {  
    if (observer == null || subject == null || callback == null || isCanDoFunc == null) return;  

    if (isCanDoFunc(argForIsCanDo)) {  
        callback(arg);  
        return;  
       }  

    Timer timer = new Timer(observer, callback, arg, subject, isCanDoFunc, argForIsCanDo);       
    m_Timers.Add(timer);  
}  

함수 설명에 의하면,subject의 isCandoFunc(argForIsCando) 함수가true로 되돌아올 때,observer에 알릴 때,observer의callback(arg) 함수를 실행합니다.
두 번째 SetTimer 함수는 더 간단합니다.
public void SetTimer(TimerObserverOrSubject observer, OnCallBack callback , object arg, float timepass) {  
    if (observer != null && callback != null) {             
        Timer timer = new Timer(observer, callback, arg, timepass);  
        m_Timers.Add(timer);  
    }  
}  

타임 패스 시간 후에 observer에 알립니다. observer의 콜백 (arg) 함수를 실행합니다.
Update () 함수에서 모든 Timer를 터치할 수 있는지, 삭제할 필요가 있는지 확인합니다

좋은 웹페이지 즐겨찾기