예제 #1
0
        // [런타임에서] Portrait를 연결하고, Portrait를 검색하여 animPlayData를 세팅한다.
        // 다른 Link가 모두 끝난뒤에 호출하자
        /// <summary>
        /// Connect to Portrait and initialize it for runtime processing.
        /// </summary>
        /// <param name="portrait"></param>
        public void LinkPortrait(apPortrait portrait)
        {
            _portrait = portrait;

            InitAndLink();

            if (_animPlayDataList == null)
            {
                _animPlayDataList = new List <apAnimPlayData>();
            }

            apAnimPlayData animPlayData = null;

            for (int i = 0; i < _animPlayDataList.Count; i++)
            {
                animPlayData          = _animPlayDataList[i];
                animPlayData._isValid = false;                //일단 유효성 초기화 (나중에 값 넣으면 자동으로 true)

                apAnimClip animClip = _portrait.GetAnimClip(animPlayData._animClipID);


                apOptRootUnit rootUnit = _portrait._optRootUnitList.Find(delegate(apOptRootUnit a)
                {
                    if (a._rootOptTransform != null)
                    {
                        if (a._rootOptTransform._meshGroupUniqueID == animPlayData._meshGroupID)
                        {
                            return(true);
                        }
                    }
                    return(false);
                });

                if (animClip != null && rootUnit != null)
                {
                    animPlayData.Link(animClip, rootUnit);

                    //추가 : 여기서 ControlParamResult를 미리 만들어서 이후에 AnimClip이 미리 만들수 있게 해주자
                    animClip.MakeAndLinkControlParamResults();
                }
            }

            //추가 : 메카님 연동
            _mecanim.LinkPortrait(portrait, this);


            if (portrait._isUsingMecanim && portrait._animator != null)
            {
                _isMecanim = true;
            }
            else
            {
                _isMecanim = false;
            }
        }
        //추가 : AnimPlayData로 PlayQueued를 바로 실행하는 함수가 나오면서, 이름으로 검색하는 건 오버로드로 뺌
        public apAnimPlayData PlayQueued(string animClipName, int layer, apAnimPlayUnit.BLEND_METHOD blendMethod, bool isAutoEndIfNotloop = false)
        {
            apAnimPlayData playData = GetAnimPlayData_Opt(animClipName);

            if (playData == null)
            {
                Debug.LogError("PlayQueued Failed : No AnimClip [" + animClipName + "]");
                return(null);
            }
            return(PlayQueued(playData, layer, blendMethod, isAutoEndIfNotloop));
        }
        public bool IsPlaying(string animClipName)
        {
            apAnimPlayData animPlayData = GetAnimPlayData_Opt(animClipName);

            if (animPlayData == null)
            {
                Debug.LogError("No AnimCip : " + animClipName);
                return(false);
            }
            return(animPlayData._linkedAnimClip.IsPlaying_Opt);
        }
        //추가 : AnimPlayData로 PlayQueued를 바로 실행하는 함수가 나오면서, 이름으로 검색하는 건 오버로드로 뺌
        public apAnimPlayData CrossFade(string animClipName, int layer, apAnimPlayUnit.BLEND_METHOD blendMethod, float fadeTime, PLAY_OPTION playOption = PLAY_OPTION.StopSameLayer, bool isAutoEndIfNotloop = false)
        {
            apAnimPlayData playData = GetAnimPlayData_Opt(animClipName);

            if (playData == null)
            {
                Debug.LogError("CrossFade Failed : No AnimClip [" + animClipName + "]");
                return(null);
            }
            return(CrossFade(playData, layer, blendMethod, fadeTime, playOption, isAutoEndIfNotloop));
        }
