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(); } }