public static void UpdateCdpath(Animation ani, EditorCurveBinding[] curveDatas, FB.PosePlus.AniClip _clip, FB.PosePlus.AniPlayer con, List <Transform> cdpath) { foreach (var dd in curveDatas) { Transform tran = ani.transform.Find(dd.path); if (tran == null) { Debug.LogWarning("trans not found:" + dd.path); //丢弃无法被找到的动画通道 } else { if (cdpath.Contains(tran) == false) { _clip.boneinfo.Add(tran.name); cdpath.Add(tran); } } } foreach (var b in con.bones) { //if (b.bone.GetComponent<asbone>() != null) { //特别关注的骨骼 if (_clip.boneinfo.Contains(b.bone.name) == false) { _clip.boneinfo.Add(b.bone.name); cdpath.Add(b.bone); } } } Debug.LogWarning("curve got path =" + cdpath.Count); }
public static void WriteAniClip(FB.PosePlus.AniClip clip, System.IO.Stream ms) { //name var nameb = System.Text.Encoding.UTF8.GetBytes(clip.name); ms.WriteByte((byte)nameb.Length); ms.Write(nameb, 0, nameb.Length); //fps byte[] fpsb = BitConverter.GetBytes(clip.fps); ms.Write(fpsb, 0, 4); //loop ms.WriteByte((byte)(clip.loop ? 1 : 0)); { //boneinfo int c = clip.boneinfo.Count; byte[] cliplenb = BitConverter.GetBytes(c); ms.Write(cliplenb, 0, 4); for (int i = 0; i < c; i++) { byte[] bnameb = System.Text.Encoding.UTF8.GetBytes(clip.boneinfo[i]); ms.WriteByte((byte)bnameb.Length); ms.Write(bnameb, 0, bnameb.Length); } } { //subclips int c = clip.subclips.Count; byte[] cliplenb = BitConverter.GetBytes(c); ms.Write(cliplenb, 0, 4); for (int i = 0; i < c; i++) { byte[] bnameb = System.Text.Encoding.UTF8.GetBytes(clip.subclips[i].name); ms.WriteByte((byte)bnameb.Length); ms.Write(bnameb, 0, bnameb.Length); ms.WriteByte((byte)(clip.subclips[i].loop ? 1 : 0)); byte[] sb = BitConverter.GetBytes(clip.subclips[i].startframe); byte[] eb = BitConverter.GetBytes(clip.subclips[i].endframe); } } {//frame int c = clip.frames.Count; byte[] cliplenb = BitConverter.GetBytes(c); ms.Write(cliplenb, 0, 4); for (int i = 0; i < c; i++) { byte[] fidb = BitConverter.GetBytes(clip.frames[i].fid); ms.Write(fidb, 0, 4); ms.WriteByte((byte)(clip.frames[i].key ? 1 : 0)); for (int ib = 0; ib < clip.boneinfo.Count; ib++) { clip.frames[i].bonesinfo[ib].Save(ms, i > 0 ? clip.frames[i - 1].bonesinfo[ib] : null); } } } }
int calcbonehash(FB.PosePlus.AniClip clip) { string b = ""; foreach (var bi in clip.boneinfo) { b += bi + "|"; } return(b.GetHashCode()); }
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; } }
void FillAniBoneInfo(Transform root, FB.PosePlus.AniPlayer controller, FB.PosePlus.AniClip ani) { string path = getPath(root, controller.transform); if (ani.boneinfo == null) { ani.boneinfo = new List <string>(); } ani.boneinfo.Add(path); foreach (Transform t in root) { FillAniBoneInfo(t, controller, ani); } }
//int transcode = -1; //Transform[] trans = null; public void SetPose(AniClip clip, int frame, bool reset = false) { _checkBone(); //if (clip.bonehash != transcode) //{ // trans = new Transform[clip.boneinfo.Count]; // for (int i = 0; i < clip.boneinfo.Count; i++) // { // trans[i] = this.transform.Find(clip.boneinfo[i]); // } // transcode = clip.bonehash; //} bool badd = false; if (lastClip == clip && !reset) { if (lastframe + 1 == frame) { badd = transform; } if (clip.loop && lastframe == clip.frames.Count - 1 && frame == 0) { badd = true; } } for (int i = 0; i < clip.boneinfo.Count; i++) { var bn = clip.boneinfo[i]; if (this.bonecache.ContainsKey(bn) == false) { //if (bn == "CameraPoint") //{ // AddBone(bn); //} //else { continue; } } clip.frames[frame].bonesinfo[i].UpdateTran(bones[bonecache[bn]].bone, bones[bonecache[bn]].tpose, this.transform, badd); } lastClip = clip; lastframe = frame; }
public bool MatchBone(AniClip clip) { Dictionary <int, int> boneconvert = new Dictionary <int, int>(); for (int i = 0; i < clip.boneinfo.Count; i++) { bool bhave = false; for (int j = 0; j < this.boneinfo.Count; j++) { if (this.boneinfo[j] == clip.boneinfo[i]) { boneconvert[j] = i; bhave = true; } } if (bhave == false) { //需要增加骨骼了,呵呵了 Debug.LogError("bone need add:" + clip.boneinfo[i]); Debug.LogWarning("目前不能处理这种情况,将另一个动画放在前面试试"); return(false); } //if donthave } for (int i = 0; i < this.boneinfo.Count; i++) { if (boneconvert.ContainsKey(i) == false) { Debug.LogWarning("bone need delete:" + this.boneinfo[i]); } } this.boneinfo = new List <string>(clip.boneinfo); foreach (var f in frames) { List <PoseBoneMatrix> list = new List <PoseBoneMatrix>(); for (int i = 0; i < this.boneinfo.Count; i++) { list.Add(null); } foreach (var c in boneconvert) { list[c.Value] = f.bonesinfo[c.Key]; } f.bonesinfo = list; } return(true); }
public AniClip GetAniClip(string name) { FB.PosePlus.AniClip clip = null; if (loadaniclipcache.TryGetValue(name, out clip)) { return(clip); } byte[] buf = bufs[name]; using (System.IO.MemoryStream ms = new System.IO.MemoryStream(buf)) { clip = BitHelper.ReadAniClip(ms); } return(clip); }
public void SetPose(AniClip clip, int frame, bool reset = false, Transform parent = null) { if (clip.bonehash != transcode) { trans = new Transform[clip.boneinfo.Count]; for (int i = 0; i < clip.boneinfo.Count; i++) { trans[i] = this.transform.Find(clip.boneinfo[i]); } transcode = clip.bonehash; } bool badd = false; if (lastClip == clip && !reset) { if (lastframe + 1 == frame) { badd = transform; } if (clip.loop && lastframe == clip.frames.Count - 1 && frame == 0) { badd = true; } } for (int i = 0; i < trans.Length; i++) { if (trans[i] == null) { continue; } if (parent != null && parent != trans[i]) { if (trans[i].IsChildOf(parent) == false) { continue; } } clip.frames[frame].bonesinfo[i].UpdateTran(trans[i], badd); } lastClip = clip; lastframe = frame; }
public Frame(AniClip clip, AniPlayer player, Frame last, int _fid, Transform root, IList <Transform> trans) { //Debug.LogWarning("bones=" + trans.Length); this.fid = _fid; this.key = true; this.boneinfo = clip.boneinfo; //bonesinfo = new PoseBoneMatrix[trans.Count]; for (int i = 0; i < trans.Count; i++) { PoseBoneMatrix b = new PoseBoneMatrix(); bonesinfo.Add(b); string bone = this.boneinfo[i]; var tbone = player.getbone(bone); bonesinfo[i].Record(root, trans[i], tbone == null?Matrix4x4.identity:tbone.tpose, last == null ? null : last.bonesinfo[i]); } }
public void AddAni(AniClip clip) { if (clips == null) { clips = new List <AniClip>(); } if (clipcache == null) { clipcache = new Dictionary <string, int>(); } if (clipcache.ContainsKey(clip.name)) { clips[clipcache[clip.name]] = clip; } else { clips.Add(clip); clipcache[clip.name] = clips.Count - 1; } }
void CloneAni(AnimationClip clip, float fps) { var ani = target as Animator; //创建CleanData.Ani FB.PosePlus.AniClip _clip = ScriptableObject.CreateInstance <FB.PosePlus.AniClip>(); _clip.boneinfo = new List <string>();//也增加了每个动画中的boneinfo信息. //这里重新检查动画曲线,找出动画中涉及的Transform部分,更精确 List <Transform> cdpath = new List <Transform>(); var curveDatas = AnimationUtility.GetCurveBindings(clip); //AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(clip, true); foreach (var dd in curveDatas) { Transform tran = ani.transform.Find(dd.path); if (cdpath.Contains(tran) == false) { _clip.boneinfo.Add(dd.path); cdpath.Add(tran); } } Debug.LogWarning("curve got path =" + cdpath.Count); string path = System.IO.Path.GetDirectoryName(AssetDatabase.GetAssetPath(clip.GetInstanceID())); _clip.name = clip.name; _clip.frames = new List <FB.PosePlus.Frame>(); _clip.fps = fps; _clip.loop = clip.isLooping; float flen = (clip.length * fps); int framecount = (int)flen; if (flen - framecount > 0.0001) { framecount++; } //if (framecount < 1) framecount = 1; framecount += 1; FB.PosePlus.Frame last = null; //ani.StartPlayback(); //逐帧复制 //ani.Play(_clip.name, 0, 0); for (int i = 0; i < framecount; i++) { ani.Play(_clip.name, 0, (i * 1.0f / fps) / clip.length); ani.Update(0); last = new FB.PosePlus.Frame(last, i, cdpath); _clip.frames.Add(last); } if (_clip.loop) { _clip.frames[0].LinkLoop(last); } Debug.Log("FrameCount." + framecount); FB.PosePlus.AniPlayer con = ani.GetComponent <FB.PosePlus.AniPlayer>(); List <FB.PosePlus.AniClip> clips = null; if (con.clips != null) { clips = new List <FB.PosePlus.AniClip>(con.clips); } else { clips = new List <FB.PosePlus.AniClip>(); } foreach (var c in clips) { if (c.name == _clip.name + ".FBAni") { clips.Remove(c); break; } } //ani.StopPlayback(); string outpath = path + "/" + clip.name + ".FBAni.asset"; AssetDatabase.CreateAsset(_clip, outpath); var src = AssetDatabase.LoadAssetAtPath(outpath, typeof(FB.PosePlus.AniClip)) as FB.PosePlus.AniClip; //设置clip //FB.CleanData.AniController con = ani.GetComponent<FB.CleanData.AniController>(); clips.Add(src); con.clips = clips; }
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); }
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); }
/// <summary> /// 每一帧的设置动作 /// </summary> /// <param name="clip"></param> /// <param name="frame"></param> /// <param name="reset"></param> /// <param name="parent"></param> public void SetPose(AniClip clip, int frame, bool reset = false, Transform parent = null) { if (clip == null) { int i = 0; } //这里防止外部循环设置同一帧数据 if (clip.GetHashCode() == lastSetClipHash && frame == lastSetFrame) { return; } lastSetClipHash = clip.GetHashCode(); lastSetFrame = frame; if (clip.bonehash != transcode) { curBoneTrans = new Transform[clip.boneinfo.Count]; for (int i = 0; i < clip.boneinfo.Count; i++) { var name = clip.boneinfo[i]; Transform t = null; if (!transformCacheMap.TryGetValue(name, out t)) { t = this.transform.Find(name); transformCacheMap[name] = t; } curBoneTrans[i] = t; } transcode = clip.bonehash; } bool badd = false; if (lastClip == clip && !reset) { if (lastframe + 1 == frame) { badd = transform; } if (clip.loop && lastframe == clip.frames.Count - 1 && frame == 0) { badd = true; } } for (int i = 0; i < curBoneTrans.Length; i++) { if (curBoneTrans[i] == null) { continue; } if (parent != null && parent != curBoneTrans[i]) { if (curBoneTrans[i].IsChildOf(parent) == false) { continue; } } clip.frames[frame].bonesinfo[i].UpdateTran(curBoneTrans[i], badd); } if (clip.frames.Count > 0 && frame >= 0) { SetBoxColiderAttribute(clip.frames[frame]); //设置碰撞盒 if (isShowBoxLine) { SetDebugDot(clip.frames[frame]); //设置触发点 } if (isPlayRunTime) { SetEffect(clip.frames[frame]); //设置/检测特效 SetAudio(clip.frames[frame]); } } }
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; }
void SelfInit(FB.PosePlus.AniClip clipa, FB.PosePlus.AniClip clipb) { clip_a_cache = clip_a = clipa; clip_b_cache = clip_b = clipb; }
/// <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; } } }
public static void AddClip(AnimationClip clip, float fps, Animation ani) { FB.PosePlus.AniClip _clip = ScriptableObject.CreateInstance <FB.PosePlus.AniClip>(); _clip.boneinfo = new List <string>();//也增加了每个动画中的boneinfo信息. //这里重新检查动画曲线,找出动画中涉及的Transform部分,更精确 List <Transform> cdpath = new List <Transform>(); var curveDatas = AnimationUtility.GetCurveBindings(clip); FB.PosePlus.AniPlayer con = ani.GetComponent <FB.PosePlus.AniPlayer>(); UpdateCdpath(ani, curveDatas, _clip, con, cdpath); string path = System.IO.Path.GetDirectoryName(AssetDatabase.GetAssetPath(clip.GetInstanceID())); _clip.name = clip.name; _clip.frames = new List <FB.PosePlus.Frame>(); _clip.fps = fps; _clip.loop = clip.isLooping; float flen = (clip.length * fps); int framecount = (int)flen; if (flen - framecount > 0.0001) { framecount++; } for (int i = 0, l = clip.events.Length; i < l; i++) { var aniEvent = clip.events[i]; FrameEvent evt = new FrameEvent(); evt.name = aniEvent.functionName; evt.position = aniEvent.time; evt.intVariable = aniEvent.intParameter; evt.floatVariable = aniEvent.floatParameter; evt.stringVariable = aniEvent.stringParameter; _clip.events.Add(evt); } framecount += 1; FB.PosePlus.Frame last = null; for (int i = 0; i < framecount; i++) { ani[_clip.name].time = (i * 1.0f / fps) / clip.length; ani[_clip.name].enabled = true; ani[_clip.name].weight = 1; ani.Sample(); ani[_clip.name].enabled = false; last = new FB.PosePlus.Frame(_clip, con, last, i, ani.transform, cdpath); _clip.frames.Add(last); } Dictionary <string, int> clipcache = new Dictionary <string, int>(); if (con.clips != null) { for (int i = 0, l = con.clips.Count; i < l; i++) { if (con.clips[i]) { clipcache[con.clips[i].name] = i; Debug.Log(con.clips[i].name); } else { con.clips.RemoveAt(i); i--; l--; } } } con.clipcache = clipcache; string outpath = path + "/" + clip.name + ".FBAni.asset"; FB.PosePlus.AniClip src = null; /*if (Pretreatment.AnimatorCache.ContainsKey(outpath)) * { * src = Pretreatment.AnimatorCache[outpath]; * } * else * { * AssetDatabase.CreateAsset(_clip, outpath); * src = AssetDatabase.LoadAssetAtPath(outpath, typeof(FB.PosePlus.AniClip)) as FB.PosePlus.AniClip; * Pretreatment.AnimatorCache[outpath] = src; * }*/ AssetDatabase.CreateAsset(_clip, outpath); src = AssetDatabase.LoadAssetAtPath(outpath, typeof(FB.PosePlus.AniClip)) as FB.PosePlus.AniClip; Pretreatment.AnimatorCache[outpath] = src; con.AddAni(src); }
public void SetPose(AniClip clip, int frame, bool reset = false, Transform parent = null) { if (clip.bonehash != transcode) { trans = new Transform[clip.boneinfo.Count]; for (int i = 0; i < clip.boneinfo.Count; i++) { trans[i] = this.transform.Find(clip.boneinfo[i]); } transcode = clip.bonehash; } bool badd = false; if (lastClip == clip && !reset) { if (lastframe + 1 == frame) { badd = transform; } if (clip.loop && lastframe == clip.frames.Count - 1 && frame == 0) { badd = true; } } for (int i = 0; i < trans.Length; i++) { if (trans[i] == null) { continue; } if (parent != null && parent != trans[i]) { if (trans[i].IsChildOf(parent) == false) { continue; } } clip.frames[frame].bonesinfo[i].UpdateTran(trans[i], badd); } if (clip.frames.Count > 0 && frame >= 0) { SetBoxColiderAttribute(clip.frames[frame]); //设置碰撞盒 if (IsShowBoxLine) { SetDebugDot(clip.frames[frame]); //设置触发点 } if (bPlayRunTime) { SetEffect(clip.frames[frame]); //设置/检测特效 SetAudio(clip.frames[frame]); } } lastClip = clip; lastframe = frame; }
public void SetPose(AniClip clip, int frame, bool reset = false, Transform parent = null) { if (clip.bonehash != transcode) { trans = new Transform[clip.boneinfo.Count]; for (int i = 0; i < clip.boneinfo.Count; i++) { trans[i] = this.transform.Find(clip.boneinfo[i]); } transcode = clip.bonehash; } bool badd = false; if (lastClip == clip && !reset) { if (lastframe + 1 == frame) badd = transform; if (clip.loop && lastframe == clip.frames.Count - 1 && frame == 0) badd = true; } for (int i = 0; i < trans.Length; i++) { if (trans[i] == null) continue; if (parent != null && parent != trans[i]) { if (trans[i].IsChildOf(parent) == false) continue; } clip.frames[frame].bonesinfo[i].UpdateTran(trans[i], badd); } lastClip = clip; lastframe = frame; }
public bool MatchBone(AniClip clip) { Dictionary<int, int> boneconvert = new Dictionary<int, int>(); for (int i = 0; i < clip.boneinfo.Count; i++) { bool bhave = false; for (int j = 0; j < this.boneinfo.Count; j++) { if (this.boneinfo[j] == clip.boneinfo[i]) { boneconvert[j] = i; bhave = true; } } if (bhave == false) {//需要增加骨骼了,呵呵了 Debug.LogError("bone need add:" + clip.boneinfo[i]); Debug.LogWarning("目前不能处理这种情况,将另一个动画放在前面试试"); return false; } //if donthave } for (int i = 0; i < this.boneinfo.Count; i++) { if (boneconvert.ContainsKey(i) == false) { Debug.LogWarning("bone need delete:" + this.boneinfo[i]); } } this.boneinfo = new List<string>(clip.boneinfo); foreach (var f in frames) { List<PoseBoneMatrix> list = new List<PoseBoneMatrix>(); for (int i = 0; i < this.boneinfo.Count; i++) { list.Add(null); } foreach (var c in boneconvert) { list[c.Value] = f.bonesinfo[c.Key]; } f.bonesinfo = list; } return true; }
public static void Show(FB.PosePlus.AniClip clipa, FB.PosePlus.AniClip clipb) { var window = EditorWindow.GetWindow <Window_AniTools>(true, "Window_Tools", true); window.SelfInit(clipa, clipb); }
public string SaveAniClip(AniClip clip) { int id = clip.GetInstanceID(); string name = null; if (savecache.TryGetValue(id, out name)) { return name; } using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) { BitHelper.WriteAniClip(clip, ms); byte[] bs = ms.ToArray(); string sha1 = ResLibTool.ComputeHashString(bs); name = sha1 + ".aniclip.bin"; bufs[name] = bs; } return name; }
//从一个Animator中获取所有的Animation public static void CloneAni(UnityEngine.AnimationClip clip, float fps, Animator ani) { //创建CleanData.Ani FB.PosePlus.AniClip _clip = ScriptableObject.CreateInstance <FB.PosePlus.AniClip>(); _clip.boneinfo = new List <string>();//也增加了每个动画中的boneinfo信息. //这里重新检查动画曲线,找出动画中涉及的Transform部分,更精确 List <Transform> cdpath = new List <Transform>(); var curveDatas = AnimationUtility.GetCurveBindings(clip); //AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(clip, true); foreach (var dd in curveDatas) { Transform tran = ani.transform.Find(dd.path); if (tran == null) { Debug.LogWarning("trans not found:" + dd.path); //丢弃无法被找到的动画通道 } else { if (cdpath.Contains(tran) == false) { _clip.boneinfo.Add(tran.name); cdpath.Add(tran); } } } FB.PosePlus.AniPlayer con = ani.gameObject.GetComponent <FB.PosePlus.AniPlayer>(); foreach (var b in con.bones) { //if (b.bone.GetComponent<asbone>() != null) { //特别关注的骨骼 if (_clip.boneinfo.Contains(b.bone.name) == false) { _clip.boneinfo.Add(b.bone.name); cdpath.Add(b.bone); } } } Debug.LogWarning("curve got path =" + cdpath.Count); string path = System.IO.Path.GetDirectoryName(AssetDatabase.GetAssetPath(clip.GetInstanceID())); _clip.name = clip.name; _clip.frames = new List <FB.PosePlus.Frame>(); _clip.fps = fps; _clip.loop = clip.isLooping; float flen = (clip.length * fps); int framecount = (int)flen; if (flen - framecount > 0.0001) { framecount++; } //if (framecount < 1) framecount = 1; for (int i = 0, l = clip.events.Length; i < l; i++) { var aniEvent = clip.events[i]; FrameEvent evt = new FrameEvent(); evt.name = aniEvent.functionName; evt.position = aniEvent.time; evt.intVariable = aniEvent.intParameter; evt.floatVariable = aniEvent.floatParameter; evt.stringVariable = aniEvent.stringParameter; _clip.events.Add(evt); } framecount += 1; FB.PosePlus.Frame last = null; //ani.StartPlayback(); //逐帧复制 //ani.Play(_clip.name, 0, 0); for (int i = 0; i < framecount; i++) { ani.Play(mapClip2State[_clip.name], 0, (i * 1.0f / fps) / clip.length); ani.Update(0); last = new FB.PosePlus.Frame(_clip, con, last, i, ani.transform, cdpath); _clip.frames.Add(last); } //特殊处理:写文件后,clips中的内容会丢失 //这里用clipcache保存clips的内容 //Debug.Log(con.clips[0].name); Dictionary <string, int> clipcache = new Dictionary <string, int>(); if (con.clips != null) { for (int i = 0; i < con.clips.Count; i++) { if (con.clips[i]) { clipcache[con.clips[i].name] = i; } else { con.clips.RemoveAt(i); } } } con.clipcache = clipcache; string outpath = PathHelper.CheckFileName(path + "/" + ani.gameObject.name + "_" + clip.name + ".FBAni.asset"); /*FB.PosePlus.AniClip src = null; * if (Pretreatment.AnimatorCache.ContainsKey(outpath)) * { * src = Pretreatment.AnimatorCache[outpath]; * } * else * { * AssetDatabase.CreateAsset(_clip, outpath); * src = AssetDatabase.LoadAssetAtPath(outpath, typeof(FB.PosePlus.AniClip)) as FB.PosePlus.AniClip; * Pretreatment.AnimatorCache[outpath] = src; * }*/ AssetDatabase.CreateAsset(_clip, outpath); var src = AssetDatabase.LoadAssetAtPath(outpath, typeof(FB.PosePlus.AniClip)) as FB.PosePlus.AniClip; Pretreatment.AnimatorCache[outpath] = src; src.clipName = PathHelper.CheckFileName(clip.name); con.AddAni(src); }