示例#1
0
        // Functions
        //---------------------------------------------
        public void Update()
        {
#if UNITY_2017_1_OR_NEWER
            //추가 3.5 : Timeline의 PlayerDirector가 연결되어 있다면 재생할 수 있는지 확인하자.
            //재생되는 타임라인이 있다면, 메카님 컨트롤러는 무시하고 타임라인의 제어를 받자
            if (_timlinePlay != null)
            {
                if (_timlinePlay.IsAnyPlaying)
                {
                    if (_playType == PLAY_TYPE.Mecanim)
                    {
                        //Mecanim > Timeline
                        _playType = PLAY_TYPE.Timeline;

                        //메카님에서 재생중이던 클립들을 모두 Unlink해야한다.
                        UnlinkAllMecanimClips();
                    }

                    //타임라인으로 재생을 한다.
                    _timlinePlay.Update();


                    if (_timlinePlay.IsLastPlayedTimelineClipChanged)
                    {
                        //프레임 보정>>
                        //마지막으로 재생된 TimelineClip과, 현재 Animator에서 백그라운드에서 재생중인 State간의 시간을 보정한다.
                        //- 0번 레이어야 한다.
                        //- 재생 중인 State여야 한다.
                        if (_timlinePlay.LastPlayedTimelineClip != null &&
                            _animator != null &&
                            _isValidAnimator &&
                            _nLayers > 0)
                        {
                            _curStateInfo = _animator.GetCurrentAnimatorStateInfo(0);
                            _curClipInfos = _animator.GetCurrentAnimatorClipInfo(0);

                            UnityEngine.Timeline.TimelineClip lastTimelineClip = _timlinePlay.LastPlayedTimelineClip;
                            float lastLocalTime = _timlinePlay.LastPlayedLocalTime;

                            if (_curClipInfos != null && _curClipInfos.Length > 0)
                            {
                                if (_curClipInfos[0].clip == lastTimelineClip.animationClip)
                                {
                                    //현재 "재생중"인 "0번"레이어의 "현재 클립"과 동일하다
                                    //시간을 보정하자
                                    _animator.PlayInFixedTime(0, 0, lastLocalTime);
                                }
                            }
                        }
                    }

                    //더이상 처리를 하지 않는다.
                    return;
                }



                if (_playType == PLAY_TYPE.Timeline)
                {
                    //Timeline > Mecanim
                    _playType = PLAY_TYPE.Mecanim;

                    //Timeline에서 재생중이던 클립들을 모두 Unlink해야한다.
                    _timlinePlay.UnlinkAll();
                }
            }
#endif

            if (!_isValidAnimator)
            {
                //변경 : Timeline을 위해서 설정된 경우 RuntimeAnimatorController가 필요 없을 수 있다.
                //Debug.LogError("AnyPortrait : IsValidAnimator = false");
                return;
            }

            //1. 일단 Clip Data를 초기화
            for (int i = 0; i < _nClipData; i++)
            {
                _clipData[i].ReadyToUpdate();
            }

            _curOrder = 0;
            //2. 레이어를 돌면서 각 클립에 대해 플레이, 시간, 배속(정방향/역방향)을 갱신한다.
            //AnimPlayUnit에 대해서 값을 넣는다.
            for (int iLayer = 0; iLayer < _nLayers; iLayer++)
            {
                _curMecanimLayer = _layers[iLayer];
                if (iLayer == 0)
                {
                    //Layer 0에서는 GetLayerWeight의 값이 0이 리턴된다. (항상 1이어야함)
                    _curLayerWeight = 1.0f;
                }
                else
                {
                    _curLayerWeight = _animator.GetLayerWeight(iLayer);
                }


                //_isInTransition = _animator.IsInTransition(iLayer);
                _curStateInfo = _animator.GetCurrentAnimatorStateInfo(iLayer);
                _curClipInfos = _animator.GetCurrentAnimatorClipInfo(iLayer);

                //Debug.Log("Cur Clip Info : "+ _curClipInfos.Length);

                //Debug.Log("Mecanim Layer [" + iLayer + "] / _isInTransition : " + _isInTransition + " / _curLayerWeight : " + _curLayerWeight);

                _curNormalizedTime = _curStateInfo.normalizedTime;
                //if(_curNormalizedTime > 1.0f)
                //{
                //	_curNormalizedTime -= (int)_curNormalizedTime;
                //}


                //"현재 Clip" 먼저 처리
                if (_curClipInfos != null && _curClipInfos.Length > 0)
                {
                    for (int iClip = 0; iClip < _curClipInfos.Length; iClip++)
                    {
                        _curClipAsset = _curClipInfos[iClip].clip;
                        if (_curClipAsset == _portrait._emptyAnimClipForMecanim ||
                            _curClipAsset == null)
                        {
                            continue;
                        }
                        _curClipData = _clipDataByAsset[_curClipAsset];

                        if (_curClipData._isCalculated)
                        {
                            //이미 처리가 되었다면 패스
                            continue;
                        }
                        //업데이트를 하자 <Current>

                        _curClipData.SetData(iLayer,
                                             _curOrder,
                                             _curMecanimLayer._blendType,
                                             _curStateInfo.speed,
                                             _curStateInfo.speedMultiplier,
                                             _curLayerWeight * _curClipInfos[iClip].weight,
                                             _curNormalizedTime);

                        _curOrder++;
                    }
                }

                _nextStateInfo = _animator.GetNextAnimatorStateInfo(iLayer);
                _nextClipInfos = _animator.GetNextAnimatorClipInfo(iLayer);



                //"다음 Clip" 처리
                if (_nextClipInfos != null && _nextClipInfos.Length > 0)
                {
                    //1. 전환되는 Clip이 존재한다.
                    _nextNormalizedTime = _nextStateInfo.normalizedTime;
                    //if (_nextNormalizedTime > 1.0f)
                    //{
                    //	_nextNormalizedTime -= (int)_nextNormalizedTime;
                    //}

                    for (int iClip = 0; iClip < _nextClipInfos.Length; iClip++)
                    {
                        _nextClipAsset = _nextClipInfos[iClip].clip;
                        if (_nextClipAsset == _portrait._emptyAnimClipForMecanim ||
                            _nextClipAsset == null)
                        {
                            continue;
                        }
                        _nextClipData = _clipDataByAsset[_nextClipAsset];

                        if (_nextClipData._isCalculated)
                        {
                            //이미 처리가 되었다면 패스
                            continue;
                        }
                        //업데이트를 하자 <Next>
                        _nextClipData.SetData(iLayer,
                                              _curOrder,
                                              _curMecanimLayer._blendType,
                                              //apAnimPlayUnit.BLEND_METHOD.Additive,
                                              _nextStateInfo.speed,
                                              _nextStateInfo.speedMultiplier,
                                              _curLayerWeight * _nextClipInfos[iClip].weight,
                                              _nextNormalizedTime);

                        _curOrder++;
                    }
                }
            }


            //3. 플레이 데이터 확인하여 PlayUnit 생성/삭제하여 연결한다.
            //프레임이나 설정, 이벤트 등을 갱신하고 호출한다.
            //0번 레이어를 기준으로 RootUnit을 결정한다.
            for (int i = 0; i < _nClipData; i++)
            {
                _curClipData = _clipData[i];
                if (!_curClipData._isCalculated)
                {
                    //계산이 안되었으면 Release를 한다.
                    if (_curClipData._isCalculatedPrev)
                    {
                        //이전 프레임에서는 계산이 되었던 ClipData이다.
                        _curClipData.Unlink();
                    }
                }
                else
                {
                    //계산이 되었으면 연결을 하고, 프레임과 Weight를 업데이트한다.
                    if (!_curClipData._isCalculatedPrev)
                    {
                        //이전 프레임에서는 계산이 안된 ClipData이다.
                        _curClipData.Link();

                        //Layer = 0인 경우에 Link가 발생하는 경우 => RootUnit을 설정해주자
                        if (_curClipData._playedLayer == 0)
                        {
                            _animPlayManager.SetOptRootUnit(_curClipData._linkedRootUnit);
                        }
                    }

                    //이제 업데이트를 합시다.
                    _curClipData.UpdateAnimClipAndPlayUnit();
                }

                //Prev를 갱신한다
                _curClipData._isCalculatedPrev = _curClipData._isCalculated;
            }
        }