예제 #5
0
        //애니메이션 속도 설정
        public void SetAnimSpeed(string animClipName, float speed)
        {
            apAnimPlayData animPlayData = GetAnimPlayData_Opt(animClipName);

            if (animPlayData == null)
            {
                Debug.LogError("No AnimCip : " + animClipName);
                return;
            }
            animPlayData._linkedAnimClip._speedRatio = speed;
        }
        public apAnimPlayData CrossFadeQueuedAt(string animClipName, int frame, int layer, apAnimPlayUnit.BLEND_METHOD blendMethod, float fadeTime, bool isAutoEndIfNotloop = false)
        {
            apAnimPlayData playData = GetAnimPlayData_Opt(animClipName);

            if (playData == null)
            {
                Debug.LogError("CrossFadeQueuedAt Failed : No AnimClip [" + animClipName + "]");
                return(null);
            }
            return(CrossFadeQueuedAt(playData, frame, layer, blendMethod, fadeTime, isAutoEndIfNotloop));
        }
        public apAnimPlayData.AnimationPlaybackStatus GetAnimationPlaybackStatus(string animClipName)
        {
            apAnimPlayData animPlayData = GetAnimPlayData_Opt(animClipName);

            if (animPlayData == null)
            {
                Debug.LogError("No AnimCip : " + animClipName);
                return(apAnimPlayData.AnimationPlaybackStatus.None);
            }
            return(animPlayData.PlaybackStatus);
        }
        /// <summary>
        /// [Please do not use it] Set AnimClip to get data
        /// </summary>
        /// <param name="playData"></param>
        /// <param name="layer"></param>
        /// <param name="blendMethod"></param>
        /// <param name="isAutoEndIfNotLoop"></param>
        /// <param name="isEditor"></param>
        public void SetAnimClip(apAnimPlayData playData, int layer, BLEND_METHOD blendMethod, bool isAutoEndIfNotLoop, bool isEditor)
        {
            _linkedAnimClip = playData._linkedAnimClip;
            _targetRootUnit = playData._linkedOptRootUnit;

            //추가
            if (_linkedAnimClip._parentPlayUnit != null &&
                _linkedAnimClip._parentPlayUnit != this)
            {
                //이미 다른 PlayUnit이 사용중이었다면..
                _linkedAnimClip._parentPlayUnit.SetEnd();
                //_linkedAnimClip._parentPlayUnit._linkedAnimClip = null;
            }
            _linkedAnimClip._parentPlayUnit = this;

            _layer = layer;

            _isLoop    = _linkedAnimClip.IsLoop;
            _isAutoEnd = isAutoEndIfNotLoop;
            if (_isLoop)
            {
                _isAutoEnd = false;                //<<Loop일때 AutoEnd는 불가능하다
            }


            _blendMethod = blendMethod;

            _isPause                = false;
            _playStatus             = PLAY_STATUS.Ready;
            _isPlayStartEventCalled = false;
            _isEndEventCalled       = false;


            //_speedRatio = 1.0f;

            _isFirstFrame   = true;
            _nextPlayStatus = _playStatus;

            //추가 1.14
            _isResetFrameOnReadyStatus = true;

            if (isEditor)
            {
                _linkedAnimClip.Stop_Editor(false);                //Stop은 하되 업데이트는 하지 않는다. (false)
            }
            else
            {
                _linkedAnimClip.Stop_Opt(false);
            }

            _unitWeight          = 0.0f;
            _totalRequestWeights = 0.0f;
        }
