private void PlayAnimation(AnimationRecord record) { var name = record.AinmName; var transitTime = (float)record.TransitTime; //记录下当前播放动画的名字 if (Animation.isPlaying) { if (Animation.IsPlaying(name)) { //直接播放 Animation.Stop(name); Animation.Play(name); } else { //淡出播放(有transitTime控制) Animation.CrossFade(name, transitTime, PlayMode.StopAll); } } else { Animation.Play(name); //不知道为啥,组件必须这么处理下,要不播放动作时会经常卡死 Animation.enabled = false; Animation.enabled = true; } //是否需要有动画结束通知 var processEnd = 2 != record.WrapMode || record.LoopTime > 0; if (processEnd) { mNeedProcessEndEvent = true; } else { mNeedProcessEndEvent = false; } if (mNeedProcessEndEvent) { //计算动画总时长 var state = Animation[name]; var totalLength = state.length / state.speed; if (WrapMode.Loop == state.wrapMode) { if (record.LoopTime > 0) { totalLength = totalLength * record.LoopTime; } } mCurrentAniEndTime = Time.time + Math.Abs(totalLength); } }
public AnimationViewer(PropsDataBase db, AnimationRecord AnimToFocus) : this() { AnimQueuedForFocus = AnimToFocus; foreach ((string fileName, int dirIndex) in db.FileList) { FileListExtended.Add((fileName, db.ContentDir[dirIndex])); } Animations.AddRange(db.Animations.Where(a => a.IsAmbPerf == false)); }
public void OnPostDraw() { if (m_SelectedAnimFrame.IsValid) { AnimationDebugRecord animStateRecord = Debugger.frameDebugger.FindAggregate <AnimationDebugRecord>(m_SelectedAnimFrame.providerIdentifier); if (animStateRecord == null) { m_SelectedAnimFrame = AnimationFrameIdentifier.CreateInvalid(); return; } Assert.IsTrue(m_SelectedAnimFrame.animIndex < animStateRecord.AnimationRecords.Count); if (m_SelectedAnimFrame.animIndex >= animStateRecord.AnimationRecords.Count) { m_SelectedAnimFrame = AnimationFrameIdentifier.CreateInvalid(); return; } AnimationRecord animRecord = animStateRecord.AnimationRecords[m_SelectedAnimFrame.animIndex]; Assert.IsTrue(m_SelectedAnimFrame.animFrameIndex < animRecord.animFrames.Count); if (m_SelectedAnimFrame.animFrameIndex >= animRecord.animFrames.Count) { m_SelectedAnimFrame = AnimationFrameIdentifier.CreateInvalid(); return; } AnimationFrameInfo animFrame = animRecord.animFrames[m_SelectedAnimFrame.animFrameIndex]; string label = $"{animRecord.animName}\nFrame:{animFrame.animFrame:0.00}\nWeight:{animFrame.weight:0.00}"; Vector2 labelSize = TimelineWidget.GetLabelSize(label); Rect toolTipRect = new Rect(Event.current.mousePosition.x + 20, Event.current.mousePosition.y, labelSize.x + 5.0f, labelSize.y + 5.0f); TimelineWidget.DrawRectangleWithDetour(toolTipRect, kTooltipBackgroundColor, kTooltipDetourColor); TimelineWidget.DrawLabel(toolTipRect, label, kTooltipTextColor); m_SelectedAnimFrame = AnimationFrameIdentifier.CreateInvalid(); } }
private AnimationRecord[] ReadChunkANDT(Stream stream, Chunk chunk, MphdRecord mphdRecord) { bool lsb = mphdRecord.LSB; // count structures backwards stream.Position = chunk.FilePosition + chunk.Length - AnimationRecord.SIZE; int animationCount = 0; while (ReadSignedByte(stream) != -1) { ++animationCount; stream.Position -= (AnimationRecord.SIZE + 1); } AnimationRecord[] animationRecords = new AnimationRecord[animationCount]; stream.Position = chunk.FilePosition + chunk.Length - AnimationRecord.SIZE; int animationIndex = 0; while (true) { long recordPosition = stream.Position; AnimationRecord animationRecord = new AnimationRecord(); animationRecord.Type = ReadSignedByte(stream); if (animationRecord.Type == -1) break; animationRecord.Delay = ReadSignedByte(stream); animationRecord.Counter = ReadSignedByte(stream); animationRecord.UserInfo = ReadSignedByte(stream); animationRecord.CurrentOffset = ReadSignedLong(stream, lsb); animationRecord.StartOffset = ReadSignedLong(stream, lsb); animationRecord.EndOffset = ReadSignedLong(stream, lsb); // offsets are negative offsets into a list of frame indices (32bit) at the beginning of the chunk int frameCount = (int)((animationRecord.EndOffset - animationRecord.StartOffset) / 4); // move (backwards) to frame indices at beginning of chunk animationRecord.Frames = new int[frameCount]; //stream.Position += animationRecord.StartOffset; stream.Position = chunk.FilePosition + chunk.Length + animationRecord.StartOffset; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { animationRecord.Frames[frameIndex] = (int)ReadSignedLong(stream, lsb); if (mphdRecord.VersionHigh < 1) animationRecord.Frames[frameIndex] /= mphdRecord.BlockStructSize; } animationRecords[animationIndex++] = animationRecord; stream.Position = recordPosition - AnimationRecord.SIZE; } stream.Position = chunk.FilePosition + chunk.Length; return animationRecords; }
/// <summary> /// Get animations for current spellcast. /// This happens the first time a spell is cast and stored for re-casting. /// It's likely player will use a wide variety of spell types in normal play. /// </summary> void SetCurrentAnims(ElementTypes elementType, int border = 0, bool dilate = false) { // Attempt to get current anims if (castAnims.ContainsKey(elementType)) { currentAnimType = elementType; currentAnims = castAnims[elementType]; return; } // Load spellcast file string filename = WeaponBasics.GetMagicAnimFilename(elementType); string path = Path.Combine(DaggerfallUnity.Instance.Arena2Path, filename); CifRciFile cifFile = new CifRciFile(); if (!cifFile.Load(path, FileUsage.UseMemory, true)) { throw new Exception(string.Format("Could not load spell anims file {0}", path)); } // Load CIF palette cifFile.Palette.Load(Path.Combine(DaggerfallUnity.Instance.Arena2Path, cifFile.PaletteName)); // Load textures - spells have a single frame per record unlike weapons AnimationRecord[] animationRecords = new AnimationRecord[cifFile.RecordCount]; for (int record = 0; record < cifFile.RecordCount; record++) { Texture2D texture; if (!TextureReplacement.TryImportCifRci(filename, record, 0, false, out texture)) { // Get Color32 array DFSize sz; Color32[] colors = cifFile.GetColor32(record, 0, 0, border, out sz); // Dilate edges if (border > 0 && dilate) { ImageProcessing.DilateColors(ref colors, sz); } // Create Texture2D texture = new Texture2D(sz.Width, sz.Height, TextureFormat.ARGB32, false); texture.SetPixels32(colors); texture.Apply(true); } // Set filter mode and store in frames array if (texture) { texture.filterMode = (FilterMode)DaggerfallUnity.Settings.MainFilterMode; animationRecords[record].Texture = texture; animationRecords[record].Size = cifFile.GetSize(record); } } // Add frames array to dictionary castAnims.Add(elementType, animationRecords); // Use as current anims currentAnimType = elementType; currentAnims = animationRecords; }
//播放动画 public bool Play(int animationId, Action <string> callback = null) { //读表 var tableData = Table.GetAnimation(animationId); if (null == tableData) { Logger.Error("TableError:DataTable.Table.GetAnimation({0})", animationId); OnAnimationEnd("no animation"); return(false); } // 数据都是对的了,现在模型还没有加载完成,播不了动画,就不播了 if (!Animation) { return(false); } //动作名字 var aniName = tableData.AinmName; //动作资源目录,到后面就判断这个是否为空,是空就不需要加载新的,否则需要加载 var animFile = string.Empty; if (null == Animation[aniName] || null == Animation.GetClip(aniName)) { //如果没有加载过这个动作 animFile = CalculateResPath(aniName); } else { StringBoolStruct sb; if (mDictAniCache.TryGetValue(aniName, out sb)) { if (sb.Flag) { animFile = CalculateResPath(aniName); if (0 == animFile.CompareTo(sb.Str)) { animFile = string.Empty; sb.Flag = false; } } } else { animFile = CalculateResPath(aniName); } } //判断当前是否正在播放这个动作 if (string.IsNullOrEmpty(animFile) && Animation.IsPlaying(aniName) && mCurrentAnimationName == aniName) { if ((WrapMode)tableData.WrapMode == WrapMode.Loop) { return(false); } } OnAnimationInterrupt(mCurrentAnimationName); mTableData = tableData; mCurrentAnimationName = aniName; mCurrentAnimationId = animationId; mPlayEndCallBack = callback; //设置下一个动作id mNextAnimationId = tableData.NextAnimId; OnAnimationBegin(mCurrentAnimationName); //不需要加载新的 if (string.IsNullOrEmpty(animFile)) { var state = Animation[mCurrentAnimationName]; if (null != state) { PlayAnimation(tableData); return(true); } } var loadingAnimationName = mCurrentAnimationName; //加载新动作 ResourceManager.PrepareResource <AnimationClip>(animFile, clip => { if (null == clip) { Logger.Fatal("Load animation[{0}] failded!", animFile); return; } // animation has changed already if (mCurrentAnimationId != animationId) { // 如果当前的动作类型还没有换,虽然动作本身换了,加载好的动作还是要加进去 StringBoolStruct sb; if (mDictAniCache.TryGetValue(loadingAnimationName, out sb)) { if (sb.Flag && sb.Str == animFile) { Animation.AddClip(clip, aniName); sb.Flag = false; } } return; } if (Animation == null) { return; } mDictAniCache[mCurrentAnimationName] = new StringBoolStruct(animFile, false); Animation.AddClip(clip, aniName); Animation.clip = clip; var state = Animation[aniName]; state.speed = (float)tableData.SPEED; if (tableData.WrapMode == 0) { state.wrapMode = WrapMode.Default; //默认是once } else if (tableData.WrapMode == 1) { //state.wrapMode = WrapMode.Once;//动画播放完就停止播放状态 state.wrapMode = WrapMode.ClampForever; //动画播完最后一帧就一直播放最后一帧 } else if (tableData.WrapMode == 2) { state.wrapMode = WrapMode.Loop; //循环模式,动画播完就从头播放 } else if (tableData.WrapMode == 3) { state.wrapMode = WrapMode.PingPong; //循环模式,动画播完就从尾巴往回播放 } else if (tableData.WrapMode == 4) { state.wrapMode = WrapMode.ClampForever; //动画播完最后一帧就一直播放最后一帧 } OptList <Renderer> .List.Clear(); gameObject.GetComponentsInChildren(OptList <Renderer> .List); { var __array2 = OptList <Renderer> .List; var __arrayLength2 = __array2.Count; for (var __i2 = 0; __i2 < __arrayLength2; ++__i2) { var renderer = __array2[__i2]; { renderer.enabled = true; } } } PlayAnimation(tableData); }, true, true, mSyncLoadResource, mFirstPriority, true); return(true); }
public bool PlayWithoutLoad(int animationId, Action <string> callback = null) { return(Play(animationId, callback)); //读表 var tableData = Table.GetAnimation(animationId); if (null == tableData) { Logger.Error("TableError:DataTable.Table.GetAnimation({0})", animationId); OnAnimationEnd("no animation"); return(false); } var aniName = tableData.AinmName; if (!Animation) { return(false); } if (null == Animation[tableData.AinmName]) { //如果使用的是主角的动作,在尝试加载播放 Play(animationId, callback); return(false); } if (Animation.IsPlaying(tableData.AinmName) && mCurrentAnimationName == aniName) { if ((WrapMode)tableData.WrapMode == WrapMode.Loop) { return(false); } } bWithout = true; OnAnimationInterrupt(mCurrentAnimationName); mTableData = tableData; mCurrentAnimationName = aniName; mCurrentAnimationId = animationId; mPlayEndCallBack = callback; //设置下一个动作id mNextAnimationId = tableData.NextAnimId; OnAnimationBegin(mCurrentAnimationName); var state = Animation[aniName]; if (tableData.WrapMode == 0 && state.wrapMode != WrapMode.Default) { state.wrapMode = WrapMode.Default; //默认是once } else if (tableData.WrapMode == 1 && state.wrapMode != WrapMode.ClampForever) { //state.wrapMode = WrapMode.Once;//动画播放完就停止播放状态 state.wrapMode = WrapMode.ClampForever; //动画播完最后一帧就一直播放最后一帧 } else if (tableData.WrapMode == 2 && state.wrapMode != WrapMode.Loop) { state.wrapMode = WrapMode.Loop; //循环模式,动画播完就从头播放 } else if (tableData.WrapMode == 3 && state.wrapMode != WrapMode.PingPong) { state.wrapMode = WrapMode.PingPong; //循环模式,动画播完就从尾巴往回播放 } else if (tableData.WrapMode == 4 && state.wrapMode != WrapMode.ClampForever) { state.wrapMode = WrapMode.ClampForever; //动画播完最后一帧就一直播放最后一帧 } PlayAnimation(tableData); return(true); }
private void DrawAnimationWidget(FrameDebugProviderInfo providerInfo, AnimationDebugRecord animStateRecord, int animIndex, TimelineWidget.DrawInfo drawInfo) { AnimationRecord animation = animStateRecord.AnimationRecords[animIndex]; if (animation.endTime < drawInfo.timeline.startTime) { return; } if (animation.startTime > drawInfo.timeline.endTime) { return; } float startPosition = drawInfo.GetPixelPosition(animation.startTime); float endPosition = drawInfo.GetPixelPosition(animation.endTime); Rect drawRect = drawInfo.timeline.drawRect; drawRect.y += animation.rank * kAnimWidgetOffset; Rect animRect = new Rect(startPosition, drawRect.y, endPosition - startPosition, kAnimWidgetHeight); TimelineWidget.DrawRectangleWithDetour(animRect, kAnimWidgetBackgroundColor, kAnimWidgetDetourColor); int barStartPosition = Missing.truncToInt(startPosition) + 1; int maxBarPosition = Missing.truncToInt(endPosition); for (int i = 0; i < animation.animFrames.Count; ++i) { int barEndPosition = Missing.truncToInt(drawInfo.GetPixelPosition(animation.animFrames[i].endTime)); if (barEndPosition > barStartPosition) { float weight = animation.animFrames[i].weight; if (weight < 1.0f) { Rect barRect = new Rect(barStartPosition, drawRect.y, barEndPosition - barStartPosition, (1.0f - weight) * kAnimWidgetHeight); TimelineWidget.DrawRectangle(barRect, kAnimWidgetWeightColor); } } barStartPosition = barEndPosition; } TimelineWidget.DrawLabelInsideRectangle(animRect, animation.animName, kAnimWidgetTextColor); // check if mouse is hovering the anim widget if (endPosition > startPosition && animRect.Contains(Event.current.mousePosition)) { float mouseNormalizedTime = (Event.current.mousePosition.x - startPosition) / (endPosition - startPosition); float mouseTime = animation.startTime + mouseNormalizedTime * (animation.endTime - animation.startTime); float curStartTime = animation.startTime; for (int i = 0; i < animation.animFrames.Count; ++i) { float curEndTime = animation.animFrames[i].endTime; if (curStartTime <= mouseTime && mouseTime <= curEndTime) { m_SelectedAnimFrame.providerIdentifier = providerInfo.uniqueIdentifier; m_SelectedAnimFrame.animIndex = animIndex; m_SelectedAnimFrame.animFrameIndex = i; m_SelectedAnimFrame.mouseX = Missing.truncToInt(Event.current.mousePosition.x); return; } curStartTime = curEndTime; } } }
private void GameController_RecieveME3Message(string msg) { if (msg == "AnimViewer string Loaded") { if (GameController.TryGetMEProcess(MEGame.ME3, out Process me3Process)) { me3Process.MainWindowHandle.RestoreAndBringToFront(); } this.RestoreAndBringToFront(); ME3OpenTimer.Start(); ME3StartingUp = false; LoadingAnimation = false; ReadyToView = true; animTab.IsSelected = true; noUpdate = true; ShouldFollowActor = false; SelectedSquadMember = ESquadMember.Liara; noUpdate = false; EndBusy(); if (AnimQueuedForFocus != null) { SelectedAnimation = Animations.FirstOrDefault(a => a.AnimSequence == AnimQueuedForFocus.AnimSequence); AnimQueuedForFocus = null; } } else if (msg.StartsWith("AnimViewer string AnimLoaded")) { Vector3 pos = defaultPosition; if (msg.IndexOf("vector") is int idx && idx > 0 && msg.Substring(idx + 7).Split(' ') is string[] strings && strings.Length == 3) { var floats = new float[3]; for (int i = 0; i < 3; i++) { if (float.TryParse(strings[i], out float f)) { floats[i] = f; } else { floats = defaultPosition.ToArray(); break; } } pos = new Vector3(floats); } noUpdate = true; XPos = (int)pos.X; YPos = (int)pos.Y; ZPos = (int)pos.Z; Yaw = 180; Pitch = 0; playbackState = PlaybackState.Playing; PlayPauseIcon = EFontAwesomeIcon.Solid_Pause; noUpdate = false; if (GameController.TryGetMEProcess(MEGame.ME3, out Process me3Process)) { me3Process.MainWindowHandle.RestoreAndBringToFront(); } this.RestoreAndBringToFront(); LoadingAnimation = false; EndBusy(); } else if (msg == "AnimViewer string HenchLoaded") { LoadAnimation(SelectedAnimation); } }