Unity使用spine动画

2023-11-20

Unity使用spine动画

在 Unity 中,常常使用 Spine 来制作一些动画,引擎本身并不能直接播放 Spine 动画,需要额外导入一个 RunTime 插件库才能支持。

官网插件导入

当然,也可以到 Spine 官网关于 Unity 插件的下载地址spine-unity-download 直接下载最新的插件包,导入插件核心库的同时,还是导入一些 demo 例子,帮助我们快速上手使用插件的 API ,因此这里我也选择使用第二种方式导入插件。建议新建一个空工程来导入相关 demo 了解插件的使用,而正式工程只导入 spine-csharp 和 spine-unity 两个部分即可。

插件导入步骤

  • 在 Unity 菜单中依次点击:Assets->Improt Package->Custom Package ;
  • 选中 Spine-Unity 3.6 runtime unitypackage 并导入,去掉 Spine Examples 的勾选(假如需要查看 demo 则点击 All );

image

  • 点击 Import 完成导入,导入完成后在工程 Assets 下会多出一个 Spine 目录,表示导入成功。

Spine 资源导入步骤

通常制作好的 Spine 动画导出时会有三个文件: .png 、.json 和 .atlas :

image

  • 在导入 Unity 之前需要将 .atlas 后缀的文件改为 .atlas.txt 后缀(不修改可能会有问题);
  • 将三个文件拖到 Unity 的 Project 面板中,假如运行库导入正常,此时会生成三个新的文件:_Atlas 、_Material 和 _SkeletinData ,并且在 Console 面板中会打印导入成功的日志:

image

三个文件的作用:

  • _Material资源包含一个着色器引用和.png纹理。
  • _Atlas资源包含一个材质引用和.atlas.txt 。
  • _SkeletonData资源包含一个json引用和_Atlas资源。

在 UGUI 中使用 Spine

在 Hierarchy 面板中,右键 Spine->SkeletonGraphic(UnityUI) :

image

然后将 Spine 资源导入时生成的 _SkeletinData 文件拖到动画 UI 对象的 Skeleton Data Asset 属性中,且可以编辑相应的动画控制属性:
image

勾选 Starting Loop 然后运行场景即可看到当前 Starting Animation 所选中动画的效果,并能动态切换其他动画。

程序控制

很多时候,动画需要通过程序控制实现动态创建、切换和销毁,主要会用到几个组件:SkeletonAnimation 、SkeletonGraphic 和 SkeletonRenderer :

  • SkeletonAnimation 动画基本控制组件:

      skeletonAnimation.timeScale = 1.5f;
      skeletonAnimation.loop = true;
      skeletonAnimation.AnimationName = "run";
    

这里用于设置动画的播放速度,是否循环,还有切换动画,如下脚本,将其挂在带 SkeletonAnimation 或继承自 SkeletonAnimation 的组件的物体上,用于播放一次动画:

      using UnityEngine;​
    public class TestSpineAnimCtl : MonoBehaviour {
        public SkeletonAnimation sa;​
        // Use this for initialization
        void Start () {
            sa = sa ?? gameObject.GetComponent<SkeletonAnimation>();
            PlayAnim("run2");
        }​
        public void PlayAnim(string animName) {
            sa.state.SetAnimation(0, animName, false);
        }
    }

通过获取其 state 属性,其实是 Spine.AnimationState 对象。

切换动画的bug

由于spine在切换动画的时候自动补偿,用于动画的平稳过度。但是会导致残影等bug,这时候需要在SetAnimation前调用
skeletonAnimation.skeleton.SetToSetupPose ();
spineAnimationState.ClearTracks ();
来消除前一个动画的影响。

左右方向动画

不比在Spine编辑对话框中设置动画的朝向(向左、向右)。SkeletonAnimation的Skeleton对象有FlipX(还有FlipY)的属性,你可以根据需要设置骨骼的水平镜像。

    // 如果你的角色已经是面向右边的,那么这样设置后就会面向左边。
    skeletonAnimation.skeleton.FlipX = true; 