예제 #9
0
        /// <summary>
        /// Wait for the previous animation to finish, then play it smoothly.
        /// (If the previously playing animation is a loop animation, it will not be executed.)
        /// </summary>
        /// <param name="animClipName">Name of the Animation Clip</param>
        /// <param name="fadeTime">Fade Time</param>
        /// <param name="layer">The layer to which the animation is applied. From 0 to 20</param>
        /// <param name="blendMethod">How it is blended with the animation of the lower layers</param>
        /// <param name="isAutoEndIfNotloop">If True, animation that does not play repeatedly is automatically terminated.</param>
        /// <returns>Animation data to be played. If it fails, null is returned.</returns>
        public apAnimPlayData CrossFadeQueued(string animClipName, int layer, apAnimPlayUnit.BLEND_METHOD blendMethod, float fadeTime, bool isAutoEndIfNotloop = false)
        {
            //Debug.LogError("Start CrossFadeQueued [" + animClipName + "]");

            apAnimPlayData playData = GetAnimPlayData_Opt(animClipName);

            if (playData == null)
            {
                Debug.LogError("CrossFade Failed : No AnimClip [" + animClipName + "]");
                return(null);
            }

            if (layer < MIN_LAYER_INDEX || layer > MAX_LAYER_INDEX)
            {
                Debug.LogError("CrossFade Failed : Layer " + layer + " is invalid. Layer must be between " + MIN_LAYER_INDEX + " ~ " + MAX_LAYER_INDEX);
                return(null);
            }

            if (fadeTime < 0.0f)
            {
                fadeTime = 0.0f;
            }

            //Debug.Log("CrossFadeQueued [" + animClipName + "]");

            apAnimPlayQueue playQueue      = _animPlayQueues[layer];
            apAnimPlayUnit  resultPlayUnit = playQueue.PlayQueued(playData, blendMethod, fadeTime, isAutoEndIfNotloop);

            if (resultPlayUnit == null)
            {
                return(null);
            }

            //float delayTime = resultPlayUnit.DelayToPlayTime;
            //float delayTime = Mathf.Clamp01(resultPlayUnit.RemainPlayTime - fadeTime);

            //if (playOption == PLAY_OPTION.StopAllLayers)
            //{
            //	//다른 레이어를 모두 정지시킨다. - 단, 딜레이를 준다.
            //	for (int i = 0; i < _animPlayQueues.Count; i++)
            //	{
            //		if (i == layer)
            //		{ continue; }
            //		_animPlayQueues[i].StopAll(delayTime);
            //	}
            //}

            RefreshPlayOrders();

            return(playData);
        }
        //----------------------------------------------------------------------------------------
        public apAnimPlayData PlayAt(string animClipName, int frame, int layer, apAnimPlayUnit.BLEND_METHOD blendMethod, PLAY_OPTION playOption = PLAY_OPTION.StopSameLayer, bool isAutoEndIfNotloop = false, bool isDebugMsg = true)
        {
            apAnimPlayData playData = GetAnimPlayData_Opt(animClipName);

            if (playData == null)
            {
                if (isDebugMsg)
                {
                    Debug.LogError("PlayAt Failed : No AnimClip [" + animClipName + "]");
                }
                return(null);
            }
            return(PlayAt(playData, frame, layer, blendMethod, playOption, isAutoEndIfNotloop, isDebugMsg));
        }
예제 #11
0
        /// <summary>
        /// AnimClip 이름을 인자로 받아서 애니메이션을 재생한다.
        /// Fade 타임을 받아서 다른 모든 클립에서 자연스럽게 변환된다.
        /// </summary>
        /// <param name="animClipName">Clip 이름. 맞지 않을 경우 처리 실패</param>
        /// <param name="layer">실행되는 레이어. 0부터 실행되며 최대값은 20</param>
        /// <param name="blendMethod">다른 레이어와 블렌드시 옵션</param>
        /// <param name="playOption">StopAllLayer인 경우 요청된 레이어 외의 Clip들이 다음 Clip이 실행되는 순간 같이 종료된다.</param>
        /// <param name="isAutoEndIfNotloop">[Loop 타입이 아닌 경우] True이면 재생 종료시 자동으로 처리 데이터가 삭제된다.</param>
        /// <param name="fadeTime">페이드 시간. 기본값은 0.3</param>
        /// <returns></returns>
        public apAnimPlayData CrossFade(string animClipName, int layer, apAnimPlayUnit.BLEND_METHOD blendMethod, float fadeTime, PLAY_OPTION playOption = PLAY_OPTION.StopSameLayer, bool isAutoEndIfNotloop = false)
        {
            apAnimPlayData playData = GetAnimPlayData_Opt(animClipName);

            if (playData == null)
            {
                Debug.LogError("CrossFade Failed : No AnimClip [" + animClipName + "]");
                return(null);
            }

            if (layer < MIN_LAYER_INDEX || layer > MAX_LAYER_INDEX)
            {
                Debug.LogError("CrossFade Failed : Layer " + layer + " is invalid. Layer must be between " + MIN_LAYER_INDEX + " ~ " + MAX_LAYER_INDEX);
                return(null);
            }

            if (fadeTime < 0.0f)
            {
                fadeTime = 0.0f;
            }

            apAnimPlayQueue playQueue      = _animPlayQueues[layer];
            apAnimPlayUnit  resultPlayUnit = playQueue.Play(playData, blendMethod, fadeTime, isAutoEndIfNotloop);

            if (resultPlayUnit == null)
            {
                return(null);
            }


            //float fadeInTime = resultPlayUnit.FadeInTime;

            if (playOption == PLAY_OPTION.StopAllLayers)
            {
                //다른 레이어를 모두 정지시킨다. - 단, 딜레이를 준다.
                for (int i = 0; i < _animPlayQueues.Count; i++)
                {
                    if (i == layer)
                    {
                        continue;
                    }
                    _animPlayQueues[i].StopAll(fadeTime);
                }
            }

            RefreshPlayOrders();

            return(playData);
        }
