public void Resume() { for (int i = 0; i < _nPlayedUnit; i++) { _tmpCurPlayUnit = _animPlayUnits[i]; _tmpCurPlayUnit.Resume(); } }
//---------------------------------------------------- // 재생/정지 요청 함수들 //---------------------------------------------------- //AnimClip을 PlayUnit에 담아서 재생한다. //Queue에 저장된 모든 클립은 무시되며 블렌드되지 않는다. public apAnimPlayUnit Play(apAnimPlayData playData, apAnimPlayUnit.BLEND_METHOD blendMethod, float blendTime = 0.0f, bool isAutoEndIfNotloop = true) { //현재 상태에서 실행되지 않은 Queued 애니메이션 재생 요청은 삭제한다. PushAllNoActiveRequests(); //Request를 생성한다. apAnimPlayRequest request = PopRequest(); //request.SetCurrentPlayedUnits(this, _animPlayUnits); request.SetCurrentPlayedUnits(this); //현재 플레이 중인 AnimPlayUnit들의 LinkKey를 넣어준다. //Debug.Log("Add Play Unit Link Key"); for (int i = 0; i < _animPlayUnits.Count; i++) { //Debug.Log(_animPlayUnits[i]._linkedAnimClip._name + " : " + _animPlayUnits[i].LinkKey + " / " + _animPlayUnits[i].PlayStatus); request.AddPrevPlayUnitKeyLink(_animPlayUnits[i].LinkKey, _animPlayUnits[i].UnitWeight); } apAnimPlayUnit newPlayUnit = MakePlayUnit(playData, blendMethod, isAutoEndIfNotloop); //newPlayUnit.Play(); newPlayUnit.Resume(); //Pause가 걸려있으면 풀어주자 //Play 명령을 준다. request.PlayNew(newPlayUnit, blendTime); //이때, 만약 PlayQueued 타입이며 newPlayUnit을 타겟으로 하는게 있으면 처리할 때 무력화시켜야 한다. apAnimPlayRequest overlapQueuedRequest = _requests_Live.Find(delegate(apAnimPlayRequest a) { return(a != request && a.RequestType == apAnimPlayRequest.REQUEST_TYPE.Queued && a._nextPlayUnit == newPlayUnit); }); if (overlapQueuedRequest != null) { //Debug.Log("겹치는 Queue Request를 그냥 바로 삭제"); PushRequest(overlapQueuedRequest); } #region [미사용 코드] //TODO : 이 AnimClip을 CalculatedParam에 연결해야한다. //Debug.LogError("TODO : 이 AnimClip을 CalculatedParam에 연결해야한다"); ////플레이 유닛은 플레이 시작 ////나머지는 End로 만든다. //for (int i = 0; i < _animPlayUnits.Count; i++) //{ // if (newPlayUnit != _animPlayUnits[i]) // { // _animPlayUnits[i].SetEnd(); // } //} #endregion _nPlayedUnit = _animPlayUnits.Count; //Order를 갱신한다. RefreshOrder(); //Debug.Log("Next Play Units [" + _nPlayedUnit + "]"); return(newPlayUnit); }
// Update //-------------------------------------------------- public void Update(float tDelta, int index) { //if (_nextPlayUnit != null) //{ // Debug.Log("[" + index +" - " + _requestType + "] Request Update : " + _nextPlayUnit._linkedAnimClip._name); //} //else //{ // Debug.Log("[" + index +" - " + _requestType + "] Request Update : Null"); //} switch (_requestType) { case REQUEST_TYPE.New: { switch (_status) { case STATUS.Ready: case STATUS.Active: //Ready 상태가 없다. 있어도 Active로 처리 if (!_isNextUnitPlayed) { if (_nextPlayUnit != null && _nextPlayUnit.NextOwnerRequest == this //<<일단 소유권 문제는 제외하자 ) { //Debug.LogError(">>>> [New] Play AnimClip : " + _nextPlayUnit._linkedAnimClip._name); _parentAnimPlayQueue.RefreshPlayOrderAll(); //전체 Order를 갱신 _nextPlayUnit.Play(); } //else //{ // //Debug.LogError(">>>> [New] Play AnimClip : Failed"); // if(_nextPlayUnit == null) // { // Debug.LogError(">>>> 대상 PlayUnit이 없다."); // } // else if(_nextPlayUnit.NextOwnerRequest != this) // { // Debug.LogError(">>>> 대상 PlayUnit의 소유권이 Request에 없다."); // } //} _isNextUnitPlayed = true; _tActiveStart = _tLive; _tActiveMiddle = (_tActiveStart + _tActiveEnd) * 0.5f; } _tLive += tDelta; float itpLive = (_tLive - _tActiveStart); float itpMiddle = (_tActiveMiddle - _tActiveStart); float itpEnd = (_tActiveEnd - _tActiveStart); if (_tLive >= _tActiveEnd || _tActiveEnd < BIAS_ZERO) { _status = STATUS.End; //끝! _nextUnitWeight = 1.0f; _prevUnitWeight = 0.0f; //for (int i = 0; i < _prevPlayUnits.Count; i++) //{ // if (_nextPlayUnit != _prevPlayUnits[i] // //&& _prevPlayUnits[i].PrevOwnerRequest == this // ) // { // _prevPlayUnits[i].SetEnd(); // } //} //변경 -> Queue가 간접적으로 End하도록 만든다. _parentAnimPlayQueue.SetEndByRequest(this); } else { //int calType = 0; if (_isNextPlayUnitIsInPrevUnit) //if(false) { //만약 Prev 유닛에 이미 재생중이었다면 if (_tLive < _tActiveMiddle) { //절반 동안은 서서히 내려가고 (이미 재생중이었으므로) _nextUnitWeight = (1.0f - (itpLive / itpMiddle)) * _nextUnitWeight_Overlap; //_nextUnitWeight = 0.0f; //calType = 0; } else { //그 나머지는 1로 올라간다. _nextUnitWeight = ((itpLive - itpMiddle) / (itpEnd - itpMiddle)); //calType = 1; if (!_isNextUnitFrameReset) { //프레임을 여기서 리셋한다. if (_nextPlayUnit != null && _nextPlayUnit.NextOwnerRequest == this) { _parentAnimPlayQueue.RefreshPlayOrderAll(); //전체 Order를 갱신 if (!_nextPlayUnit.IsLoop) { _nextPlayUnit.ResetPlay(); } else { _nextPlayUnit.Resume(); } } _isNextUnitFrameReset = true; } } } else { //새로운 NextUnit이 재생을 시작했다면 (기본) _nextUnitWeight = itpLive / itpEnd; //calType = 2; } _prevUnitWeight = 1.0f - (itpLive / itpEnd); //Debug.Log("Fade [" + _prevUnitWeight + " > " + _nextUnitWeight + " (" + (_prevUnitWeight + _nextUnitWeight) + ") ] - Overlap [" + _nextUnitWeight_Overlap + "]"); //if((_prevUnitWeight + _nextUnitWeight) > 1.02f // || (_prevUnitWeight + _nextUnitWeight) < 0.98f) //{ // Debug.Log("ITP Live : " + itpLive + " / ITP Middle : " + itpMiddle + " / ITP End : " + itpEnd + " / Cal Type : " + calType); //} } break; case STATUS.End: _nextUnitWeight = 1.0f; _prevUnitWeight = 0.0f; break; } } break; case REQUEST_TYPE.Queued: { switch (_status) { case STATUS.Ready: { //여기가 중요 //대기중인 AnimPlayUnit의 종료를 기다린다. //if(_prevWaitingPlayUnit == null) //{ // _status = STATUS.End; // _nextUnitWeight = 0.0f; // break; //} _tLive += tDelta; float remainTime = 0.0f; if (_prevWaitingPlayUnit != null) { remainTime = _prevWaitingPlayUnit.RemainPlayTime; } if (remainTime <= _tBlend + BIAS_ZERO) { _status = STATUS.Active; // Blend 시간을 포함하여 다음 PlayUnit을 실행할 수 있게 되었다. //Debug.LogError("Queue Ready >> Active (Remain : " + remainTime + " / Blend Time : " + _tBlend + ")"); //현재 시간을 기점으로 Start-End 시간을 만든다. _tActiveStart = _tLive; _tActiveEnd = _tActiveStart + _tBlend; _tActiveMiddle = (_tActiveStart + _tActiveEnd) * 0.5f; _nextUnitWeight = 0.0f; //<<아직은 0 _prevUnitWeight = 1.0f; //이걸 플레이하는 시점에서 지정 _isNextPlayUnitIsInPrevUnit = _parentAnimPlayQueue.IsAlreadyAnimUnitPlayed(_nextPlayUnit); _nextUnitWeight_Overlap = 1.0f; if (_isNextPlayUnitIsInPrevUnit) { //Debug.LogError("[" + _nextPlayUnit._linkedAnimClip._name + "] Overlap 상태로 Queue 시작 : 현재 Weight : " + _nextPlayUnit.UnitWeight); _nextUnitWeight_Overlap = _nextPlayUnit.UnitWeight; } else { _nextUnitWeight_Overlap = 0.0f; } } else { //대기.. //Debug.Log("Queue Ready (Remain : " + remainTime + " / Blend Time : " + _tBlend + ")"); _nextUnitWeight = 0.0f; _prevUnitWeight = 1.0f; } } break; case STATUS.Active: if (!_isNextUnitPlayed) { if (_nextPlayUnit != null && _nextPlayUnit.NextOwnerRequest == this) { //Debug.LogError(">>>> [Queued] Play AnimClip : " + _nextPlayUnit._linkedAnimClip._name); //여기서는 Order를 갱신하지 않는다. if (!_isNextPlayUnitIsInPrevUnit) { _parentAnimPlayQueue.RefreshPlayOrderAll(); //전체 Order를 갱신 //Debug.Log(">> Play (" + _isResetPlayAtStartFrame + " / " + _frameToStart + ")"); if (_isResetPlayAtStartFrame) { _nextPlayUnit.Play(); } else { _nextPlayUnit.PlayAt(_frameToStart); _isResetPlayAtStartFrame = true; //<<초기화 } } } //else //{ // Debug.LogError(">>>> [Queued] Play AnimClip : Failed"); //} //_tLive = 0.0f; _isNextUnitPlayed = true; } _tLive += tDelta; float itpLive = (_tLive - _tActiveStart); float itpMiddle = (_tActiveMiddle - _tActiveStart); float itpEnd = (_tActiveEnd - _tActiveStart); if (_tLive >= _tActiveEnd || _tActiveEnd < BIAS_ZERO) { _status = STATUS.End; //끝! _nextUnitWeight = 1.0f; _prevUnitWeight = 0.0f; //for (int i = 0; i < _prevPlayUnits.Count; i++) //{ // if (_nextPlayUnit != _prevPlayUnits[i] // //&& _prevPlayUnits[i].PrevOwnerRequest == this // ) // { // _prevPlayUnits[i].SetEnd(); // } //} //변경 -> Queue가 간접적으로 End하도록 만든다. _parentAnimPlayQueue.SetEndByRequest(this); } else { if (_isNextPlayUnitIsInPrevUnit) { //만약 Prev 유닛에 이미 재생중이었다면 if (_tLive < _tActiveMiddle) { //절반 동안은 서서히 내려가고 (이미 재생중이었으므로) _nextUnitWeight = (1.0f - (itpLive / itpMiddle)) * _nextUnitWeight_Overlap; } else { //그 나머지는 1로 올라간다. _nextUnitWeight = ((itpLive - itpMiddle) / itpMiddle); if (!_isNextUnitFrameReset) { //프레임을 여기서 리셋한다. if (_nextPlayUnit != null && _nextPlayUnit.NextOwnerRequest == this) { _parentAnimPlayQueue.RefreshPlayOrderAll(); //전체 Order를 갱신 if (!_nextPlayUnit.IsLoop) { //Debug.LogError(">>> [Queued] Reset Play : " + _nextPlayUnit._linkedAnimClip._name); //Debug.Log(">> ResetPlay (" + _isResetPlayAtStartFrame + " / " + _frameToStart + ")"); if (_isResetPlayAtStartFrame) { _nextPlayUnit.ResetPlay(); } else { _nextPlayUnit.ResetPlayAt(_frameToStart); _isResetPlayAtStartFrame = true; } } else { _nextPlayUnit.Resume(); } } _isNextUnitFrameReset = true; } } } else { //새로운 NextUnit이 재생을 시작했다면 (기본) _nextUnitWeight = Mathf.Clamp01(itpLive / itpEnd); } _prevUnitWeight = 1.0f - Mathf.Clamp01(itpLive / itpEnd); } break; case STATUS.End: _nextUnitWeight = 1.0f; _prevUnitWeight = 0.0f; break; } } break; case REQUEST_TYPE.Stop: { switch (_status) { case STATUS.Ready: case STATUS.Active: //Ready 상태가 없다. 있어도 Active로 처리 _tLive += tDelta; if (_tLive >= _tActiveEnd || _tActiveEnd < BIAS_ZERO) { _status = STATUS.End; //끝! _nextUnitWeight = 1.0f; _prevUnitWeight = 0.0f; //for (int i = 0; i < _prevPlayUnits.Count; i++) //{ // if (_prevPlayUnits[i] != null && _prevPlayUnits[i].PrevOwnerRequest == this) // { // _prevPlayUnits[i].SetEnd(); // } //} //변경 -> Queue가 간접적으로 End하도록 만든다. _parentAnimPlayQueue.SetEndByRequest(this); } else { _nextUnitWeight = _tLive / _tActiveEnd; _prevUnitWeight = 1.0f - _nextUnitWeight; } break; case STATUS.End: _nextUnitWeight = 1.0f; _prevUnitWeight = 0.0f; break; } } break; } }