然而,如果你的角色在设计时两边朝向的动画是不一样的,你可以使用Spine的皮肤功能,一个皮肤表示向左,而另一个向右,然后再设置一个变量根据不同的朝向切换皮肤。

    bool facingLeft = (facing != "right"); 
    skeletonAnimation.skeleton.FlipX = facingLeft;
    skeletonAnimation.skeleton.SetSkin(facingLeft ? "leftSkin" : "rightSkin");

通道(Track)

Track是把动画分层,让角色在同一时间可以播放几个Spine动画。

这在任何情况下都是有用的,比如,你的角色正在跑动,但是还想在跑动的时候拿枪进行射击。

如果你在Track 0播放一个动感,然后在Track 1中播放另一个动画,这两个动画在同时播放时可以根据各自的需要去控制结束点和是否循环。

在动画播放过程中,高层级的通道会覆盖低层级的Track:越大的通道数字就拥有越高的优先级。

    // 跑步动画运行在Track 0,而射击动画运行在Track 1
    skeletonAnimation.state.SetAnimation(0, "run", true);
    skeletonAnimation.state.SetAnimation(1, "shoot", false);
  • SkeletonGraphic 用于 Unity 的 UI 中:

      using UnityEngine;​
      public class TestSpineAnimCtl : MonoBehaviour {
          public SkeletonGraphic sgp;​
          // Use this for initialization
          void Start () {
              sgp = sgp ?? gameObject.GetComponent<SkeletonGraphic>();
              PlayAnim("run2");
          }
      ​
          public void PlayAnim(string animName) {
              sgp.AnimationState.SetAnimation(0, animName, false);
          }
      }
    

通过其 AnimationState 组件来控制动画,其实也是获取一个 Spine.AnimationState 对象。

##添加事件:
skeletonAnimation.state.Start:开始播放
skeletonAnimation.state.End:动画被清除或者中断
skeletonAnimation.state.Interrupt:动画被打断
skeletonAnimation.state.Complete:播放结束
skeletonAnimation.state.Event:用户自定义事件
事件设置采用lambda表达式:
skeletonAnimation.state.Complete += (state, trackIndex,loopCount) => {
Debug.log("");
};
动态获取slot的坐标:
Vector3 pos

精灵纹理的渲染和Z轴次序

Spine一般使用阿尔法混合的方式去渲染你的Spine模型。

从Spine项目中绘制、上色和导出部件的时候,你导出PNG文件的像素编码格式是RGBA(红色、绿色、蓝色和阿尔法值)。在文件中,每个像素在阿尔法通道中有0-255的值,就像RGB通道一样,代表每个像素的透明度有256种层次。

这种透明与半透明在阿尔法通道中定义,展现深度/渲染顺序的经典问题。这些问题有许多不完善的解决方案,并且在我们今天的AAA游戏中也会发生一些奇怪的3D现象。

但是,在非常标准的方式中,也就是说i,像大多数2D阿尔法混合精灵渲染案例,包括Unity自己的Sprite/SpriteRenderer系统,spine-unity使用的渲染器,不使用3Dz-buffer和非阿尔法测试去确定哪些渲染在前,哪些渲染在后。

在一个网格中,它根据网格中三角形的顺序去渲染物体,然后绘制一个东西在另一个东西上面。该顺序是在Spine中控制槽的绘制顺序来决定的。

网格之间,spine-unity使用一些Unity的渲染顺序系统去确定 精灵/网格 应该谁上面。这是使用spine-unity标准配置的典型行为: Between meshes, spine-unity uses many of Unity’s render order systems to determine what sprite/mesh should be on top of which. Using the standard spine-unity setup, here is typical behavior for it:

  • 网格数据被当作一个整体传递给Unity。
  • 它使用GPU的triangle-by-triangle的方式渲染。
  • 所有网格的渲染由多种因素确定顺序:
    • 着色器的语言和队列标签(默认为其他精灵的“透明”队列)
    • Material.renderQueue。(除非你设置它否则它就什么都不做。它只是覆盖shader语言的队列标签)

