Exemplo n.º 1
0
        public void Update(float tDelta)
        {
            //현재 재생중인 유닛이 있다면 시작
            _isUpdated = false;
            if (_nPlayedUnit > 0)
            {
                //업데이트..
                //Debug.Log("Update Queue");
                for (int i = 0; i < _nPlayedUnit; i++)
                {
                    _tmpCurPlayUnit = _animPlayUnits[i];
                    _tmpCurPlayUnit.SetWeight(0.0f, false);                    //<<일단 Weight를 0으로 둔다.
                    _tmpCurPlayUnit.Update(tDelta);

                    _isUpdated = true;
                    if (_tmpCurPlayUnit.IsRemovable)
                    {
                        //TODO : 이 객체와 연결된 CalculatedParam에 AnimClip이 사라졌음을 알려야한다.
                        //Debug.LogError("TODO : 이 객체와 연결된 CalculatedParam에 AnimClip이 사라졌음을 알려야한다");
                        _tmpCurPlayUnit.SetWeight(0.0f, true);
                        _isAnyUnitChanged = true;
                    }
                }

                _isInitPlayUnit = false;
            }
            else
            {
                //만약 _nPlayedUnit = 0인 상태로 한번도 초기화를 안했다면..
                if (!_isInitPlayUnit)
                {
                    _isInitPlayUnit = true;
                }
            }

            apAnimPlayRequest curRequest = null;


            if (_requests_Live.Count > 0)
            {
                //Debug.Log("----------------- Request Update[" + _requests_Live.Count + "] ---------------------");
                //Request를 업데이트하고
                //각 Request별로 연관된 PlayUnit의 Weight를 지정해주자
                for (int iCur = 0; iCur < _requests_Live.Count; iCur++)
                {
                    curRequest = _requests_Live[iCur];
                    if (curRequest.IsEnded)
                    {
                        continue;
                    }
                    curRequest.Update(tDelta, iCur);
                }
                //Debug.Log("------------------------------------------------------");
            }



            //이제 Weight를 지정해준다.
            //1. Request를 자체적으로 업데이트하여 UnitWeight를 계산한다.

            //업데이트 방식
            //- 앞에서부터 설정한다.
            //- 일단 Weight를 1로 설정
            //- 이전 Prev 시간 영역 (-Start ~ +End)을 비교하여 겹치는 시간이 BlendTime보다 긴지 짧은지 판별한다.
            //- 겹친 시간계산하고, 현재의 ITP를 구한다.
            //- 현재 Request에 ITP를 곱하고, 이전 "모든 Weight"에 (1-ITP)를 곱한다.
            // 겹친 시간 : [ tStart <- tCur ] + [ tCur -> tEnd ]

            //2. 현재 시점에서 중복된 Request들 간의 RequestWeight를 계산한다.
            //3. Request를 돌면서 Prev/Next에 대해서 Weight를 지정해준다.


            float prevCurrent2EndTime = -1.0f;
            float tmpOverlapTime      = 0.0f;
            float tmpOverlapITP       = 0.0f;

            bool isAnyRequestChanged = false;

            for (int iCur = 0; iCur < _requests_Live.Count; iCur++)
            {
                curRequest = _requests_Live[iCur];
                //Ready => Weight : 1
                //End => Weight : 0
                if (!curRequest.IsLive)
                {
                    if (curRequest.IsEnded)
                    {
                        curRequest.SetRequestWeight(0.0f);
                        isAnyRequestChanged = true;
                    }
                    else
                    {
                        curRequest.SetRequestWeight(1.0f);
                    }
                    continue;
                }

                curRequest.SetRequestWeight(1.0f);                //일단 1을 넣는다.

                if (iCur == 0)
                {
                    prevCurrent2EndTime = curRequest.Current2EndTime;
                    continue;
                }

                //BlendTime보다 짧다면 Overlap 시간이 짧아진다.
                //CurTime을 기준으로 [tStart <- tCur] 시간과 [tCur -> tEnd] 시간을 나누어 더하여 계산하는데,
                //[tCur -> tEnd] 시간은 이전 Request와 길이를 비교한다.
                tmpOverlapTime = curRequest.Current2StartTime + Mathf.Min(prevCurrent2EndTime, curRequest.Current2EndTime);
                if (tmpOverlapTime < 0.001f)
                {
                    tmpOverlapITP = 1.0f;
                }
                else
                {
                    tmpOverlapITP = curRequest.Current2StartTime / tmpOverlapTime;
                }

                for (int iPrev = 0; iPrev < iCur; iPrev++)
                {
                    _requests_Live[iPrev].MultiplyRequestWeight(1.0f - tmpOverlapITP);
                }
                curRequest.MultiplyRequestWeight(tmpOverlapITP);


                prevCurrent2EndTime = curRequest.Current2EndTime;
            }


            //마지막으로 다시 돌면서 Request에서 계산된 UnitWeight * RequestWeight를 넣어서 완성
            float totalRequestWeight = 0.0f;
            int   nLiveRequest       = 0;

            for (int iCur = 0; iCur < _requests_Live.Count; iCur++)
            {
                curRequest = _requests_Live[iCur];
                //curRequest.AdaptWeightToPlayUnits();

                if (!curRequest.IsLive)
                {
                    continue;
                }

                curRequest.AdaptWeightToPlayUnits();
                totalRequestWeight += curRequest.RequestWeight;
                nLiveRequest++;
            }

            if (nLiveRequest > 0 && totalRequestWeight > 0.0f)
            {
                if (totalRequestWeight > 1.0f)
                {
                    totalRequestWeight = 1.0f;
                }

                //추가
                //전체 PlayUnit의 Weight가 totalRequestWeight 또는 1을 넘어가거나 모자르다면 거기에 맞게 Normalize한다.
                float totalPlayUnitWeight = 0.0f;
                int   nPlayUnit           = 0;
                for (int iPlayUnit = 0; iPlayUnit < _animPlayUnits.Count; iPlayUnit++)
                {
                    totalPlayUnitWeight += _animPlayUnits[iPlayUnit].UnitWeight;
                    if (totalPlayUnitWeight > 0.0f)
                    {
                        nPlayUnit++;
                    }
                }
                if (totalPlayUnitWeight > 0.0f && nPlayUnit > 1)
                {
                    float normalizeWeight = totalRequestWeight / totalPlayUnitWeight;

                    for (int iPlayUnit = 0; iPlayUnit < _animPlayUnits.Count; iPlayUnit++)
                    {
                        _animPlayUnits[iPlayUnit].NormalizeWeight(normalizeWeight);
                    }
                }
            }



            bool isOrderRefreshable = _isAnyUnitChanged || isAnyRequestChanged;

            //변화값이 있으면 삭제 여부를 판단하자
            if (_isAnyUnitChanged)
            {
                _animPlayUnits.RemoveAll(delegate(apAnimPlayUnit a)
                {
                    return(a.IsRemovable);
                });

                _isAnyUnitChanged = false;
                _nPlayedUnit      = _animPlayUnits.Count;


                _playManager.OnAnyAnimPlayUnitEnded();
            }


            if (isAnyRequestChanged)
            {
                //끝난 Request를 Pool에 돌려놓는다.
                List <apAnimPlayRequest> endedRequests = new List <apAnimPlayRequest>();
                for (int i = 0; i < _requests_Live.Count; i++)
                {
                    if (_requests_Live[i].IsEnded)
                    {
                        endedRequests.Add(_requests_Live[i]);
                    }
                }

                for (int i = 0; i < endedRequests.Count; i++)
                {
                    PushRequest(endedRequests[i]);
                }
            }


            if (isOrderRefreshable)
            {
                //Order를 갱신한다.
                RefreshOrder();
            }
        }