public void Link(apPortrait portrait, apAnimPlayManager animPlayManager, apAnimPlayMecanim animPlayMecanim)
        {
            ClearTracks();
#if UNITY_2017_1_OR_NEWER
            _portrait = portrait;
#endif
            _animPlayManager = animPlayManager;
#if UNITY_2017_1_OR_NEWER
            //_animPlayMecanim = animPlayMecanim;
#endif

            //Inspector에서 지정된 트랙 정보가 있다면 먼저 등록한다.
#if UNITY_2017_1_OR_NEWER
            if (portrait._timelineTrackSets != null && portrait._timelineTrackSets.Length > 0)
            {
                apPortrait.TimelineTrackPreset trackSetData = null;
                for (int i = 0; i < portrait._timelineTrackSets.Length; i++)
                {
                    trackSetData = portrait._timelineTrackSets[i];

                    AddTrack(trackSetData._playableDirector, trackSetData._trackName, trackSetData._layer, trackSetData._blendMethod);
                }
            }
#endif
        }
Exemplo n.º 2
0
        // Init
        //----------------------------------------------
        public apAnimPlayQueue(int layer, apPortrait portrait, apAnimPlayManager playManager)
        {
            _layer       = layer;
            _portrait    = portrait;
            _playManager = playManager;


            Clear();
            _isAnyUnitChanged = false;

            _requests_Live.Clear();
            _requests_Total.Clear();
            _requests_Remained.Clear();

            AddRequestPool();            //<<Pool을 만든다.
        }
            //업데이트
            public void Update(apAnimPlayManager animPlayManager)
            {
#if UNITY_2017_1_OR_NEWER
                _lastPlayedTimelineClip = null;
#endif

                if (_nTrackData == 0)
                {
                    return;
                }

                for (int i = 0; i < _nTrackData; i++)
                {
                    _curTrackData = _trackData[i];
                    _curTrackData.Update(animPlayManager);
                }

                //0번 레이어의 마지막으로 재생된 클립 정보를 받자
#if UNITY_2017_1_OR_NEWER
                _lastPlayedTimelineClip = _trackData[0]._lastPlayedTimelineClip;
#endif
                _lastPlayedLocalTime = _trackData[0]._lastPlayedLocalTime;
            }
