x哥(懂的都懂)的框架, 拿点代码过来做注释. 想了解详情可以去他的github

https://github.com/yimengfan/BDFramework.Core

# Object files

# Libraries

# Shared objects (inc. Windows DLLs)
*.so.*
*.dylib

# Executables
*.exe
*.out
*.app
*.i*
*.x86_64
*.hex
/TestProject/Library
/TestProject/obj
/TestProject/Temp
/TestProject/UnityPackageManager
/TestProject/Assembly-CSharp.csproj
/TestProject/Assembly-CSharp-Editor.csproj
/TestProject/Assembly-CSharp-Editor-firstpass.csproj
/TestProject/TestProject.sln
/TestProject/.idea/.idea.TestProject/.idea/contentModel.xml
/TestProject/.idea/.idea.TestProject/.idea/indexLayout.xml
/TestProject/.idea/.idea.TestProject/.idea/modules.xml
/TestProject/.idea/.idea.TestProject/.idea/workspace.xml
/TestProject/.idea/.idea.TestProject/riderModule.iml
/TestProject/TestProject.sln.DotSettings.user
/TestProject/UpgradeLog.htm
/TestProject/Assets/Resource/.svn
/TestProject/Assets/Code/.svn
/TestProject/.sonarqube
/TestProject/TestProject.Editor.Plugins.csproj
/TestProject/TestProject.Editor.csproj
/TestProject/TestProject.csproj
/TestProject/.idea/.idea.TestProject/.idea/encodings.xml
/TestProject/.idea/.idea.TestProject/.idea/sonarIssues.xml
/TestProject/.idea/.idea.TestProject/.idea/vcs.xml
/TestProject/.vs/TestProject/v15/.suo
/TestProject/.vs/TestProject/v15/Server/sqlite3/db.lock
/TestProject/.vs/TestProject/v15/Server/sqlite3/storage.ide
/TestProject/.vs
/TestProject/.idea
/TestProject/.idea
/TestProject/.vs
/TestProject/UnityDLL
/TestProject/*.err
/TestProject/*.tmp
/TestProject/*.cmdline
/TestProject/Unity.PackageManagerUI.Editor.csproj
/TestProject/Unity.TextMeshPro.Editor.csproj
/TestProject/Unity.TextMeshPro.csproj
/TestProject/UnityEditor.StandardEvents.csproj
/TestProject/Assets/Plugins/Editor/JetBrains/JetBrains.Rider.Unity.Editor.Plugin.Repacked.dll
/TestProject/Assets/Plugins/Editor/JetBrains
TestProject/Assets/Code/Game/Editor.meta
TestProject/Assets/Code/Game/Editor/AnimtionImport.meta
TestProject/Assets/Code/Game/Editor/Data.meta
TestProject/Assets/Code/Game/Editor/HeroEdit.meta
TestProject/Assets/Code/Game/Editor/RouteTool.meta
TestProject/Assets/Code/Game/Editor/AnimtionImport/Editor.meta
TestProject/Assets/Code/Game/Editor/HeroEdit/Editor.meta
TestProject/Assets/Code/Game/Editor/HeroEdit/Table.meta
TestProject/Assets/Code/Game/Editor/HeroEdit/TableAttributes.meta
TestProject/Assets/Code/Game/Editor/RouteTool/Editor.meta
TestProject/Assets/Plugins/iOS.meta
/TestProject/Assets/StreamingAssets/Windows/Art
/TestProject/Assets/StreamingAssets/iOS/Art
/TestProject/rotorz.dotnet-exception-utils.csproj
/TestProject/rotorz.dotnet-type-utils.csproj
/TestProject/rotorz.unity3d-editor-menu.editor.csproj
/TestProject/rotorz.unity3d-package-utils.editor.csproj
/TestProject/rotorz.unity3d-reorderable-list.csproj
/TestProject/rotorz.unity3d-reorderable-list.editor.csproj
/TestProject/rotorz.unity3d-utils.csproj
/TestProject/rotorz.unity3d-utils.editor.csproj
/TestProject/Assembly-CSharp-firstpass.csproj
/TestProject/ProjectSettings/ProjectVersion.txt
/TestProject/Logs
/TestProject/Assets/Code/BDFramework/Tools/ILRBuild/build.sln.meta
/TestProject/Assets/Code/BDFramework/Tools/ILRBuild/build.sln
/TestProject/Assets/Plugins/Editor/JetBrains.meta
/TestProject/Assets/Code/BDFramework/Tools/ILRBuild/build.exe.meta
/TestProject/Assets/Plugins/Sirenix/Odin Inspector/Config/Resources.meta
/TestProject/Assets/Plugins/Sirenix/Odin Inspector/Config/Resources/Sirenix.meta
/TestProject/Assets/3rdPlugins/.svn
/TestProject/Assets/DebugUILine.cs
/TestProject/Assets/DebugUILine.cs.meta
/TestProject/Assets/DebugUILine.cs
/TestProject/Assets/StreamingAssets/Windows/hotfix/Assembly-CSharp.dll.mdb.meta
/TestProject/Assets/StreamingAssets/Windows/hotfix/Assembly-CSharp.dll.mdb
/TestProject/Assets/Resource/Effect/.svn
/TestProject/Assets/StreamingAssets/.svn
/TestProject/Assets/3rdPlugins/com.unity.textmeshpro@1.3.0/Tests.meta
/TestProject/Assets/3rdPlugins/com.unity.textmeshpro@1.3.0/Tests

参考 ignore

PosPlus 教程 https://www.bilibili.com/video/av23948137

资源目录(大致)

Resource(不是Resources)     资源目录

  Effect               特效目录

  Font              字体目录

  handlers             协议目录

  Img               图片目录

  Model              模型目录

  Resources           打进本地包

  Runtime            运行时

  Scene               场景目录

  Shaders           Shader目录

  Table                Excel表目录

  TableEditor          JSON表目录

导入流程

原始文件

sunwukong@ani.txt(UTF-8)

Ctrl+D 复制动画信息

打开 Animation 窗口

删除 动画 Position 信息

创建 Animator Controller

将动画拖进 Animator Controller

添加脚本

#region    FPS计算

    float fps;
    float deltaTime = 0.0f;
    float msec;
    Rect rect;
    GUIStyle style = new GUIStyle();

    void Start() {
        int w = Screen.width, h = Screen.height;
        rect = , , , h *  / );
        style.alignment = TextAnchor.UpperLeft;
        style.fontSize = h *  / ;
        style.normal.textColor = new Color(1.0f, 0.0f, 0f, 1.0f);
    }

    void Update() {
        deltaTime += (Time.deltaTime - deltaTime) * 0.1f;
    }

    void OnGUI() {
        msec = deltaTime * 1000.0f;
        fps = 1.0f / deltaTime;

        GUI.Label(rect, string.Format("{0:0.0} ms ({1:0.} fps)", msec, fps), style);
    }

    #endregion

FPS计算

    [UnityEditor.MenuItem()]
    static public void DeleteModelUnuseData()
    {
        var path = Application.dataPath + "/Resource/Runtime/Char";

        var fs = Directory.GetFiles(path, "*.prefab", SearchOption.AllDirectories);

        ;
        foreach (var f in fs)
        {
            i++;
            EditorUtility.DisplayProgressBar("处理模型", Path.GetFileName(f), i / fs.Length);
            //
            var absPath = "Assets" + f.Replace(Application.dataPath, "");
            var o = AssetDatabase.LoadMainAssetAtPath(absPath) as GameObject;
            //添加特殊点
            var p1 = o.transform.Find("EffectPoint");
            if (p1 == null)
            {
//                var op1= new GameObject("EffectPoint");
//                op1.transform.SetParent(o.transform,false);
                Debug.LogError("缺少节点 EffectPoint:" + absPath);
            }

            var p2 = o.transform.Find("AtkPoint");
            if (p2 == null)
            {
                p2 = o.transform.Find("Bip001/AtkPoint");
//                var op2= new GameObject("AtkPoint");
//                op2.transform.SetParent(o.transform,false);
                if (p2 == null)
                    Debug.LogError("缺少节点 AtkPoint:" + absPath);
            }

            var p3 = o.transform.Find("BehurtPoint");
            if (p3 == null)
            {
//                var op3= new GameObject("BehurtPoint");
//                op3.transform.SetParent(o.transform,false);
                Debug.LogError("缺少节点 BehurtPoint:" + absPath);
            }

            //添加特殊点
            var p4 = o.transform.Find("StaticPoint");
            if (p4 == null)
            {
//                var op1= new GameObject("EffectPoint");
//                op1.transform.SetParent(o.transform,false);
                Debug.LogError("缺少节点 StaticPoint:" + absPath);
            }

            var p5 = o.transform.Find("HeadPoint");
            if (p5 == null)
            {
//                var op1= new GameObject("EffectPoint");
//                op1.transform.SetParent(o.transform,false);
                Debug.LogError("缺少节点 HeadPoint:" + absPath);
            }
            else
            {
                p5.position = ,);
            }

            //删除镜头
            var cams = o.GetComponentsInChildren<Camera>();
            foreach (var c in cams)
            {
                GameObject.DestroyImmediate(c, true);
            }

            //删除animator
            var ani = o.GetComponent<Animator>();
            if (ani != null)
            {
                GameObject.DestroyImmediate(ani, true);
            }
        }

        EditorUtility.ClearProgressBar();
        AssetDatabase.SaveAssets();
        //
        AssetDatabase.Refresh();
    }

模型资源检测

    [MenuItem("Assets/自动创建角色", true)]
    static public bool CreateCharValidation()
    {
        string path = AssetDatabase.GetAssetPath(Selection.activeObject).ToLower();
        return path.EndsWith(".fbx");
    }

    [MenuItem("Assets/自动创建角色")]
    static public void CreateChar()
    {
        string path = AssetDatabase.GetAssetPath(Selection.activeObject);
        Object[] objs = AssetDatabase.LoadAllAssetsAtPath(path);
        string directory = Path.GetDirectoryName(path) + "/";
        Dictionary<string, AnimationClip> clipDict = CreateAnimClips(directory, objs);

        AnimatorController ac = CreateAnimController(directory, clipDict);
        Dictionary<string, Material> matDict = CreateMaterials(directory, objs);
        CreatePrefab(path, matDict, ac, clipDict);
    }

    private static Dictionary<string, AnimationClip> CreateAnimClips(string directory, Object[] objs)
    {
        Dictionary<string, AnimationClip> clipDict = new Dictionary<string, AnimationClip>();
        AnimationClip srcClip; //源AnimationClip
        AnimationClip newClip; //新AnimationClip
        string animationPath = "";
        foreach (Object o in objs)
        {
            if (o.GetType() == typeof(AnimationClip))
            {
                srcClip = o as AnimationClip;
                if (srcClip.name.Equals("__preview__Take 001")) continue;
                EditorUtility.DisplayProgressBar("复制动画文件", srcClip.name, 0.1f);
                newClip = new AnimationClip();
                newClip.name = srcClip.name;
                //防止动画命名出错
                if (newClip.name == "hit")
                {
                    newClip.name = "behurt";
                }

                animationPath = directory + srcClip.name + ".anim";
                if (File.Exists(animationPath))
                {
                    File.Delete(animationPath);
                }

                var setting = AnimationUtility.GetAnimationClipSettings(srcClip);
                if (srcClip.name == "idle")
                {
                    setting.loopTime = true;
                }

                AnimationUtility.SetAnimationClipSettings(newClip, setting); //设置新clip的AnimationClipSettings
                newClip.frameRate = srcClip.frameRate; //设置新clip的帧率
                EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(srcClip); //获取clip的curveBinds
                ; i < curveBindings.Length; i++)
                {
                    AnimationUtility.SetEditorCurve(newClip, curveBindings[i],
                        AnimationUtility.GetEditorCurve(srcClip, curveBindings[i])); //设置新clip的curve
                }

                EditorUtility.DisplayProgressBar("复制动画文件", srcClip.name, 0.7f);
                AssetDatabase.CreateAsset(newClip,
                    animationPath); //AssetDatabase中的路径都是相对Asset的  如果指定路径已存在asset则会被删除,然后创建新的asset

                EditorUtility.DisplayProgressBar("复制动画文件", srcClip.name, 0.9f);
                clipDict.Add(newClip.name, newClip);
            }
        }

        EditorUtility.ClearProgressBar();
        AssetDatabase.SaveAssets(); //保存修改
        AssetDatabase.Refresh();
        return clipDict;
    }

    private static AnimatorController CreateAnimController(string directory, Dictionary<string, AnimationClip> clipDict)
    {
        //创建animationController文件,保存在Assets路径下
        AnimatorController animatorController =
            AnimatorController.CreateAnimatorControllerAtPath(directory + "New Animation Controller.controller");
        //得到它的Layer, 默认layer为base 你可以去拓展
        AnimatorControllerLayer layer = animatorController.layers[];
        AnimatorStateMachine sm = layer.stateMachine;

        foreach (KeyValuePair<string, AnimationClip> kv in clipDict)
        {
            //取出动画名子 添加到state里面
            AnimatorState state = sm.AddState(kv.Key);
            state.motion = kv.Value;
            //把state添加在layer里面
            sm.AddAnyStateTransition(state);
        }

        return animatorController;
    }

    private static Dictionary<string, Material> CreateMaterials(string directory, Object[] objs)
    {
        Dictionary<string, Material> dict = new Dictionary<string, Material>();
        string matPath = directory + "/Materials";
        if (Directory.Exists(matPath))
        {
            Directory.Delete(matPath, true);
            AssetDatabase.Refresh();
        }

        Directory.CreateDirectory(matPath);
        foreach (Object o in objs)
        {
            if (o.GetType() == typeof(Material))
            {
                var srcMat = o as Material;
                EditorUtility.DisplayProgressBar("复制材质球", srcMat.name, 0.1f);
                var newMat = new Material(srcMat);
                newMat.name = srcMat.name;
                EditorUtility.DisplayProgressBar("复制材质球", srcMat.name, 0.7f);
                string newPath = matPath + "/" + newMat.name + ".mat";
                AssetDatabase.CreateAsset(newMat, newPath);
                EditorUtility.DisplayProgressBar("复制材质球", srcMat.name, 0.9f);
                dict.Add(newMat.name, newMat);
            }
        }

        EditorUtility.ClearProgressBar();
        AssetDatabase.SaveAssets(); //保存修改
        AssetDatabase.Refresh();
        return dict;
    }

    private static void CreatePrefab(string path, Dictionary<string, Material> matDict,
        AnimatorController ac, Dictionary<string, AnimationClip> clipDict)
    {
        var charPath = Application.dataPath + "/Resource/Runtime/Char/";
        int count = Directory.GetFiles(charPath, "*.prefab", SearchOption.TopDirectoryOnly).Length;
        count++;

        var o = AssetDatabase.LoadMainAssetAtPath(path) as GameObject;
        GameObject go = GameObject.Instantiate(o);
        //1.设置prefab的name
        go.name = count >  ? count + " + count;
        //2,设置特殊点
        GameObject point = new GameObject("EffectPoint");
        point.transform.SetParent(go.transform, false);
        point = new GameObject("BehurtPoint");
        point.transform.SetParent(go.transform, false);
        point = new GameObject("StaticPoint");
        point.transform.SetParent(go.transform, false);
        point = new GameObject("AtkPoint");
        point.transform.SetParent(go.transform, false);
        point = new GameObject("HeadPoint");
        point.transform.position = ,);
        point.transform.SetParent(go.transform, false);
        //3.设置材质球
        Renderer[] renders = go.GetComponentsInChildren<Renderer>();
        foreach (var render in renders)
        {
            int cnt = render.sharedMaterials.Length;
            Material[] matArr = new Material[cnt];
            ; i < cnt; i++)
            {
                Material oldMat = render.sharedMaterials[i];
                Material newMatPath;
                if (matDict.TryGetValue(oldMat.name, out newMatPath))
                {
                    matArr[i] = newMatPath;
                }
                else
                {
                    //一般不会走进来
                    matArr[i] = null;
                }
            }

            render.sharedMaterials = matArr;
        }

        //4.animator controller 操作
        Animator animator = go.GetComponent<Animator>();
        if (animator == null)
        {
            animator = go.AddComponent<Animator>();
        }

        RuntimeAnimatorController runAnim =
            AssetDatabase.LoadAssetAtPath<RuntimeAnimatorController>(AssetDatabase.GetAssetPath(ac));
        animator.runtimeAnimatorController = runAnim;
        AniPlayer aniPlayer = go.gameObject.AddComponent<FB.PosePlus.AniPlayer>();
        animator.enabled = false;
        aniPlayer.Clips = null;
        foreach (var c in clipDict.Values)
        {
            CloneAni(animator, c, c.frameRate);
        }

        //5.创建 skill相关
        SkillPlayer_TBS skilltbs = go.GetComponent<SkillPlayer_TBS>();
        if (skilltbs == null)
        {
            skilltbs = go.AddComponent<SkillPlayer_TBS>();
        }

        G_Skill _s = new G_Skill();
        string directory = System.IO.Path.GetDirectoryName(path);
        string outpath = directory + "/" + skilltbs.name + ".Skills.txt";
        File.WriteAllText(outpath, JsonMapper.ToJson(_s));
        AssetDatabase.Refresh();
        var src = AssetDatabase.LoadAssetAtPath<TextAsset>(outpath);
        skilltbs.SkillText = src;
        AssetDatabase.SaveAssets();
        PrefabUtility.SaveAsPrefabAsset(go, "Assets/Resource/Runtime/Char/"+go.name+".prefab");
        GameObject.DestroyImmediate(go);
    }

    static void CloneAni(Animator target, AnimationClip clip, float fps)
    {
        var ani = target;

        //创建CleanData.Ani
        FB.PosePlus.AniClip _clip = ScriptableObject.CreateInstance<FB.PosePlus.AniClip>();
        _clip.boneinfo = new List<string>(); //也增加了每个动画中的boneinfo信息.

        //这里重新检查动画曲线,找出动画中涉及的Transform部分,更精确
        List<Transform> cdpath = new List<Transform>();
        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.loop = clip.isLooping;
        float flen = (clip.length * fps);
        int framecount = (int) flen;
        if (flen - framecount > 0.0001) framecount++;
        //if (framecount < 1) framecount = 1;

        framecount += ;
        FB.PosePlus.Frame last = null;

        //ani.StartPlayback();
        //逐帧复制
        //ani.Play(_clip.name, 0, 0);
        ; i < framecount; i++)
        {
            ani.Play(_clip.name, , (i * 1.0f / fps) / clip.length);
            ani.Update();

            last = new FB.PosePlus.Frame(last, i, cdpath);
            _clip.frames.Add(last);
        }

        if (_clip.loop)
        {
            _clip.frames[].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;
    }

自动创建角色

https://github.com/blueberryzzz/ReferenceFinder

    

BDFramework.Core 学习的更多相关文章

  1. EntityFramework Core 学习系列(一)Creating Model

    EntityFramework Core 学习系列(一)Creating Model Getting Started 使用Command Line 来添加 Package  dotnet add pa ...

  2. ASP.NET Core学习系列

    .NET Core ASP.NET Core ASP.NET Core学习之一 入门简介 ASP.NET Core学习之二 菜鸟踩坑 ASP.NET Core学习之三 NLog日志 ASP.NET C ...

  3. Nancy in .Net Core学习笔记 - 初识Nancy

    前言 去年11月份参加了青岛MVP线下活动,会上老MVP衣明志介绍了Nancy, 一直没有系统的学习一下,最近正好有空,就结合.NET Core学习总结了一下. 注: 本文中大部分内容都是对官网文档的 ...

  4. .NET CORE学习笔记系列(2)——依赖注入[7]: .NET Core DI框架[服务注册]

    原文https://www.cnblogs.com/artech/p/net-core-di-07.html 包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IS ...

  5. .NET CORE学习笔记系列(2)——依赖注入[6]: .NET Core DI框架[编程体验]

    原文https://www.cnblogs.com/artech/p/net-core-di-06.html 毫不夸张地说,整个ASP.NET Core框架是建立在一个依赖注入框架之上的,它在应用启动 ...

  6. .NET CORE学习笔记系列(2)——依赖注入[5]: 创建一个简易版的DI框架[下篇]

    为了让读者朋友们能够对.NET Core DI框架的实现原理具有一个深刻而认识,我们采用与之类似的设计构架了一个名为Cat的DI框架.在上篇中我们介绍了Cat的基本编程模式,接下来我们就来聊聊Cat的 ...

  7. .NET CORE学习笔记系列(2)——依赖注入[4]: 创建一个简易版的DI框架[上篇]

    原文https://www.cnblogs.com/artech/p/net-core-di-04.html 本系列文章旨在剖析.NET Core的依赖注入框架的实现原理,到目前为止我们通过三篇文章从 ...

  8. .NET CORE学习笔记系列(2)——依赖注入【3】依赖注入模式

    原文:https://www.cnblogs.com/artech/p/net-core-di-03.html IoC主要体现了这样一种设计思想:通过将一组通用流程的控制权从应用转移到框架中以实现对流 ...

  9. .NET CORE学习笔记系列(2)——依赖注入【2】基于IoC的设计模式

    原文:https://www.cnblogs.com/artech/p/net-core-di-02.html 正如我们在<控制反转>提到过的,很多人将IoC理解为一种“面向对象的设计模式 ...

随机推荐

  1. python--numpy生成正态分布数据及randint randn normal的使用

    正太分布:也叫(高斯分布Gaussian distribution),是一种随机概率分布 机器学习中numpy.random如何生成这样的正态分布数据,本篇博客记录这样的用法 import numpy ...

  2. 1+X证书web前端开发中级对应课程分析

    官方QQ群 1+x 证书 Web 前端开发 JavaScript 专项练习 http://blog.zh66.club/index.php/archives/198/ 1+x 证书 Web 前端开发初 ...

  3. 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 7

    23.5  创建RESTful规范 WebAPI框架 虽然我们现在可以自己实现API了,也了解了RESTful API的设计原则,但让自己实现的API符合RESTful API规范,对很多刚接触API ...

  4. LeetCode 71.简化路径

    LeetCode 71.简化路径 题目描述: 以 Unix 风格给出一个文件的绝对路径,你需要简化它.或者换句话说,将其转换为规范路径.在 Unix 风格的文件系统中,一个点(.)表示当前目录本身:此 ...

  5. @PostConstruct - 静态方法调用IOC容器Bean对象

    需求:工具类里面引用IOC容器Bean,强迫症患者在调用工具类时喜欢用静态方法的方式而非注入的方式去调用,但是spring 不支持注解注入静态成员变量. 静态变量/类变量不是对象的属性,而是一个类的属 ...

  6. python-3.8.0 新特性之赋值表达式

    [python-3.8.0 新特性之赋值表达式] 赋值表达式的语法是这样的“ name := expression ”,形式上看和赋值语句 “ = ” 差不多,就作用上来看也雷同.也就是说 “:=” ...

  7. jquery 图片缩放插件使用

    https://cdn.bootcss.com/d3-transition/1.1.1/d3-transition.js http://www.jq22.com/jquery-info9291

  8. 完整版的CAD技巧!3天轻松玩转CAD,零基础也能学会

    最近有很多小伙伴反应,CAD图纸学起来有点小困难,也许你还没能掌握技巧,CAD大神带你3天轻松玩转CAD,零基础也能快速学会. 一.看懂图纸是关键 CAD制图首先得让自己知道要绘制什么,如果心中对图纸 ...

  9. 控制台程序(C#)不弹出登录窗口连接到Dynamics CRM Online的Web API

    微软动态CRM专家罗勇 ,回复331或者20190505可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me! 我之前的文章 控制台程序(C#)不弹出认证窗口连接到Dynami ...

  10. 实时数据推送webSocket

    实时数据推送 在Web或移动项目中,服务器向客户端实时推送消息是一种常见的业务需求. 实现方式 Polling:轮询(俗称“拉”),即定期重新请求数据. Long-Polling:长轮询,是 Poll ...