예제 #12
0
        private apAnimPlayUnit MakePlayUnit(apAnimPlayData playData, apAnimPlayUnit.BLEND_METHOD blendMethod, bool isAutoEndIfNotloop)
        {
            //새로 만들고
            //그 전에..
            //재생중인 PlayUnit이 있으면 그걸 사용하자
            //레이어는 같아야 한다.
            apAnimPlayUnit existPlayUnit = null;

            for (int i = 0; i < _animPlayUnits.Count; i++)
            {
                if (_animPlayUnits[i]._linkedAnimClip == playData._linkedAnimClip &&
                    _animPlayUnits[i].IsUpdatable

                    )
                {
                    existPlayUnit = _animPlayUnits[i];
                    break;
                }
            }
            if (existPlayUnit != null)
            {
                //Debug.Log("아직 재생중인 PlayUnit을 다시 재생하는 요청이 왔다. [" + existPlayUnit._linkedAnimClip._name + "]");
                existPlayUnit.SetSubOption(blendMethod, isAutoEndIfNotloop, GetNextPlayUnitRequestOrder(), GetNextRequestLinkKey());

                _nPlayedUnit = _animPlayUnits.Count;
                return(existPlayUnit);
            }

            apAnimPlayUnit newPlayUnit = new apAnimPlayUnit(this, GetNextPlayUnitRequestOrder(), GetNextRequestLinkKey());

            newPlayUnit.SetAnimClip(playData, _layer, blendMethod, isAutoEndIfNotloop, false);

            //if(!newPlayUnit._linkedAnimClip.IsPlaying)
            //{
            //	if(newPlayUnit.Frame != newPlayUnit.StartFrame)
            //	{
            //		Debug.Log("새로운 재생 요청 - 프레임이 초기화되지 않음 [" + newPlayUnit._linkedAnimClip._name + "]");
            //	}
            //	newPlayUnit.ResetPlay();
            //}

            //리스트에 넣자
            _animPlayUnits.Add(newPlayUnit);

            _nPlayedUnit    = _animPlayUnits.Count;
            _isInitPlayUnit = false;
            return(newPlayUnit);
        }
        /// <summary>
        /// Play the animation
        /// </summary>
        /// <param name="animClipName">Name of the Animation Clip</param>
        /// <param name="layer">The layer to which the animation is applied. From 0 to 20</param>
        /// <param name="blendMethod">How it is blended with the animation of the lower layers</param>
        /// <param name="playOption">How to stop which animations</param>
        /// <param name="isAutoEndIfNotloop">If True, animation that does not play repeatedly is automatically terminated.</param>
        /// <returns>Animation data to be played. If it fails, null is returned.</returns>
        public apAnimPlayData Play(apAnimPlayData playData, int layer, apAnimPlayUnit.BLEND_METHOD blendMethod, PLAY_OPTION playOption = PLAY_OPTION.StopSameLayer, bool isAutoEndIfNotloop = false, bool isDebugMsg = true)
        {
            if (playData == null)
            {
                if (isDebugMsg)
                {
                    Debug.LogError("Play Failed : Unknown AnimPlayData");
                }
                return(null);
            }

            if (layer < MIN_LAYER_INDEX || layer > MAX_LAYER_INDEX)
            {
                if (isDebugMsg)
                {
                    Debug.LogError("Play Failed : Layer " + layer + " is invalid. Layer must be between " + MIN_LAYER_INDEX + " ~ " + MAX_LAYER_INDEX);
                }
                return(null);
            }

            apAnimPlayQueue playQueue      = _animPlayQueues[layer];
            apAnimPlayUnit  resultPlayUnit = playQueue.Play(playData, blendMethod, 0.0f, isAutoEndIfNotloop);

            if (resultPlayUnit == null)
            {
                return(null);
            }



            if (playOption == PLAY_OPTION.StopAllLayers)
            {
                //다른 레이어를 모두 정지시킨다.
                for (int i = 0; i < _animPlayQueues.Count; i++)
                {
                    if (i == layer)
                    {
                        continue;
                    }
                    _animPlayQueues[i].StopAll(0.0f);
                }
            }

            RefreshPlayOrders();

            return(playData);
        }
        /// <summary>
        /// Wait for the previous animation to finish, then play it.
        /// (If the previously playing animation is a loop animation, it will not be executed.)
        /// </summary>
        /// <param name="animClipName">Name of the Animation Clip</param>
        /// <param name="layer">The layer to which the animation is applied. From 0 to 20</param>
        /// <param name="blendMethod">How it is blended with the animation of the lower layers</param>
        /// <param name="isAutoEndIfNotloop">If True, animation that does not play repeatedly is automatically terminated.</param>
        /// <returns>Animation data to be played. If it fails, null is returned.</returns>
        public apAnimPlayData PlayQueued(apAnimPlayData playData, int layer, apAnimPlayUnit.BLEND_METHOD blendMethod, bool isAutoEndIfNotloop = false)
        {
            if (playData == null)
            {
                Debug.LogError("PlayQueued Failed : Unknown AnimPlayData");
                return(null);
            }

            if (layer < MIN_LAYER_INDEX || layer > MAX_LAYER_INDEX)
            {
                Debug.LogError("PlayQueued Failed : Layer " + layer + " is invalid. Layer must be between " + MIN_LAYER_INDEX + " ~ " + MAX_LAYER_INDEX);
                return(null);
            }

            apAnimPlayQueue playQueue      = _animPlayQueues[layer];
            apAnimPlayUnit  resultPlayUnit = playQueue.PlayQueued(playData, blendMethod, 0.0f, isAutoEndIfNotloop);

            if (resultPlayUnit == null)
            {
                return(null);
            }



            //if (playOption == PLAY_OPTION.StopAllLayers)
            //{
            //	//다른 레이어를 모두 정지시킨다. - 단, 딜레이를 준다.
            //	for (int i = 0; i < _animPlayQueues.Count; i++)
            //	{
            //		if (i == layer)
            //		{ continue; }
            //		_animPlayQueues[i].StopAll(delayTime);
            //	}
            //}

            RefreshPlayOrders();

            return(playData);
        }
