Aseprite工具入门教程4之动画导入Unity

1、时间轴功能

(1)眼睛图标

  • 显示/隐藏图层
  • 图层隐藏时无法绘制

(2)锁定图标

  • 锁定后无法移动或编辑图层
  • 防止意外在错误图层上绘制

(3)单元格图标

两个点代表帧分开,一个椭圆代表帧统一。分开就是每一帧是单独的单元格,统一就是所有帧形成一个单元格。

【做法演示】

添加第一层kuangjia,此时什么也没有。

点击第一层的统一单元格。

点击第一层的第一帧,然后画一个矩形外框

选中第一层的第1~3帧,右击后选择Link Cels。

选择完毕后如下图所示,此时执行动画,所有帧都会显示该框架。

(4)时间线设置图标

(5)洋葱皮图标

打开该功能,可以看到前后一帧的信息,便于制作连续动画。

2、添加标签

(1)作用

用于组织和管理动画帧或图层,有助于将动画序列分组。

当从aseprite导出动画到Unity时,如果正确设置了标签,Unity可以识别并根据这些标签自动切分动画片段,而无需手动进行切分。

在Unity的Animator中,可以基于Aseprite中的标签来创建动画状态机的状态。例如,如果在Aseprite中有一个角色攻击动作的标签,那么在Unity中可以直接将其作为一个独立的状态来设置过渡逻辑。

(2)添加方法

选择帧:首先,在时间轴上选择你想要标记的帧范围。

添加标签:然后,点击菜单栏中的"层"(Layer)> "添加标签"(Add Tag)。

命名标签:在弹出的对话框中输入你的标签名称,然后点击"确定"。

添加完成后如下图所示:

3、动画制作操作方法

(1)复制帧到结尾

在结尾添加空白帧,

选择帧Ctrl + C,然后点击结尾的空白帧Ctrl+V

那么在结尾帧之前就会粘贴刚才被复制的那一帧。

(2)角色的pivot

标记出pivot,可以保持角色相对pivot的位置不变。

创建新的Layer,在第一帧标记出pivot,单元格图标选择椭圆后再右击Link Cels。

后续所有的帧中角色pivot的位置都保持不变。

4、Aseprite导入Unity方法1

(1)导入方法

Ase的内容如下:

在Unity的Assets下创建Resources目录,直接将ase文件拖到该目录下,在右下角可以看到4个动画。

将Assets -> Resources下的huochairen拖到Hierarchy -> Scene下重命名为Player。

将默认的Scene修改为PersistentScene。

点击Window -> Animation -> Animator调出状态机界面如下,默认情况下已经有状态机信息。

右击Entry通过"Set StateMachine Default State" 设置默认的状态为idle。

重新保存后没有生效,我们看到重新保存后报错了。

报错信息:Failed to load 'D:/workspace/unity/tengxuncloud/huochairen/HuoChaiRen/Assets/Resources/huochairen2.ase'. File may be corrupted or was serialized with a newer version of Unity.

UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)

其实是因为Aseprite自动生成的这个animator是只读的,你不能够对它进行任何的操作。

(2)修改Unity的Animator的方法

点击Assets中的ase文件,点击Export Animation Assets。

此时就会生成controller文件。

后续修改就会生效,仍然保持和已有动画tag的同步,但不能读取新增的动画tag。

Export animation assets,勾选animation clips可以导出动画,但是不能和aseprite文件保持同步。

5、Aseprite导入Unity方法2

(1)导入方法

制作完成后,点击File -> Export Sprite Sheet,相关配置如下:

此时在aseprite下工作目录下就出现了png图片。

将该png放到Assets/Resources目录下,点击png文件修改参数如下,完成后点击"Apply"。

再次点击Inspector中的Sprite Editor。

Type选择"Grid By Cell Size",配置Pixel Size,该值是Aseprite中画布的大小。

点击Slice -> Apply。

在Hierarchy -> PersistentScene下新建空物体命名为Player,并且设置默认图片如下:

(2)创建Animation Clip

在Animation下点击Create

创建anim文件如下:

创建完毕后就会自动生成Player.Controller文件。

将帧图片拖到Animation界面中如下:

点击Create New Clip创建新的动画clip。

如果有3帧则分别拖入如下:

所有动画创建完毕后如下:

(3)创建Animator状态机(错误的历史版本)

编写脚本如下:

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;

public class Player : MonoBehaviour
{
    private Rigidbody2D rigidbody;
    private Animator animator;


    private float xInput;
    private float yInput;
    private bool isDirectionLeft = false;
    private bool isDirectionRight = false;

    private float moveSpeed;

    // Start is called before the first frame update
    void Start()
    {
        rigidbody = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        HandlePlayerInput();
    }


    private void FixedUpdate()
    {
        PlayerMove();
    }

    private void PlayerMove()
    {
        moveSpeed = Settings.moveSpeed;
        Vector2 move = new Vector2((float)(xInput * moveSpeed * Time.deltaTime), 0);
        rigidbody.MovePosition(rigidbody.position + move);
    }

    public void HandlePlayerInput()
    {
        xInput = Input.GetAxisRaw("Horizontal");
        if (xInput != 0)
        {
            if(xInput < 0)
            {
                animator.SetFloat("xInput", xInput);
                animator.SetTrigger("is_walk_left");
                isDirectionLeft = true;
                isDirectionRight = false;
            }
            else
            {
                animator.SetFloat("xInput", xInput);
                animator.SetTrigger("is_walk_right");
                isDirectionLeft = false;
                isDirectionRight = true;
            }
        }


        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (isDirectionLeft) {
                animator.SetTrigger("is_idle_left");
                animator.SetTrigger("is_battle_left");
            }
            else
            {
                animator.SetTrigger("is_idle_right");
                animator.SetTrigger("is_battle_right");
            }
        }

    }
}

该状态机设计会出现反应迟钝的现象。

(4)创建Animator状态机(正确)

编写脚本如下:

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;

public class Player : MonoBehaviour
{
    private Rigidbody2D rigidbody;
    private Animator animator;


    private float xInput;
    private float yInput;
    private bool isWalking;
    private bool isDirectionRight;


    private float moveSpeed;

    // Start is called before the first frame update
    void Start()
    {
        isDirectionRight = true;
        rigidbody = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        HandlePlayerInput();
    }


    private void FixedUpdate()
    {
        PlayerMove();
    }

    private void PlayerMove()
    {
        moveSpeed = Settings.moveSpeed;
        Vector2 move = new Vector2((float)(xInput * moveSpeed * Time.deltaTime), 0);
        rigidbody.MovePosition(rigidbody.position + move);
    }

    public void HandlePlayerInput()
    {
        // 获取水平输入:-1(左),0(无输入),1(右)
        xInput = Input.GetAxisRaw("Horizontal");
        

        // 判断是否正在移动
        isWalking = Mathf.Abs(xInput) > 0.5f;

        Debug.Log("xInput:" + xInput + "   isWalking:" + isWalking + "   isDirectionRight:" + isDirectionRight);

        // 设置方向参数:0 表示向右,1 表示向左
        if(xInput < 0)
        {
            isDirectionRight = false;
        }
        else if(xInput > 0)
        {
            isDirectionRight = true;
            
        }

        if (isDirectionRight)
        {
            animator.SetInteger("direction", 0); // 右边
        }
        else
        {
            animator.SetInteger("direction", 1); // 左边
        }


            // 设置是否行走
            animator.SetBool("isWalking", isWalking);

        // 触发战斗
        if (Input.GetKeyDown(KeyCode.Space))
        {
            animator.SetTrigger("isBattling");
        }
    }
}