Exemplo n.º 4
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);
                        }
                    }
                }
            }
        }
            //트랙을 추가한다.
            public bool AddTrack(string trackName, int layer, apAnimPlayUnit.BLEND_METHOD blendMethod, apPortrait portrait, apAnimPlayManager animPlayManager)
            {
                //이미 적용된 트랙이 있다면, 에러 메시지를 보낸다.
                bool isExist = _trackData.Exists(delegate(TimelineTrackData a)
                {
                    return(a._trackName.Equals(trackName));
                });

                if (isExist)
                {
                    Debug.LogError("AnyPortrait : A track with the same name has already been registered. [ " + trackName + " ]");
                    return(false);
                }

                TimelineTrackData newTrackData = new TimelineTrackData(this);
                bool isResult = newTrackData.SetTrack(trackName, layer, blendMethod, portrait, animPlayManager);

                if (!isResult)
                {
                    return(false);
                }

                //리스트에 트랙 추가
                _trackData.Add(newTrackData);
                _nTrackData = _trackData.Count;

                //트랙을 추가했으면, Layer에 맞게 정렬한다. (오름차순)
                _trackData.Sort(delegate(TimelineTrackData a, TimelineTrackData b)
                {
                    return(a._layerIndex - b._layerIndex);
                });

                for (int i = 0; i < _trackData.Count; i++)
                {
                    _trackData[i].SetLayerOrder(i);                    //<<레이어의 순서를 다시 지정한다.
                }

                return(true);
            }
            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
            }
            public bool SetTrack(string trackName, int layerIndex, apAnimPlayUnit.BLEND_METHOD blendMethod, apPortrait portrait, apAnimPlayManager animPlayManager)
            {
#if UNITY_2017_1_OR_NEWER
                //PlayableDirector playDirector = _parentTrackSet._playableDirector;
                PlayableAsset playAsset = _parentTrackSet._playableAsset;
#endif

                _trackName  = trackName;
                _layerIndex = layerIndex;
#if UNITY_2017_1_OR_NEWER
                _layerOrder = _layerIndex;
#endif
                _blendMethod = blendMethod;

                if (string.IsNullOrEmpty(_trackName))
                {
                    //이름이 빈칸이거나 null이다.
                    return(false);
                }

                _clipData = new List <TimelineClipData>();
#if UNITY_2017_1_OR_NEWER
                _timelineClips   = new List <TimelineClip>();
                _clipDataByTrack = new Dictionary <TimelineClip, TimelineClipData>();
#endif

                _nClipData = 0;

                //연결을 하자
                bool isFind = false;
#if UNITY_2017_1_OR_NEWER
                _animationTrack = null;
#endif

                //그 전에 AnimClip <-> AnimationClipAsset을 서로 연결해야한다.
                apAnimClip    curAnimClip           = null;
                AnimationClip curAnimationClipAsset = null;
                Dictionary <AnimationClip, apAnimClip> animClipAsset2AnimClip = new Dictionary <AnimationClip, apAnimClip>();

                for (int i = 0; i < portrait._animClips.Count; i++)
                {
                    curAnimClip = portrait._animClips[i];
                    if (curAnimClip == null)
                    {
                        continue;
                    }
                    curAnimationClipAsset = curAnimClip._animationClipForMecanim;
                    if (curAnimationClipAsset == null)
                    {
                        continue;
                    }

                    if (animClipAsset2AnimClip.ContainsKey(curAnimationClipAsset))
                    {
                        continue;
                    }

                    animClipAsset2AnimClip.Add(curAnimationClipAsset, curAnimClip);
                }

                //apAnimClip에 해당하는 apOptRootUnit을 알아야 한다.
                //apAnimPlayData에 그 정보가 저장되어 있으니 참조하자
                apAnimPlayData curPlayData = null;
                Dictionary <apAnimClip, apOptRootUnit> animClip2RootUnit = new Dictionary <apAnimClip, apOptRootUnit>();

                for (int i = 0; i < animPlayManager._animPlayDataList.Count; i++)
                {
                    curPlayData = animPlayManager._animPlayDataList[i];
                    if (curPlayData == null)
                    {
                        continue;
                    }
                    if (curPlayData._linkedAnimClip == null || curPlayData._linkedOptRootUnit == null)
                    {
                        continue;
                    }

                    if (animClip2RootUnit.ContainsKey(curPlayData._linkedAnimClip))
                    {
                        continue;
                    }

                    //apAnimClip -> apOptRootUnit으로 연결 데이터 추가
                    animClip2RootUnit.Add(curPlayData._linkedAnimClip, curPlayData._linkedOptRootUnit);
                }


#if UNITY_2017_1_OR_NEWER
                foreach (PlayableBinding playableBinding in playAsset.outputs)
                {
#endif
#if UNITY_2018_1_OR_NEWER
                bool isAnimTrack = playableBinding.sourceObject != null && playableBinding.sourceObject is AnimationTrack;
#elif UNITY_2017_1_OR_NEWER
                bool isAnimTrack = playableBinding.streamType == DataStreamType.Animation;
#endif
                //if (playableBinding.streamType != DataStreamType.Animation)
#if UNITY_2017_1_OR_NEWER
                if (!isAnimTrack)
                {
                    //애니메이션 타입이 아니라면 패스
                    continue;
                }

                AnimationTrack animTrack = playableBinding.sourceObject as AnimationTrack;
                if (animTrack == null)
                {
                    continue;
                }
                //if(animTrack.isEmpty)
                //{
                //	//클립이 아예 없는데용
                //	continue;
                //}

                if (!animTrack.name.Equals(_trackName))
                {
                    //이름이 다르다.
                    continue;
                }

                if (animTrack.isEmpty)
                {
                    //클립이 아예 없는데용
                    //continue;
                    Debug.LogWarning("AnyPortrait : ( Warning ) No Clip in the requested track. [ " + trackName + " ]");
                    //일단 처리는 하자
                }

                //이름도 같고 유효한 트랙을 찾았다!
                isFind          = true;
                _animationTrack = animTrack;


                AnimationClip animClipInTrack = null;
                apAnimClip targetAnimClip     = null;
                apOptRootUnit targetRootUnit  = null;

                foreach (TimelineClip timelineClip in _animationTrack.GetClips())
                {
                    //Track의 TimelineClip 중에서 유효한 AnimationClip만 선택한다.
                    animClipInTrack = timelineClip.animationClip;

                    if (!animClipAsset2AnimClip.ContainsKey(animClipInTrack))
                    {
                        //유효한 AnimationClip이 아니다.
                        continue;
                    }

                    targetAnimClip = animClipAsset2AnimClip[animClipInTrack];

                    if (targetAnimClip == null)
                    {
                        //animClip이 비어있다.
                        continue;
                    }

                    if (!animClip2RootUnit.ContainsKey(targetAnimClip))
                    {
                        //apAnimClip -> apOptRootUnit을 조회할 수 없다.
                        continue;
                    }

                    targetRootUnit = animClip2RootUnit[targetAnimClip];
                    if (targetRootUnit == null)
                    {
                        //RootUnit이 null이다.
                        continue;
                    }


                    TimelineClipData newClipData = new TimelineClipData(timelineClip, targetAnimClip, targetRootUnit);
                    _clipData.Add(newClipData);

                    _timelineClips.Add(timelineClip);
                    _clipDataByTrack.Add(timelineClip, newClipData);
                    //_clipDataByAnimClip.Add(targetAnimClip, newClipData);
                    _nClipData++;
                }

                //Debug.Log("Track [" + trackName + "] Added");

                //<<추가>> 시간대에 따라서 Sort
                _clipData.Sort(delegate(TimelineClipData a, TimelineClipData b)
                {
                    return((int)((a._timelineClip.start - b._timelineClip.start) * 100.0));
                });

                if (isFind)
                {
                    break;
                }
            }
#endif
                if (!isFind)
                {
                    Debug.LogError("AnyPortrait : No track with the requested name. [" + trackName + "]");
                }
                return(isFind);
            }