分层和排序

Sorting LayerSorting Order属性其实是在SkeletonRenderer/SkeletonAnimation的Inspector中,实际上它只是修改了MeshRenderer的sorting layersorting order 属性.

尽管被隐藏在MeshRenderer的Inspector中,这些属性实际上是MeshRendererserialized/stored的一部分,而不是SkeletonRenderer。

通过摄像头距离排序

如果你保持所有的渲染器同样的分层和排序,他们会收到上述其他排序方案的影响。

如果队列标签页一样(如果你使用相同的材质和着色器),那么你应该根据摄像机的距离去控制Spine游戏对象的排序。

别忘了这个透视摄像机的排序模式.

那么可以在我的Spine骨架的部分之间渲染任何东西吗?

有时候,你需要你的角色骑一辆自行车、举起一块石头或者拥抱一根柱子。对Spine而言,这意味着你要显示的东西,有些东西渲染在前面,有些东西渲染在后面。

在Unity中,网格是整体渲染的。那么你怎么知道哪个渲染在前面,哪个渲染在后面?

对于这个问题的答案是:可能将来会改变。

但是对于现在来说,你可以使用Spine-unity的SkeletonUtility方法调用"Submesh Renderers"。它会单独覆盖。

但基本上,它的作用是让你的SkeletonRenderer网格根据槽(上面和下面)去拆分。这些拆分的部分会根据他们自己的GameObject中的MeshRenderers去渲染。因为他们是单独渲染的,你可以分别设置他们的Sorting Order。

我已经调低了骨架的阿尔法值,为什么还会重复显示?

这在任何地方都适用的实时网格渲染。当三角形被绘制时透明度就被应用了,而不是之后。

这里大概有一些解决方案,或者一些变通方案。 去玩一些你最爱的游戏吧!你可以在各种2D游戏中找到一些变通方法的例子。

spine-unity怎么决定我的Spine模型的大小?

Spine使用 1像素:1单位。意思是,如果你只是包含图像在你的骨架中,并且没有任何旋转和缩放,在Spine中该图像的1个像素就对应1个单位高和1个单位宽。

在Unity中,1单位:1米。这是Unity默认的物理值和约束(包括2D和3D)。对于这点,使用1像素:1单位通常不是一个好主意。反而,Unity自己的精灵默认缩放为1/100;意味着100个像素就是1个Unity的单位大小。

为了方便,当你将Spine数据带入Unity的时候,可以将缩放设置为0.01用来匹配Unity的精灵。

效率优化

上面提到从 Spine 导出的文件有三种:.png 、.json 和 .atlas ,但使用 .json 格式读取动画数据是比较慢且运行效率较低的方式。Spine 新版本其实还支持更快的数据导出方式,即 Binary format ,那就是二进制的数据导出,采用这种方式导出的格式是:.png 、.skel 和 .atlas 。
image
导入前需要将 .skel 后缀改成 .skel.bytes ,将 .atlas 后缀改成 .atlas.txt ,然后再拖入 Unity 中,不然 .skel 文件不会对应生成 Unity 可识别的 .asset 格式的数据文件。

插件自带材质

由于打包的时候资源需要打包成 Assetbundle ,有几个插件自带的材质球需要注意一下的:

  • spine-unity\Modules\SkeletonGraphic\Shaders 中的 SkeletonGraphicDefault.mat 和 SkeletonGraphicTintBlack.mat ;
  • spine-unity\Shaders\Utility 中也有 HiddenPass.mat ;
  • spine-unity\Modules\SlotBlendModes 中有 SkeletonPMAMultiply.mat 和 SkeletonPMAScreen.mat
    需要动态加载这些材质球的话,需要将这些材质球与其他材质球资源一起打包,否则在手机包会出现材质球丢失。

