// Opt용 Update / Opt 플레이 제어 //--------------------------------------------- // Opt용 Update 함수들은 "플레이 상태"의 영향을 받지 않는다. // AnimPlayUnit에 래핑된 상태이므로 모든 제어에 대해서 바로 처리한다. // Editor와 달리 "실수형 CurFrame"을 이용하며, Reverse 처리도 가능하다 // MeshGroup과 ControlParam을 직접 제어하진 않는다. (AnimPlayUnit이 한다) /// <summary> /// [Opt 실행] Delta만큼 업데이트를 한다. /// Keyframe Weight와 Control Param Result를 만든다. /// </summary> /// <param name="tDelta">재생 시간. 음수면 Reverse가 된다.</param> /// <returns>Update가 종료시 True, 그 외에는 False이다.</returns> public bool Update_Opt(float tDelta) { _tUpdate += tDelta; _tUpdateTotal += tDelta; bool isEnd = false; if (tDelta > 0) { //Speed Ratio가 크면 프레임이 한번에 여러개 이동할 수 있다. while (_tUpdate > TimePerFrame) { //프레임이 증가한다. _curFrame++; _tUpdate -= TimePerFrame; if (_curFrame >= _endFrame) { if (_isLoop) { //루프일 경우 -> 첫 프레임으로 돌아간다. _curFrame = _startFrame; _tUpdateTotal -= TimeLength; //Animation 이벤트도 리셋한다. if (_animEvents != null && _animEvents.Count > 0) { for (int i = 0; i < _animEvents.Count; i++) { _animEvents[i].ResetCallFlag(); } } } else { //루프가 아닐 경우 _curFrame = _endFrame; _tUpdate = 0.0f; _tUpdateTotal = TimeLength; isEnd = true; break; } } //UpdateControlParam(false, _parentPlayUnit._layer, _parentPlayUnit.UnitWeight, _parentPlayUnit.BlendMethod); } } else if (tDelta < 0) { while (_tUpdate < 0.0f) { //프레임이 감소한다. _curFrame--; _tUpdate += TimePerFrame; if (_curFrame <= _startFrame) { if (_isLoop) { //루프일 경우 -> 마지막 프레임으로 돌아간다. _curFrame = _endFrame; _tUpdateTotal += TimeLength; //Animation 이벤트도 리셋한다. if (_animEvents != null && _animEvents.Count > 0) { for (int i = 0; i < _animEvents.Count; i++) { _animEvents[i].ResetCallFlag(); } } } else { //루프가 아닐 경우 _curFrame = _startFrame; _tUpdate = 0.0f; _tUpdateTotal = 0.0f; isEnd = true; break; } } //UpdateControlParam(false, _parentPlayUnit._layer, _parentPlayUnit.UnitWeight, _parentPlayUnit.BlendMethod); } } float unitWeight = _parentPlayUnit.UnitWeight; //이거 문제 생기면 끈다. //if (_parentPlayUnit._playOrder == 0) //{ // unitWeight = 1.0f; //} //??이거요? //UpdateControlParam(false, _parentPlayUnit._layer, _parentPlayUnit.UnitWeight, _parentPlayUnit.BlendMethod); UpdateControlParam(false, _parentPlayUnit._layer, unitWeight, _parentPlayUnit.BlendMethod); //추가 //AnimEvent도 업데이트 하자 if (_animEvents != null && _animEvents.Count > 0) { apAnimEvent animEvent = null; for (int i = 0; i < _animEvents.Count; i++) { animEvent = _animEvents[i]; animEvent.Calculate(CurFrameFloat, CurFrame, (tDelta > 0.0f)); if (animEvent.IsEventCallable()) { if (_portrait._optAnimEventListener != null) { //애니메이션 이벤트를 호출해줍시다. _portrait._optAnimEventListener.SendMessage(animEvent._eventName, animEvent.GetCalculatedParam(), SendMessageOptions.DontRequireReceiver); //UnityEngine.Debug.Log("Animation Event : " + animEvent._eventName); } } } } //if (isEnd) //{ // //Animation 이벤트도 리셋한다. // if (_animEvents != null && _animEvents.Count > 0) // { // for (int i = 0; i < _animEvents.Count; i++) // { // _animEvents[i].ResetCallFlag(); // } // } //} return(isEnd); }
// 변경 1.17 : 메카님은 다르게 처리해야한다. public bool UpdateMecanim_Opt(float tDelta, float stateSpeed) { _tUpdate += tDelta; _tUpdateTotal += tDelta; bool isEnd = false; if (tDelta > 0) { //Speed Ratio가 크면 프레임이 한번에 여러개 이동할 수 있다. while (_tUpdate > TimePerFrame) { //프레임이 증가한다. _curFrame++; _tUpdate -= TimePerFrame; if (_curFrame >= _endFrame) { if (_isLoop) { //루프일 경우 -> 첫 프레임으로 돌아간다. _curFrame = _startFrame; _tUpdateTotal -= TimeLength; if (stateSpeed > 0.0f) { //UnityEngine.Debug.LogWarning("Frame Over the Length (Forward)"); //만약 밖에서 이벤트 초기화가 안되었다면 여기서 하자 ResetEvents(); } } else { //루프가 아닐 경우 _curFrame = _endFrame; _tUpdate = 0.0f; _tUpdateTotal = TimeLength; isEnd = true; break; } } } } else if (tDelta < 0) { while (_tUpdate < 0.0f) { //프레임이 감소한다. _curFrame--; _tUpdate += TimePerFrame; if (_curFrame <= _startFrame) { if (_isLoop) { //루프일 경우 -> 마지막 프레임으로 돌아간다. _curFrame = _endFrame; _tUpdateTotal += TimeLength; if (stateSpeed < 0.0f) { //UnityEngine.Debug.LogWarning("Frame Over the Length (Backward)"); //만약 밖에서 이벤트 초기화가 안되었다면 여기서 하자 ResetEvents(); } } else { //루프가 아닐 경우 _curFrame = _startFrame; _tUpdate = 0.0f; _tUpdateTotal = 0.0f; isEnd = true; break; } } } } #if UNITY_EDITOR if (!Application.isPlaying) { if (_parentPlayUnit == null) { return(true); } } #endif float unitWeight = _parentPlayUnit.UnitWeight; UpdateControlParam(false, _parentPlayUnit._layer, unitWeight, _parentPlayUnit.BlendMethod); //추가 //AnimEvent도 업데이트 하자 if (_animEvents != null && _animEvents.Count > 0) { apAnimEvent animEvent = null; for (int i = 0; i < _animEvents.Count; i++) { animEvent = _animEvents[i]; //animEvent.Calculate(CurFrameFloat, CurFrame, (tDelta > 0.0f), Mathf.Abs(tDelta) > 0.0001f, tDelta, _speedRatio);//기존 animEvent.Calculate(CurFrameFloat, CurFrame, (stateSpeed > 0.0f), Mathf.Abs(tDelta) > 0.0001f, tDelta, stateSpeed); //메카님용 if (animEvent.IsEventCallable()) { if (_portrait._optAnimEventListener != null) { //애니메이션 이벤트를 호출해줍시다. //UnityEngine.Debug.Log("Animation Event : " + animEvent._eventName + " / CurFrameFloat : " + CurFrameFloat + " / tDelta : " + tDelta); _portrait._optAnimEventListener.SendMessage(animEvent._eventName, animEvent.GetCalculatedParam(), SendMessageOptions.DontRequireReceiver); } } } } return(isEnd); }