示例#2
0
        // Functions
        //---------------------------------------------
        public void Update()
        {
            if (!_isValidAnimator)
            {
                Debug.Log("IsValidAnimator = false");
                return;
            }

            //1. 일단 Clip Data를 초기화
            for (int i = 0; i < _nClipData; i++)
            {
                _clipData[i].ReadyToUpdate();
            }

            _curOrder = 0;
            //2. 레이어를 돌면서 각 클립에 대해 플레이, 시간, 배속(정방향/역방향)을 갱신한다.
            //AnimPlayUnit에 대해서 값을 넣는다.
            for (int iLayer = 0; iLayer < _nLayers; iLayer++)
            {
                _curMecanimLayer = _layers[iLayer];
                if (iLayer == 0)
                {
                    //Layer 0에서는 GetLayerWeight의 값이 0이 리턴된다. (항상 1이어야함)
                    _curLayerWeight = 1.0f;
                }
                else
                {
                    _curLayerWeight = _animator.GetLayerWeight(iLayer);
                }


                //_isInTransition = _animator.IsInTransition(iLayer);
                _curStateInfo = _animator.GetCurrentAnimatorStateInfo(iLayer);
                _curClipInfos = _animator.GetCurrentAnimatorClipInfo(iLayer);

                //Debug.Log("Cur Clip Info : "+ _curClipInfos.Length);

                //Debug.Log("Mecanim Layer [" + iLayer + "] / _isInTransition : " + _isInTransition + " / _curLayerWeight : " + _curLayerWeight);

                _curNormalizedTime = _curStateInfo.normalizedTime;
                //if(_curNormalizedTime > 1.0f)
                //{
                //	_curNormalizedTime -= (int)_curNormalizedTime;
                //}


                //"현재 Clip" 먼저 처리
                if (_curClipInfos != null && _curClipInfos.Length > 0)
                {
                    for (int iClip = 0; iClip < _curClipInfos.Length; iClip++)
                    {
                        _curClipAsset = _curClipInfos[iClip].clip;
                        if (_curClipAsset == _portrait._emptyAnimClipForMecanim ||
                            _curClipAsset == null)
                        {
                            continue;
                        }
                        _curClipData = _clipDataByAsset[_curClipAsset];

                        if (_curClipData._isCalculated)
                        {
                            //이미 처리가 되었다면 패스
                            continue;
                        }
                        //업데이트를 하자 <Current>

                        _curClipData.SetData(iLayer,
                                             _curOrder,
                                             _curMecanimLayer._blendType,
                                             _curStateInfo.speed,
                                             _curLayerWeight * _curClipInfos[iClip].weight,
                                             _curNormalizedTime);

                        _curOrder++;
                    }
                }

                _nextStateInfo = _animator.GetNextAnimatorStateInfo(iLayer);
                _nextClipInfos = _animator.GetNextAnimatorClipInfo(iLayer);



                //"다음 Clip" 처리
                if (_nextClipInfos != null && _nextClipInfos.Length > 0)
                {
                    //1. 전환되는 Clip이 존재한다.
                    _nextNormalizedTime = _nextStateInfo.normalizedTime;
                    //if (_nextNormalizedTime > 1.0f)
                    //{
                    //	_nextNormalizedTime -= (int)_nextNormalizedTime;
                    //}

                    for (int iClip = 0; iClip < _nextClipInfos.Length; iClip++)
                    {
                        _nextClipAsset = _nextClipInfos[iClip].clip;
                        if (_nextClipAsset == _portrait._emptyAnimClipForMecanim ||
                            _nextClipAsset == null)
                        {
                            continue;
                        }
                        _nextClipData = _clipDataByAsset[_nextClipAsset];

                        if (_nextClipData._isCalculated)
                        {
                            //이미 처리가 되었다면 패스
                            continue;
                        }
                        //업데이트를 하자 <Next>
                        _nextClipData.SetData(iLayer,
                                              _curOrder,
                                              _curMecanimLayer._blendType,
                                              //apAnimPlayUnit.BLEND_METHOD.Additive,
                                              _nextStateInfo.speed,
                                              _curLayerWeight * _nextClipInfos[iClip].weight,
                                              _nextNormalizedTime);

                        _curOrder++;
                    }
                }
            }


            //3. 플레이 데이터 확인하여 PlayUnit 생성/삭제하여 연결한다.
            //프레임이나 설정, 이벤트 등을 갱신하고 호출한다.
            //0번 레이어를 기준으로 RootUnit을 결정한다.
            for (int i = 0; i < _nClipData; i++)
            {
                _curClipData = _clipData[i];
                if (!_curClipData._isCalculated)
                {
                    //계산이 안되었으면 Release를 한다.
                    if (_curClipData._isCalculatedPrev)
                    {
                        //이전 프레임에서는 계산이 되었던 ClipData이다.
                        _curClipData.Unlink();
                    }
                }
                else
                {
                    //계산이 되었으면 연결을 하고, 프레임과 Weight를 업데이트한다.
                    if (!_curClipData._isCalculatedPrev)
                    {
                        //이전 프레임에서는 계산이 안된 ClipData이다.
                        _curClipData.Link();

                        //Layer = 0인 경우에 Link가 발생하는 경우 => RootUnit을 설정해주자
                        if (_curClipData._playedLayer == 0)
                        {
                            _animPlayManager.SetOptRootUnit(_curClipData._linkedRootUnit);
                        }
                    }

                    //이제 업데이트를 합시다.
                    _curClipData.UpdateAnimClipAndPlayUnit();
                }

                //Prev를 갱신한다
                _curClipData._isCalculatedPrev = _curClipData._isCalculated;
            }
        }
            public void Update(apAnimPlayManager animPlayManager)
            {
#if UNITY_2017_1_OR_NEWER
                _c_curTime = _parentTrackSet._playableDirector.time;

                _lastPlayedTimelineClip = null;
#endif
                _lastPlayedLocalTime = 0.0f;

                //1. 전체 Reday To Update
                for (int i = 0; i < _nClipData; i++)
                {
                    _clipData[i].ReadyToUpdate();
                }

#if UNITY_2017_1_OR_NEWER
                //2. 범위 체크해서 업데이트 여부 결정과 Set Data
                _c_curClipData = null;
                _c_clipA       = null;
                _c_clipB       = null;

                _c_localTimeA = 0.0;
                _c_localTimeB = 0.0;
                _c_weightA    = 0.0f;
                _c_weightB    = 0.0f;

                _c_nPlayClips = 0;

                for (int i = 0; i < _nClipData; i++)
                {
                    _c_curClipData = _clipData[i];

                    if (_c_curTime < _c_curClipData._timelineClip.start ||
                        _c_curTime > _c_curClipData._timelineClip.end)
                    {
                        continue;
                    }

                    if (_c_clipA == null)
                    {
                        _c_clipA      = _c_curClipData;
                        _c_nPlayClips = 1;

                        _c_localTimeA = _c_clipA._timelineClip.ToLocalTimeUnbound(_c_curTime);
                    }
                    else if (_c_clipB == null)
                    {
                        //단, A와 AnimClip이 겹치면 안된다.
                        if (_c_clipA._animClip != _c_curClipData._animClip)
                        {
                            _c_clipB      = _c_curClipData;
                            _c_nPlayClips = 2;

                            _c_localTimeB = _c_clipB._timelineClip.ToLocalTimeUnbound(_c_curTime);
                            break;                            //B까지 연결했으면 끝
                        }
                    }
                }

                if (_c_nPlayClips == 1)
                {
                    //PlayClip이 1개일 때
                    if (_c_localTimeA < _c_clipA._timelineClip.easeInDuration)
                    {
                        _c_weightA = GetWeightIn(_c_localTimeA, _c_clipA._timelineClip.easeInDuration);
                    }
                    else if (_c_localTimeA < _c_clipA._timelineClip.duration - _c_clipA._timelineClip.easeOutDuration)
                    {
                        _c_weightA = 1.0f;
                    }
                    else
                    {
                        _c_weightA = GetWeightOut(_c_localTimeA, _c_clipA._timelineClip.easeOutDuration, _c_clipA._timelineClip.duration);
                    }

                    _c_clipA.SetData(true, _c_weightA, (float)_c_localTimeA, _blendMethod, _layerOrder);

                    //Clip A가 마지막에 계산되었다.
                    _lastPlayedTimelineClip = _c_clipA._timelineClip;
                    _lastPlayedLocalTime    = (float)_c_localTimeA;
                }
                else if (_c_nPlayClips == 2)
                {
                    //PlayClip이 2개일 때 (무조건 Blend)
                    _c_weightA = GetWeightOut(_c_localTimeA, _c_clipA._timelineClip.blendOutDuration, _c_clipA._timelineClip.duration);
                    _c_weightB = 1.0f - _c_weightA;

                    _c_clipA.SetData(true, _c_weightA, (float)_c_localTimeA, _blendMethod, _layerOrder);
                    _c_clipB.SetData(false, _c_weightB, (float)_c_localTimeB, _blendMethod, _layerOrder);

                    //Clip B가 마지막에 계산되었다.
                    _lastPlayedTimelineClip = _c_clipB._timelineClip;
                    _lastPlayedLocalTime    = (float)_c_localTimeB;
                }



                //3. 클립데이터 확인하여 Link/Unlink 및 Update
                for (int i = 0; i < _nClipData; i++)
                {
                    _c_curClipData = _clipData[i];
                    if (!_c_curClipData._isCalculated)
                    {
                        //업데이트가 안되었다면 Release
                        if (_c_curClipData._isCalculatedPrev)
                        {
                            //이전 프레임에서는 계산이 되었던 ClipData다.
                            _c_curClipData.Unlink();
                        }
                    }
                    else
                    {
                        //업데이트가 되었으면 연결을 하고, 프레임과 Weight를 업데이트 한다.
                        if (!_c_curClipData._isCalculatedPrev)
                        {
                            //이전 프레임에서는 계산이 안되었다.
                            _c_curClipData.Link();

                            //Root Unit을 갱신할 수도 있다.
                            animPlayManager.SetOptRootUnit(_c_curClipData._linkedRootUnit);
                        }

                        //업데이트 <중요!>
                        _c_curClipData.UpdateTimelineClipAndPlayUnit();
                    }

                    //Prev 갱신
                    _c_curClipData._isCalculatedPrev = _c_curClipData._isCalculated;
                }
#endif
            }