手机包贴图丢失问题

当然,除了材质丢失,还有可能出现贴图丢失的问题,情况如下:

image

只有几个白色的方块,而正常的应该如下:

image

  1. 问题分析

现在这就是贴图丢失了,看了 《unity 在代码中创建spine动画组件》 才发现项目中用到了spine 动画,使用 Assetbundle 打包后,在手机上运行会出现丢材质的情况。如果不进行打包,直接放到 Resources 目录下是可以正常加载的,但是,这样包就会很大,而且也不能进行热更新。进过测试,发现在代码中创建 spine 组件是可以解决这个问题。

其实,最根本的问题是 :xxx_Altas.asset 和 xxx_SkeletonData.asset 这两个资源打包到 Assetbundle 之后就取不出来了(偶尔能取出),从而导致了 SkeletonGraphic 的 skeletonDataAsset 属性值变为 null 。

所以,要解决此问题可以干脆用代码动态创建两个对象替换这两个文件的作用即可:

        // 动态创建一个 spine 动画数据
        public static SkeletonDataAsset BuildSkeletonDataAsset(string skeletonPath, GameObject go) {
            SkeletonDataAsset sda;
            sda = ScriptableObject.CreateInstance<SkeletonDataAsset>();
            sda.fromAnimation = new string[0];
            sda.toAnimation = new string[0];
            sda.duration = new float[0];
            sda.scale = 0.01f;
            sda.defaultMix = 0.2f;
            AtlasAsset[] arrAtlasData = new AtlasAsset[1];
            for (int i = 0; i < arrAtlasData.Length; i++) {
                AtlasAsset atlasdata = ScriptableObject.CreateInstance<AtlasAsset>();
                atlasdata.atlasFile = ResourceManager.Instance.LoadAsset(skeletonPath + ".atlas.txt", typeof(TextAsset), go) as TextAsset;
                atlasdata.materials = new Material[1];
                atlasdata.materials[0] = ResourceManager.Instance.LoadAsset(skeletonPath + "_Material.mat", typeof(Material), go) as Material;
                arrAtlasData[i] = atlasdata;
            }
            sda.atlasAssets = arrAtlasData;
            sda.skeletonJSON = ResourceManager.Instance.LoadAsset(skeletonPath + ".skel.bytes", typeof(TextAsset), go) as TextAsset;
            return sda;
            }

步骤其实很简单,用代码动态创建一个 SkeletonDataAsset 对象,然后赋值给 SkeletonGraphic 中的 skeletonDataAsset 再调整相应的动画参数即可:

    using Spine.Unity;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    /// <summary>
    /// 用于解决 Spine 动画在手机 ab 包资源管理模式下贴图丢失问题
    /// </summary>
    public class SkeletonGraphicABReseter : MonoBehaviour {
        private SkeletonGraphic skg;
        public string spinePath = "";
        public string animName = "";
        public bool loop = false;
        public float timeScale = 1.0f;
    ​
        // Use this for initialization
        void Start () {
    #if UNITY_EDITOR
    ​
    #else
            skg = gameObject.GetComponent<SkeletonGraphic>();
            if(skg == null) {
                return;
            }
            ResetSkData();
    #endif
        }
    ​
        void ResetSkData() {
            if(skg.SkeletonDataAsset == null && spinePath.Length > 0) {
                Debugger.Log("------------ 重置动画");
                SkeletonDataAsset sda = Utils.BuildSkeletonDataAsset(spinePath, gameObject);
    ​
                skg.skeletonDataAsset = sda;
                // 重置动画
                skg.Initialize(true);
                skg.AnimationState.SetAnimation(0, animName, loop);
                skg.AnimationState.TimeScale = timeScale;
            }
        }
        }

