/// <summary> /// Updates the associated clip information and the event durations. /// </summary> /// <returns>Returns true if the Wwise event is found in the project data.</returns> private static bool UpdateClipInformation(UnityEngine.Timeline.TimelineClip clip, AK.Wwise.Event akEvent, UnityEditor.SerializedObject serializedObject, bool setClipDuration) { var clipDuration = MinimumDurationInSeconds; var eventInfo = AkWwiseProjectInfo.GetData().GetEventInfo(akEvent.Id); if (eventInfo != null) { serializedObject.FindProperty("eventDurationMin").floatValue = eventInfo.minDuration; serializedObject.FindProperty("eventDurationMax").floatValue = eventInfo.maxDuration; if (eventInfo.maxDuration > clipDuration) { clipDuration = eventInfo.maxDuration; } } if (clip != null) { clip.displayName = akEvent.Name; if (setClipDuration) { clip.duration = clipDuration; } } return(eventInfo != null && eventInfo.maxDuration > 0); }
/// <summary> /// Updates the associated clip information and the event durations. /// </summary> /// <returns>Returns true if the Wwise event is found in the project data.</returns> private static bool UpdateClipInformation(UnityEngine.Timeline.TimelineClip clip, AK.Wwise.Event akEvent, UnityEditor.SerializedObject serializedObject, bool setClipDuration) { var clipDuration = MinimumDurationInSeconds; var maxDuration = -1.0f; var minDuration = -1.0f; AkUtilities.GetEventDurations(akEvent.Id, ref maxDuration, ref minDuration); if (maxDuration != -1.0f) { serializedObject.FindProperty("eventDurationMin").floatValue = minDuration; serializedObject.FindProperty("eventDurationMax").floatValue = maxDuration; if (maxDuration > clipDuration) { clipDuration = maxDuration; } } if (clip != null) { clip.displayName = akEvent.Name; if (setClipDuration) { clip.duration = clipDuration; } } return(maxDuration != -1.0f); }
// 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; } }