示例#1
0
 // 추가 3.7 : Unlink 처리
 private void UnlinkAllMecanimClips()
 {
     for (int i = 0; i < _nClipData; i++)
     {
         _curClipData = _clipData[i];
         _curClipData.Unlink();
         _curClipData._isCalculated     = false;
         _curClipData._isCalculatedPrev = false;
     }
 }
示例#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;
            }
        }
示例#3
0
        public void LinkPortrait(apPortrait portrait, apAnimPlayManager animPlayManager)
        {
            _portrait        = portrait;
            _animPlayManager = animPlayManager;

            _animator        = _portrait._animator;
            _animController  = null;
            _isValidAnimator = false;

            if (_animator == null)
            {
                //Debug.LogError("No Animator");

                return;
            }

            _animController = _animator.runtimeAnimatorController;

            if (_animController == null)
            {
                Debug.LogError("AnyPortrait : No RuntimeAnimatorController on Animator");
                return;
            }

            _isValidAnimator = true;

            _layers.Clear();
            _clipData.Clear();
            _clipDataByAsset.Clear();
            _clipDataByAnimClip.Clear();

            //레이어 정보를 담자
            _nLayers = _animator.layerCount;

            //저장된 AnimClip 체크를 위해서 리스트를 만들자
            //유효하지 않은 AnimClip은 제외해야한다.
            List <AnimationClip> allClips   = new List <AnimationClip>();
            List <AnimationClip> validClips = new List <AnimationClip>();


            for (int iLayer = 0; iLayer < _animator.layerCount; iLayer++)
            {
                MecanimLayer newLayer = new MecanimLayer();
                newLayer._index = iLayer;

                newLayer._blendType = apAnimPlayUnit.BLEND_METHOD.Interpolation;

                if (iLayer < portrait._animatorLayerBakedData.Count)
                {
                    if (portrait._animatorLayerBakedData[iLayer]._blendType == apAnimMecanimData_Layer.MecanimLayerBlendType.Additive)
                    {
                        //미리 설정된 데이터가 있고, Additive라면 Additive로 설정
                        newLayer._blendType = apAnimPlayUnit.BLEND_METHOD.Additive;
                    }
                }

                _layers.Add(newLayer);
            }

            //어떤 AnimClip이 있는지 체크하자
            for (int i = 0; i < _animController.animationClips.Length; i++)
            {
                if (!allClips.Contains(_animController.animationClips[i]))
                {
                    allClips.Add(_animController.animationClips[i]);
                }
            }


            //apAnimClip <-> AnimationClip Asset을 서로 연결하자
            _animClip2Asset.Clear();
            _asset2AnimClip.Clear();

            //Debug.Log("animPlayManager._animPlayDataList Count : " + animPlayManager._animPlayDataList.Count);

            for (int i = 0; i < animPlayManager._animPlayDataList.Count; i++)
            {
                apAnimPlayData playData = animPlayManager._animPlayDataList[i];
                //Debug.Log("[" + i + "] : " + playData._animClipName);
                apAnimClip animClip = playData._linkedAnimClip;
                if (animClip == null)
                {
                    //Debug.LogError("[" + i + "] : " + playData._animClipName + " >> Linked Anim Clip is Null");
                    continue;
                }
                AnimationClip assetClip = animClip._animationClipForMecanim;

                if (assetClip != null)
                {
                    _animClip2Asset.Add(animClip, assetClip);
                    _asset2AnimClip.Add(assetClip, animClip);

                    MecanimClipData newClipData = new MecanimClipData(assetClip, animClip, playData._linkedOptRootUnit);
                    _clipData.Add(newClipData);
                    _clipDataByAsset.Add(assetClip, newClipData);
                    _clipDataByAnimClip.Add(animClip, newClipData);

                    if (!validClips.Contains(assetClip))
                    {
                        validClips.Add(assetClip);
                    }
                    //Debug.Log("[" + i + "] : " + playData._animClipName + " >> " + assetClip.name);
                }
                else
                {
                    if (Application.isPlaying)
                    {
                        Debug.LogError("[" + i + "] : " + playData._animClipName + " >> AnimAsset is Null");
                    }
                }
            }

            _nClipData = _clipData.Count;

            //여기서 유효성 체크
            //(유효성 체크는 Application 실행 시에)
            //if (Application.isPlaying)
            {
                for (int i = 0; i < allClips.Count; i++)
                {
                    if (!validClips.Contains(allClips[i]))
                    {
                        if (allClips[i] != _portrait._emptyAnimClipForMecanim)
                        {
                            //유효하지 않은 Clip이 발견되었다.
                            Debug.LogError("AnyPortrait : ( Caution! ) Contains an invalid AnimationClip. An error may occur when playing. [" + allClips[i].name + " < " + _portrait.gameObject.name + "]");
                            Debug.LogError("Valid Clips : " + validClips.Count);
                        }
                    }
                }
            }
        }
示例#4
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;
            }
        }