예제 #1
0
        // 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;
            }
        }
        // Update
        //--------------------------------------------------
        public void Update(float tDelta)
        {
            switch (_requestType)
            {
            case REQUEST_TYPE.New:
            {
                switch (_status)
                {
                case STATUS.Ready:
                case STATUS.Active:
                    //Ready 상태가 없다. 있어도 Active로 처리
                    if (!_isNextUnitPlayed)
                    {
                        if (_nextPlayUnit != null && _nextPlayUnit._ownerRequest == this)
                        {
                            _nextPlayUnit.Play();
                        }
                        _isNextUnitPlayed = true;
                    }

                    _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 (_nextPlayUnit != _prevPlayUnits[i] && _prevPlayUnits[i]._ownerRequest == this)
                            {
                                _prevPlayUnits[i].SetEnd();
                            }
                        }
                    }
                    else
                    {
                        if (_isNextPlayUnitIsInPrevUnit)
                        {
                            //만약 Prev 유닛에 이미 재생중이었다면
                            if (_tLive < _tActiveMiddle)
                            {
                                //절반 동안은 서서히 내려가고 (이미 재생중이었으므로)
                                _nextUnitWeight = (1.0f - (_tLive / _tActiveMiddle)) * _nextUnitWeight_Overlap;
                            }
                            else
                            {
                                //그 나머지는 1로 올라간다.
                                _nextUnitWeight = ((_tLive - _tActiveMiddle) / _tActiveMiddle);
                                if (!_isNextUnitFrameReset)
                                {
                                    //프레임을 여기서 리셋한다.
                                    if (_nextPlayUnit != null && _nextPlayUnit._ownerRequest == this)
                                    {
                                        _nextPlayUnit.ResetPlay();
                                    }
                                    _isNextUnitFrameReset = true;
                                }
                            }
                        }
                        else
                        {
                            //새로운 NextUnit이 재생을 시작했다면 (기본)
                            _nextUnitWeight = _tLive / _tActiveEnd;
                        }

                        _prevUnitWeight = 1.0f - (_tLive / _tActiveEnd);
                    }
                    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;
                    }
                    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._ownerRequest == this)
                        {
                            _nextPlayUnit.Play();
                        }
                        _isNextUnitPlayed = true;
                    }

                    _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 (_nextPlayUnit != _prevPlayUnits[i] && _prevPlayUnits[i]._ownerRequest == this)
                            {
                                _prevPlayUnits[i].SetEnd();
                            }
                        }
                    }
                    else
                    {
                        if (_isNextPlayUnitIsInPrevUnit)
                        {
                            //만약 Prev 유닛에 이미 재생중이었다면
                            if (_tLive < _tActiveMiddle)
                            {
                                //절반 동안은 서서히 내려가고 (이미 재생중이었으므로)
                                _nextUnitWeight = (1.0f - (_tLive / _tActiveMiddle)) * _nextUnitWeight_Overlap;
                            }
                            else
                            {
                                //그 나머지는 1로 올라간다.
                                _nextUnitWeight = ((_tLive - _tActiveMiddle) / _tActiveMiddle);
                                if (!_isNextUnitFrameReset)
                                {
                                    //프레임을 여기서 리셋한다.
                                    if (_nextPlayUnit != null && _nextPlayUnit._ownerRequest == this)
                                    {
                                        _nextPlayUnit.ResetPlay();
                                    }
                                    _isNextUnitFrameReset = true;
                                }
                            }
                        }
                        else
                        {
                            //새로운 NextUnit이 재생을 시작했다면 (기본)
                            _nextUnitWeight = _tLive / _tActiveEnd;
                        }

                        _prevUnitWeight = 1.0f - (_tLive / _tActiveEnd);
                    }
                    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]._ownerRequest == this)
                            {
                                _prevPlayUnits[i].SetEnd();
                            }
                        }
                    }
                    else
                    {
                        _nextUnitWeight = _tLive / _tActiveEnd;
                        _prevUnitWeight = 1.0f - _nextUnitWeight;
                    }
                    break;

                case STATUS.End:
                    _nextUnitWeight = 1.0f;
                    _prevUnitWeight = 0.0f;
                    break;
                }
            }
            break;
            }
        }