예제 #15
0
        private apAnimPlayUnit MakePlayUnit(apAnimPlayData playData, apAnimPlayUnit.BLEND_METHOD blendMethod, bool isAutoEndIfNotloop)
        {
            //새로 만들고
            //그 전에..
            //재생중인 PlayUnit이 있으면 그걸 사용하자
            //레이어는 같아야 한다.
            apAnimPlayUnit existPlayUnit = null;

            for (int i = 0; i < _animPlayUnits.Count; i++)
            {
                if (_animPlayUnits[i]._linkedAnimClip == playData._linkedAnimClip &&
                    _animPlayUnits[i].IsUpdatable

                    )
                {
                    existPlayUnit = _animPlayUnits[i];
                    break;
                }
            }
            if (existPlayUnit != null)
            {
                //Debug.Log("아직 재생중인 PlayUnit을 다시 재생하는 요청이 왔다. [" + existPlayUnit._linkedAnimClip._name + "]");
                existPlayUnit.SetSubOption(blendMethod, isAutoEndIfNotloop);

                _nPlayedUnit = _animPlayUnits.Count;
                return(existPlayUnit);
            }

            apAnimPlayUnit newPlayUnit = new apAnimPlayUnit(this);

            newPlayUnit.SetAnimClip(playData, _layer, blendMethod, isAutoEndIfNotloop, false);

            //리스트에 넣자
            _animPlayUnits.Add(newPlayUnit);

            _nPlayedUnit = _animPlayUnits.Count;
            return(newPlayUnit);
        }
