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研究院之游戏开发中的人工智能AI

    人工智能这个东西在游戏中是非常重要的 人工智能说简单了就是根据随机的数字让敌人执行一些动作或逻辑 说难了TA需要一个非常复杂的算法 本文我主要说说Unity3D中人工智能的脚本如何来编写 首先你应该搞清楚的一点AI脚本属于一个工具类脚本 工
  • unity如何解决每次写完敲代码,调试时需要卡个进度条

    解决办法如下 勾选上之后程序就可以立刻运行起来了 再也不用一直卡进度条了 不过也有弊端的 会影响静态字段初始化有问题还有Dotween的一些效果会发生变化 谨慎避免入坑
  • Unity的C#编程教程_59_字典 Dictionary 详解及应用练习

    文章目录 C Dictionary Introduction C Dictionary Looping through Dictionary C Dictionary When to Use C Dictionary Using Dicti
  • Unity的C#编程教程_52_类 Class 详解及应用练习(一)

    文章目录 C Classes for Behaviours Custom Classes 1 Custom Classes 2 Serialized Custom Class RPG Item Database Example 3 When
  • Unity InputSystem 实现同一按键单击、双击、长按执行不同逻辑

    最近学习了一下Unity InputSystem 该系统可用于实现 管理复杂的操作逻辑 上限很高 但由于它有一定的学习成本 导致一些和我一样的小白一入门时不得要领 之前卡住我的一个需求就是通过InputSystem 实现同一按键单击 双击
  • unity3D期末作业捕鱼游戏,适合初学者学习使用,包含源程序所有文件

    虚拟现实期末作业捕鱼游戏 免积分下载 点我下载资源 有按钮 背景音乐 可以发射炮弹捕鱼 可以选择难度 可以调节音乐声音大小 有游戏加载进度条 详细情况请看如下动态图 点我下载资源
  • Animator之RootMotion

    Unity3D 中 Generic 动画导入设置和 Root Motion 之间的关系 Unity3D 的 Mecanim 动画系统可以直接复用 3DS MAX 中制作的动画文件中的位移 这个就是通过 applyRootMotion 来达成
  • unity中通过touch旋转、放大和缩小物体以及滑动方向的判断

    unity中通过touch旋转 放大和缩小物体以及滑动方向的判断这个需求在游戏开发中也是非常频繁 话不多说直接上代码 using System Collections using System Collections Generic usi
  • Unity3D中通过代码修改子物体层级的顺序

    今天有个同事问我如何在程序中修改子物体的层级关系来改变遮挡关系 我给他敲出来一句代码 UI的层级关系是通过渲染表现出来的 在canvas下的物体 排序越靠前的越先被渲染 这样一来就会 被后来渲染的遮挡 总结一下有三句代码是修改子物体的层级的
  • 也想做一个绝地求生版的汽车控制移动,进来瞧瞧?(干货满满)

    控制车子移动 效果图附上 1 首先4个车轮复制一遍为车轮2备用 2 给车轮2全部添加wheel collider 只剩下车轮碰撞器和transform组件 3 给原版4个车轮添加脚本wheel 变量共有 面板赋值 依次添加车轮2里面的车轮c
  • 闲云:unity中不能识别monobehevior关键字的问题

    有时候一些小问题很恼人 如unity中新建脚本后不能识别monobehevior关键字 在vs2017右侧的解决方案中点击刷新图标 或者把不能识别的脚本添加到vs2017右侧的解决方案中的Assets中即可 还不行就点击 排除 然后再 添加
  • JPush极光推送Unity插件iOS设备无法获取DeviceToken

    前言 最近在使用JPush进行极光推送 Unity插件GitHub地址https github com jpush jpush unity3d plugin 问题描述 但是发现了一个问题 按照官方文档操作 最终仍然无法获取DeviceTok
  • Unity使用Newtonsoft报错的解决方案

    文章目录 Unity 使用 Newtonsoft 报错的解决方案 问题描述 解决方法 方法一 使用 Unity 的 Package Manager 自动导入 方法二 访问 GitHub 下载 unitypackage 文件手动导入 Unit
  • Unity里清除Console控制台Log的函数

    Log输出部分转发来自 http blog sina com cn s blog 13c4bf4b40102wz0r html 在控制台输出中 是开发者常用到的一种函数 通过Debug类来实现 打印字符串 Debug Log log 如果有
  • Unity3D之Rigidbody

    目录 常用的Rigidbody属性和方法 rigidbody AddForce rigidbody AddTorque rigidbody velocity rigidbody angularVelocity rigidbody Sleep
  • unity中的一些快捷键(齐)

    重命名的快捷键是F2 ALT 鼠标左键点击Hierarchy对象可以展开和收起对象的所有子物体 SHIFT 空格 可以对当前窗口进行放大缩小
  • 对Unity3D 静态批处理和动态批处理的理解

    Draw Call就是CPU调用图像编程接口 像OpenGL或者 DirectX 简单来说 Draw Call就是由CPU发起的一个命令 添加到一个命令缓冲区 当GPU完成了上一次的渲染任务之后 会从命令缓冲区的命令队列中再取出一个并执行
  • Unity中UI组件

    一 Canvers 画布组件 Canvers下面是添加Button和Image组件 Rect Transform 1 Position 坐标位置 2 Width Height 高宽尺寸 3 Anchors 锚点 4 Pivot中心点 即UI
  • Unity3d获得android和ios设备的唯一标识

    android为mac地址 ios为advertisingIdentifier 函数都比较简单 网上也搜得到 我也就不多说了 主要是对于我们没做过安卓和IOS开发的人来说 整合进工程有各种的问题 我也就直接上网盘了点击打开链接 代码包里看得
  • Unity3d + NGUI 的多分辨率适配

    移动端的多机型适配 现在要介绍的是 锁链战记 这款游戏的适配方法 这种适配方法是UI是一个基础尺寸 背景是一个基础尺寸 背景比UI多出的部分是一些没有实际作用的部分 这样的适配方式避免了在iPhone5这样的小屏幕上镶边 首先设定UIRoo

随机推荐

  • 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