在使用 SkeletonGraphic 的地方挂上此组件即可解决移动端材质丢失的问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity使用spine动画 的相关文章

  • Unity3D之MonoBehaviour

    Unity3D中的MonoBehaviour是一种基于组件的编程架构 用于开发游戏和应用程序 它是Unity引擎中用于创建行为的基类之一 并且可以让你通过重写其方法来定义对象在游戏运行时的行为 首先 在Unity中创建一个游戏对象并向其添加
  • unity 五种旋转方式localEulerAngles、eulerAngles、rotation、localRotation和Rotate的区别

    1 1 transform localEulerAngles 使用localEulerAngles进行旋转的时候 我们要使用transform localEulerAngles new Vector3 x y z 其中 new Vector
  • URP——后期处理特效

    通用渲染管道 URP 包括一个后处理效果的集成实现 如果使用URP 则不需要为后期处理效果安装额外的包 URP与Post Processing Stack v2包不兼容 URP使用体积框架进行后期处理效果 下面的图片显示了一个URP场景有没
  • Unity 实现选框选中物体

    最近在看RTS游戏视频注意到了选框功能 就尝试做了一下 功能实现 脚本挂载到Camera上 要不然OnPostRender 函数无法调用 rectMat新建一个材质球 设置成默认的Sprites就可以了 using System Colle
  • Unity3d中使用OnGUI()函数判断“键盘按下抬起”功能的新方法。

    private bool flagJudgeDownAllow true 开始值为true void OnGUI key Event current FunctionKeyCodeV1 key private void FunctionKe
  • Unity3D中通过代码修改子物体层级的顺序

    今天有个同事问我如何在程序中修改子物体的层级关系来改变遮挡关系 我给他敲出来一句代码 UI的层级关系是通过渲染表现出来的 在canvas下的物体 排序越靠前的越先被渲染 这样一来就会 被后来渲染的遮挡 总结一下有三句代码是修改子物体的层级的
  • Unity中的单元测试

    我知道的单元测试有两种方法 1 从Unity的AssetStore窗口下载UnityTestTools 已下架了 2 使用TestRuner 2018 2 5以上版本有 我用的是2018 2 7 TestRuner的用法 操作窗口 Wind
  • Unity Cinemachine插件学习笔记,实现单目标和多目标之间切换

    Cinemachine在2017版中正式加入 结合Timeline可以轻松的制作出一下相机动画 相比Unity自带的标准相机 这个Cinemachine插件可操作的变量更多 不同虚拟相机 用来控制相机的 可以平滑转换等 具体可以参考上篇 U
  • Unity笔记-打飞碟游戏

    目的 创建一个打飞碟游戏 简陋 游戏要求 游戏要分多个 round 飞碟数量每个 round 都是 n 个 但色彩 大小 发射位置 速度 角度 每次发射数量可以变化 游戏过程中 仅能创建 n 个飞碟 且不容许初始化阶段生成任何飞碟 飞碟线路
  • Vuforia Virtual Button(虚拟按钮)使用技巧

    最近一直在摸索Vuforia的使用 Virtual Button算是一个比较容易吸引人眼球的功能 在经过一些测试后 我来总结下自己在探索过程中得到的一些经验 1 如何新建一个Virtual Button工程 导入Vuforia sdk 后把
  • Unity+Pico 手柄按键控制

    一 定义手柄按键API 1 InputDevices GetDeviceAtXRNode 通过XRNode获取对应的设备 2 XRNode是一个枚举类型 包含LeftEye RightEye CenterEye Head LeftHand
  • 也想做一个绝地求生版的汽车控制移动,进来瞧瞧?(干货满满)

    控制车子移动 效果图附上 1 首先4个车轮复制一遍为车轮2备用 2 给车轮2全部添加wheel collider 只剩下车轮碰撞器和transform组件 3 给原版4个车轮添加脚本wheel 变量共有 面板赋值 依次添加车轮2里面的车轮c
  • Unity_如何使相机视角一直跟随角色移动

    实例代码如下 using System Collections using System Collections Generic using UnityEngine 相机视角跟踪 public class FollowTarget Mono
  • Unity动画系统详解5:BlendTree混合树是什么?

    摘要 Animator中有一个功能 用来解决多个动画之间的混合 经常用于移动动画之间的混合 这个功能叫做BlendTree 混合树 洪流学堂 让你快人几步 你好 我是跟着大智学Unity的萌新 我叫小新 这几周一起来复 yu 习 xi 动画
  • Unity里清除Console控制台Log的函数

    Log输出部分转发来自 http blog sina com cn s blog 13c4bf4b40102wz0r html 在控制台输出中 是开发者常用到的一种函数 通过Debug类来实现 打印字符串 Debug Log log 如果有
  • Unity3D 官方文档 平台特殊化之Standalone和多显示器的处理

    版本 unity 5 6 语言 C 总起 Standalone 我一眼看下去的理解就是PC机平台 官方文档中说该平台指的是Mac Windows和Linux 这篇文章主要讲的是Standalone平台下的设置 通过点击菜单栏的File gt
  • Input.GetAxis _ Unity3d

    Input GetAxis 获取轴 static function GetAxis axisName string float Description描述 Returns the value of the virtual axis iden
  • Unity中UI框架的使用1-添加面板、显示Loading页面

    其中BasePanel和Canvas都是挂在面板的预制物上的 1 导入我们的UI框架 本篇文章中有用的是两个UIPanelType NUIManager和NBasePanel 会放在文章最后供大家使用 2 先将我们做好的Panel设置成预制
  • unity的LOD组件

    本文转载自http blog csdn net huutu article details 52106468 LOD是Level Of Detais 的简称 多细节层次 在游戏场景中 根据摄像机与模型的距离 来决定显示哪一个模型 一般距离近
  • Mecanim Any State

    Any State表示任意状态 任意状态是 一个一直存在的特殊状态 他的存在是为了保证你在无意转移至某个你当前正处于的特殊状态而准备的 为你的状态机中的每个状态设置相同的对外转移是一个快捷的方式 假如有Walk Run Fly Die这四个