예제 #16
0
        //----------------------------------------------------
        // 재생/정지 요청 함수들
        //----------------------------------------------------

        /// <summary>
        /// AnimClip을 PlayUnit에 담아서 재생한다.
        /// Queue에 저장된 모든 클립은 무시되며 블렌드되지 않는다.
        /// </summary>
        /// <param name="blendMethod"></param>
        /// <param name="isAutoEndIfNotloop">True이면 Clip의 재생 후 자동으로 종료한다. (Loop일 경우 무시됨)</param>
        public apAnimPlayUnit Play(apAnimPlayData playData, apAnimPlayUnit.BLEND_METHOD blendMethod, float blendTime = 0.0f, bool isAutoEndIfNotloop = true)
        {
            //Request를 생성한다.
            apAnimPlayRequest request = PopRequest();

            request.SetCurrentPlayedUnits(this, _animPlayUnits);


            apAnimPlayUnit newPlayUnit = MakePlayUnit(playData, blendMethod, isAutoEndIfNotloop);

            //newPlayUnit.Play();

            //Play 명령을 준다.
            request.PlayNew(newPlayUnit, blendTime);

            #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;



            //Debug.Log("Next Play Units [" + _nPlayedUnit + "]");
            return(newPlayUnit);
        }
            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);
            }
예제 #18
0
        /// <summary>
        /// [Please do not use it] Set AnimClip to get data
        /// </summary>
        /// <param name="playData"></param>
        /// <param name="layer"></param>
        /// <param name="blendMethod"></param>
        /// <param name="isAutoEndIfNotLoop"></param>
        /// <param name="isEditor"></param>
        public void SetAnimClip(apAnimPlayData playData, int layer, BLEND_METHOD blendMethod, bool isAutoEndIfNotLoop, bool isEditor)
        {
            _linkedAnimClip = playData._linkedAnimClip;
            _targetRootUnit = playData._linkedOptRootUnit;

            //추가
            if (_linkedAnimClip._parentPlayUnit != null &&
                _linkedAnimClip._parentPlayUnit != this)
            {
                //이미 다른 PlayUnit이 사용중이었다면..
                _linkedAnimClip._parentPlayUnit.SetEnd();
                //_linkedAnimClip._parentPlayUnit._linkedAnimClip = null;
            }
            _linkedAnimClip._parentPlayUnit = this;

            _layer = layer;

            _isLoop    = _linkedAnimClip.IsLoop;
            _isAutoEnd = isAutoEndIfNotLoop;
            if (_isLoop)
            {
                _isAutoEnd = false;                //<<Loop일때 AutoEnd는 불가능하다
            }


            _blendMethod = blendMethod;

            _isPause                = false;
            _playStatus             = PLAY_STATUS.Ready;
            _isPlayStartEventCalled = false;
            _isEndEventCalled       = false;

            //_fadeInTime = 0.0f;
            //_fadeOutTime = 0.0f;

            //_delayToPlayTime = 0.0f;
            //_delayToEndTime = 0.0f;

            _speedRatio = 1.0f;

            _isFirstFrame   = true;
            _nextPlayStatus = _playStatus;

            if (isEditor)
            {
                _linkedAnimClip.Stop_Editor(false);                //Stop은 하되 업데이트는 하지 않는다. (false)
            }
            else
            {
                _linkedAnimClip.Stop_Opt(false);
            }

            //_tAnimClipLength = _linkedAnimClip.TimeLength;
            _unitWeight          = 0.0f;
            _isWeightCalculated  = false;
            _totalRequestWeights = 0.0f;
            //_prevUnitWeight = 0.0f;

            //_debugWeight1 = 0.0f;
            //_debugWeight2 = 0.0f;
            //_debugWeight3 = 0.0f;

            //_isDelayIn = false;
            //_isDelayOut = false;

            //_tDelay = 0.0f;
        }
예제 #19
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);
                        }
                    }
                }
            }
        }
