/// <summary> /// 对外的播放接口 /// </summary> /// <param name="clipName">动画名</param> /// <param name="subclipName">子动画名</param> /// <param name="cross">动画融合时间,0,代表不融合</param> public void Play(string clipName, string subclipName = null, float cross = 0.2f) { if (string.IsNullOrEmpty(clipName) == false) { // var _clip = GetClip(clipName); if (_clip == null) { Debug.LogError("No clip:" + clipName); return; } SubClip _subclip = null; if (string.IsNullOrEmpty(subclipName) == false) { _subclip = _clip.GetSubClip(subclipName); } //这里不直接调用了,改先缓存起来,等update中调用 并设置状态 nextPlayAniClip = _clip; nextPlaySubAniClip = _subclip; nextPlayCrosstimer = cross; } }
public void Play(AniClip clip, SubClip clipsub = null, float crosstimer = 0) { if (clipsub != null) { bLooped = clipsub.loop; startframe = (int)clipsub.startframe; endframe = (int)clipsub.endframe; if (_fps < 0) { _fps = clip.fps; } } else if (clip != null) { bLooped = clip.loop; startframe = 0; endframe = (clip.aniFrameCount - 1); if (_fps < 0) { _fps = clip.fps; } } if (crosstimer <= 0) { this._crossTimer = -1; crossFrame = null; lastClip = clip; lastframe = startframe; SetPose(clip, startframe, true); frameNow = lastClip.frames[lastframe]; } else { if (lastClip != null && lastframe >= 0 && lastframe < lastClip.frames.Count) { RecCrossFrame(); lastClip = clip; lastframe = startframe; } else { lastClip = clip; lastframe = startframe; SetPose(clip, startframe, true); frameNow = lastClip.frames[lastframe]; } this._crossTimerTotal = this._crossTimer = crosstimer; } }
public void Play(string clip, string subclip = null, float cross = 0.2f) { if (string.IsNullOrEmpty(clip) == false) { var _clip = GetClip(clip); if (_clip == null) { Debug.LogWarning("No clip:" + clip); return; } SubClip _subclip = null; if (string.IsNullOrEmpty(subclip) == false) { _subclip = _clip.GetSubClip(subclip); } //清除特效 if (!string.IsNullOrEmpty(curClipName)) { if (curClipName.Equals(clip)) { foreach (var i in livetimelist) { i.lifetime = 1000; } } else { for (int i = 0; i < livetimelist.Count - 1; i++) { AniResource.CloseEffectLooped(livetimelist[i].effid); livetimelist.RemoveAt(i); } AniResource.CleanAllEffect(); curClipName = clip; } } //Debug.LogError("_clip = " + _clip); Play(clip: _clip, clipsub: _subclip, crosstimer: cross); } }
public void Play(string clip, string subclip, float cross) { if (string.IsNullOrEmpty(clip) == false) { var _clip = GetClip(clip); if (_clip == null) { Debug.LogWarning("No clip:" + clip); return; } SubClip _subclip = null; if (string.IsNullOrEmpty(subclip) == false) { _subclip = _clip.GetSubClip(subclip); } //Debug.LogError("_clip = " + _clip); Play(_clip, _subclip, cross); } }
public static FB.PosePlus.AniClip ReadAniClip(System.IO.Stream s) { var buf4 = new byte[4]; var clip = new FB.PosePlus.AniClip(); //name int slen = s.ReadByte(); byte[] buf = new byte[slen]; s.Read(buf, 0, slen); clip.name = System.Text.Encoding.UTF8.GetString(buf); //fps s.Read(buf4, 0, 4); clip.fps = BitConverter.ToSingle(buf4, 0); //loop clip.loop = s.ReadByte() > 0; { //boneinfo s.Read(buf4, 0, 4); int bcount = BitConverter.ToInt32(buf4, 0); for (int i = 0; i < bcount; i++) { slen = s.ReadByte(); buf = new byte[slen]; s.Read(buf, 0, slen); string bone = System.Text.Encoding.UTF8.GetString(buf); clip.boneinfo.Add(bone); } } { //subclips s.Read(buf4, 0, 4); int scount = BitConverter.ToInt32(buf4, 0); for (int i = 0; i < scount; i++) { FB.PosePlus.SubClip sc = new FB.PosePlus.SubClip(); slen = s.ReadByte(); buf = new byte[slen]; s.Read(buf, 0, slen); sc.name = System.Text.Encoding.UTF8.GetString(buf); sc.loop = s.ReadByte() > 0; s.Read(buf4, 0, 4); sc.startframe = BitConverter.ToUInt32(buf4, 0); s.Read(buf4, 0, 4); sc.endframe = BitConverter.ToUInt32(buf4, 0); clip.subclips.Add(sc); } } {//frame s.Read(buf4, 0, 4); int fcount = BitConverter.ToInt32(buf4, 0); for (int i = 0; i < fcount; i++) { FB.PosePlus.Frame f = new FB.PosePlus.Frame(); s.Read(buf4, 0, 4); f.fid = BitConverter.ToInt32(buf4, 0); f.key = s.ReadByte() > 0; clip.frames.Add(f); for (int ib = 0; ib < clip.boneinfo.Count; ib++) { clip.frames[i].bonesinfo.Add(new FB.PosePlus.PoseBoneMatrix()); clip.frames[i].bonesinfo[ib].Load(s, i > 0 ? clip.frames[i - 1].bonesinfo[ib] : null); } } } return(clip); }
public static FB.PosePlus.AniClip ReadAniClip(System.IO.Stream s) { var buf4 = new byte[4]; var clip = new FB.PosePlus.AniClip(); //name int slen = s.ReadByte(); byte[] buf = new byte[slen]; s.Read(buf, 0, slen); clip.name = System.Text.Encoding.UTF8.GetString(buf); //fps s.Read(buf4, 0, 4); clip.fps = BitConverter.ToSingle(buf4, 0); //loop clip.loop = s.ReadByte() > 0; { //boneinfo s.Read(buf4, 0, 4); int bcount = BitConverter.ToInt32(buf4, 0); for (int i = 0; i < bcount; i++) { slen = s.ReadByte(); buf = new byte[slen]; s.Read(buf, 0, slen); string bone = System.Text.Encoding.UTF8.GetString(buf); clip.boneinfo.Add(bone); } } { //subclips s.Read(buf4, 0, 4); int scount = BitConverter.ToInt32(buf4, 0); for (int i = 0; i < scount; i++) { FB.PosePlus.SubClip sc = new FB.PosePlus.SubClip(); slen = s.ReadByte(); buf = new byte[slen]; s.Read(buf, 0, slen); sc.name = System.Text.Encoding.UTF8.GetString(buf); sc.loop = s.ReadByte() > 0; s.Read(buf4, 0, 4); sc.startframe = BitConverter.ToUInt32(buf4,0); s.Read(buf4, 0, 4); sc.endframe = BitConverter.ToUInt32(buf4,0); clip.subclips.Add(sc); } } {//frame s.Read(buf4, 0, 4); int fcount = BitConverter.ToInt32(buf4, 0); for (int i = 0; i < fcount; i++) { FB.PosePlus.Frame f = new FB.PosePlus.Frame(); s.Read(buf4, 0, 4); f.fid = BitConverter.ToInt32(buf4, 0); f.key = s.ReadByte() > 0; clip.frames.Add(f); for (int ib = 0; ib < clip.boneinfo.Count; ib++) { clip.frames[i].bonesinfo.Add(new FB.PosePlus.PoseBoneMatrix()); clip.frames[i].bonesinfo[ib].Load(s, i > 0 ? clip.frames[i - 1].bonesinfo[ib] : null); } } } return clip; }
readonly float fps = 30; //fps /// <summary> /// update /// </summary> /// <param name="delta"></param> public void _OnUpdate(float delta) { if (isPauseAnimation) { return; } //这里需要注意,Play接口操作的都共用的底层状态, //为了防止Update执行一半状态变了 //所以在update开始进行状态比对, //如果需要播放新动画,则设置好状态 if (nextPlayAniClip != null) { //播放 Play(nextPlayAniClip, nextPlaySubAniClip, nextPlayCrosstimer); nextPlayAniClip = null; nextPlaySubAniClip = null; return; } //下面都是推帧逻辑 if (lastClip == null) { return; } timer += delta; //判断是否在动画切换之间的过渡 if (_crossTimer >= 0) { _crossTimer -= delta; if (_crossTimer <= 0) { //过渡结束 timer 归零 timer = 0; crossFrame = null; } } //这里要用一个稳定的fps,就用播放的第一个动画的fps作为稳定fps int _frameCount = (int)(timer * fps); // if (_frameCount == frameCounter) { return; } //增加一个限制,不准动画跳帧 if (_frameCount > frameCounter + 1) { _frameCount = frameCounter + 1; timer = _frameCount / fps; } frameCounter = _frameCount; //1.不需要过渡,直接播放动画 if (_crossTimer <= 0) { //只有播放动作才推帧 int frame = lastframe + 1; if (frame > endframe) { if (bLooped) { frame = startframe; } else { frame = endframe; // //播放默认动画 if (!string.IsNullOrEmpty(this.defaultAnimationName)) { this.Play(defaultAnimationName); } } } int frameCache = lastframe; //设置动画 SetPose(lastClip, frame, true); lastframe = frame; //判断动画是否正好结束 if (frameCache < endframe && frame == endframe) { if (CurClip != null) { this.TriggerAnimationState(CurClip.name, AnimationState.OnPlayEnd); } } } //2.计算过渡插帧 播放 else if (_crossTimer > 0) { if (crossFrame != null) { //两帧之间的距离进度 float l = 1.0f - _crossTimer / _crossTimerTotal; SetPoseLerp(crossFrame, lastClip.frames[startframe], l); } } //触发帧驱动 TriggerAnimationState(CurClip.name, AnimationState.OnUpdate); }
/// <summary> /// 播放一个动画片段 /// </summary> /// <param name="clip"></param> /// <param name="subClip"></param> /// <param name="crosstimer"></param> private void Play(AniClip clip, SubClip subClip = null, float crosstimer = 0) { //清除特效 { for (int i = 0; i < effectLifeList.Count; i++) { ResourceLoader.CloseEffectLooped(effectLifeList[i].effid); } effectLifeList.Clear(); ResourceLoader.CleanAllEffect(); } //开始播放 if (subClip != null) //优先播放子动画 { bLooped = subClip.loop; startframe = (int)subClip.startframe; endframe = (int)subClip.endframe; } else if (clip != null) //子动画不存在.则播放父动画 { bLooped = clip.loop; startframe = 0; endframe = (clip.aniFrameCount - 1); } //切换动作 不需要过渡 if (crosstimer <= 0) { this._crossTimer = -1; crossFrame = null; lastClip = clip; lastframe = startframe; SetPose(clip, startframe, true); //修复设置后立马推帧问题 timer = 0f; } //切换动作需要过渡 else { //当前动作没做完 if (lastClip != null && lastframe >= 0 && lastframe < lastClip.frames.Count) { RecCrossFrame(); lastClip = clip; lastframe = startframe; //修复设置后立马推帧问题 timer = 0f; this._crossTimerTotal = this._crossTimer = crosstimer; } //当前动作做完了 else { lastClip = clip; lastframe = startframe; SetPose(clip, startframe, true); //修复设置后立马推帧问题 timer = 0f; } } }