随机推荐

  • Java Quartz框架

    Java Quartz框架 Java Quartz是一个开源的作业调度框架 用于在Java应用程序中实现定时任务和调度功能 它提供了灵活的任务调度和执行机制 可以根据时间表或触发事件来触发任务的执行 Quartz的主要作用是简化定时任务的管
  • elasticsearch query bool nested对象 聚合

    复杂的查询 下面的查询是小编自己研究写的一个比较复杂 的语句 涉及到查query bool must 已经过滤条件term 关键词介绍 from 表示从第几条开始返回 size 表示返回的题目数大小 query 查询语句 bool must
  • 抢「.AI」域名,成了 3000 万美元的大生意

    作者 汤一涛编辑 靖宇 1848 年 一个木匠在加利福尼亚州科罗马地区的一条河中偶然发现了金箔 尽管他曾试图保守这个秘密 但是金子不会说谎 一场席卷全美的淘金热就此开始 许多人怀揣着一夜暴富的梦想涌入加利福尼亚 1847 到 1870 年间
  • tensorflow-GPU版本安装,RTX3060

    首先需要安装好pycharm和anaconda 开始安装tensorflow GPU版 一 查看版本 1 首先检查自己电脑的cudn版本 开始 gt 设置 gt 应用 gt 安装的应用 搜cuda 我的是cuda 11 6 2 查看显卡型号
  • qt线程

    qt4 7 之前的线程操作 代码 需要重写一个类 继承QTread class mythread public QThread Q OBJECT 必须加 否则出现一些奇怪问题 public mytherad protected void r
  • 自动化办公-3.python自动化之word操作

    一 课前准备 python 处理 Word 需要用到 python docx 库 终端执行如下安装命令 pip3 install python docx 备注 可能word用的少 这块并没认真 但是后面的邀请函这块可以作为有用参考 没准会用
  • 什么是SSL协议?

    转自 微点阅读 https www weidianyuedu com 什么是SSL协议 SSL协议是一种安全传输协议 SSL是SecureSocketLayer的缩写 即安全套接层协议 该协议最初由Netscape企业发展而来 目前已经成为
  • 在本地部署自己的漏洞文章武器库(详细步骤说明)

    在本地部署自己的漏洞文章武器库 在平时我们进行web渗透的过程中 有些poc CVE详细情况需要进行查询之后才能进行利用 对于初级渗透人员来说 对漏洞情况和利用方式掌握不足的情况下 打造属于自己的漏洞武器库就至关重要了 可以提高平时工作和h
  • 调试osgEarth(十五)分页瓦片加载器在更新遍历时对请求处理过程(1)

    感谢 hankern 学习链接https blog csdn net hankern article details 84195754 继续调试 我感觉有两点 1 处理能处理的请求 2 摒弃处理过的请求和超时的请求 从上图可以看到 每帧可以
  • Mybatis进阶--批量新增数据

    一 传统JDBC进行批处理操作 package jdbc import java io InputStream import java sql import java util Properties public class jdbcUti
  • maven更换阿里云镜像

    1 setting文件增加maven节点
  • numpy索引与切片

    一 整数索引 作用 要获取数组的单个元素 指定元素的索引即可 例子 x np array 1 2 3 4 5 6 7 8 print x 2 3 x np array 11 12 13 14 15 16 17 18 19 20 21 22
  • listview item设置点击跳转_Flutter之路由及页面跳转与返回

    1 路由跳转到页面思路 设计三个按钮 然后三个点击事件 利用Navigator of context push MaterialPageRoute builder context gt page 进行跳转新页面2 页面折回到路由在跳转的页面
  • 小程序v-for与key值使用

    小程序中的v for和key与Vue中的用法基本相同 v for用于循环渲染列表 key用于给每个循环项分配一个唯一的标识 使用v for时 通常建议使用wx for代替 例如
  • SQL Server 中给字段设置默认值的方式

    1 在创建表的时候创建默认值 if object id T U is not null drop table T GO create table T ID int Name varchar 20 LoginTime datetime def
  • RecyclerView应用 —— 好友列表实现

    实现的效果类似于QQ好友列表 点击可展开 再次点击收起 两个Item的布局都很简单 这里就不给布局代码了 值得一提的是 RecyclerView本身并没有ListView那样的点击效果 想要类似效果可以为Item的根布局写个Selector
  • JS混淆加密的代码如何解密

    科普简介 混淆是指将 JavaScript 代码变得难以理解的过程 这可以通过更改变量名 函数名和类名 以及将代码压缩到一行来实现 混淆的主要目的是使代码难以被盗用 并保护代码的知识产权 功能作用与常用的解决方案 混淆后的代码很难阅读 但是
  • Maven进阶-配置仓库

    1 1maven介绍 Maven是一个项目管理和综合工具 Maven提供了开发人员构建一个完整的生命周期框架 开发团队可以自动完成项目的基础工具建设 Maven使用标准的目录结构和默认构建生命周期 主要服务于基于Java平台的项目构建 依赖
  • Linux系统如何看目录属于哪个磁盘分区

    Linux是先有目录 再有磁盘分区 df h 目录 例如 没有挂载磁盘的目录 显示在系统盘 root iZ2ze57v3n0zma46zqiq8nZ sh 1 5 5 df h alidata Filesystem Size Used Av
  • Unity使用spine动画

    Unity使用spine动画 在 Unity 中 常常使用 Spine 来制作一些动画 引擎本身并不能直接播放 Spine 动画 需要额外导入一个 RunTime 插件库才能支持 官网插件导入 当然 也可以到 Spine 官网关于 Unit