Inheritance: UnityEngine.ScriptableObject, IPlayAni
    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);
    }
Beispiel #2
0
    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);
                }
            }
        }
    }
Beispiel #3
0
    int calcbonehash(FB.PosePlus.AniClip clip)
    {
        string b = "";

        foreach (var bi in clip.boneinfo)
        {
            b += bi + "|";
        }
        return(b.GetHashCode());
    }
Beispiel #4
0
        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;
            }

        }
Beispiel #5
0
        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;
            }
        }
Beispiel #6
0
    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);
        }
    }
Beispiel #7
0
        //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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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;
        }
Beispiel #11
0
        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]);
            }
        }
Beispiel #12
0
 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;
     }
 }
Beispiel #13
0
    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;
    }
Beispiel #14
0
        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);
        }
Beispiel #15
0
    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);
    }
Beispiel #16
0
        /// <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]);
                }
            }
        }
Beispiel #17
0
    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;
 }
Beispiel #19
0
        /// <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);
    }
Beispiel #21
0
        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;
        }
Beispiel #22
0
        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;

        }
Beispiel #23
0
        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);
    }
Beispiel #25
0
        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;
        }
Beispiel #26
0
    //从一个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);
    }