예제 #20
0
        /// <summary>
        /// AnimClip을 PlayUnit에 담아서 재생한다.
        /// Queue에 저장된 클립들이 모두 끝나면 블렌드 없이 바로 실행된다.
        /// </summary>
        /// <param name="blendMethod"></param>
        /// <param name="isAutoEndIfNotloop">True이면 Clip의 재생 후 자동으로 종료한다. (Loop일 경우 무시됨)</param>
        /// <returns></returns>
        public apAnimPlayUnit PlayQueued(apAnimPlayData playData, apAnimPlayUnit.BLEND_METHOD blendMethod, float blendTime = 0.0f, bool isAutoEndIfNotloop = true)
        {
            //현재 재생되는 플레이 유닛 중에서 "가장 많이 남은 플레이 시간"을 기준으로 타이머를 잡자
            //Fade 타임은 없고, 자동 삭제 타이머 + 자동 재생 대기 타이머를 지정

            //현재 Queue에 있는 객체가 없다면 Play와 동일하다
            if (_nPlayedUnit == 0)
            {
                return(Play(playData, blendMethod, blendTime, isAutoEndIfNotloop));
            }

            //마지막 PlayUnit을 가져오자
            apAnimPlayUnit lastPlayUnit = _animPlayUnits[_animPlayUnits.Count - 1];

            if (lastPlayUnit.IsLoop)
            {
                //만약 마지막 PlayUnit이 Loop라면 => Queued 되지 않는다. 자동으로 [Play]로 바뀜
                return(Play(playData, blendMethod, blendTime, isAutoEndIfNotloop));
            }

            //Request를 생성한다.
            apAnimPlayRequest request = PopRequest();

            request.SetCurrentPlayedUnits(this, _animPlayUnits);


            apAnimPlayUnit newPlayUnit = MakePlayUnit(playData, blendMethod, isAutoEndIfNotloop);

            newPlayUnit.Pause();

            //Play Queued 명령을 준다.
            request.PlayQueued(newPlayUnit, lastPlayUnit, blendTime);



            #region [미사용 코드] 미리 시간을 예상해서 처리하는 것은 문제가 많다.
            //float maxRemainPlayTime = -1.0f;
            //float curRemainPlayTime = 0.0f;
            //bool isAnyOnceAnimClip = false;
            //for (int i = 0; i < _nPlayedUnit; i++)
            //{
            //	_tmpCurPlayUnit = _animPlayUnits[i];
            //	if(_tmpCurPlayUnit.IsLoop)
            //	{
            //		//하나라도 루프이면 실패다.
            //		//Queue에 넣어도 작동하지 않는다.

            //		//>수정
            //		//루프는 무시하고 Queue 시간을 잡자
            //		//만약 Loop를 만나고 Queue가 있다면 그냥 기본값인 0.5초를 Queue 시간으로 쓴다.

            //		//Debug.LogError("PlayQueued Failed : Any Clip has Loop Option. Adding to Queue will be ignored");
            //		//return null;
            //		continue;
            //	}

            //	isAnyOnceAnimClip = true;
            //	curRemainPlayTime = _tmpCurPlayUnit.GetRemainPlayTime;
            //	if(maxRemainPlayTime < curRemainPlayTime)
            //	{
            //		maxRemainPlayTime = curRemainPlayTime;
            //	}
            //}

            //if(!isAnyOnceAnimClip)
            //{
            //	maxRemainPlayTime = 0.5f;
            //}
            //if(maxRemainPlayTime < 0.0f)
            //{
            //	maxRemainPlayTime = 0.0f;
            //}

            ////최대 RemainPlayTime 만큼 Delay한다.
            //// Delay후 신규 플레이 또는 플레이 종료를 한다.
            ////Fade 시간은 0

            //apAnimPlayUnit newPlayUnit = MakePlayUnit(playData, blendMethod, isAutoEndIfNotloop);
            //newPlayUnit.Play(0.0f, maxRemainPlayTime);

            ////Debug.LogError("TODO : 이 AnimClip을 CalculatedParam에 연결해야한다");

            //for (int i = 0; i < _nPlayedUnit; i++)
            //{
            //	_tmpCurPlayUnit = _animPlayUnits[i];
            //	if (newPlayUnit != _tmpCurPlayUnit)
            //	{
            //		_tmpCurPlayUnit.FadeOut(0.0f, maxRemainPlayTime);
            //	}
            //}
            #endregion

            _nPlayedUnit = _animPlayUnits.Count;

            return(newPlayUnit);
        }