一键自动状态机复用

2023-11-03

@一键自动状态机复用

代码块

using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;

public class ImportAnimConWindow : EditorWindow
{
    string animConPath;         //需要复制动画状态机的位置
    string animClipPath;        //动画片段的位置
    static ImportAnimConWindow myWindow;
    static Dictionary<string, ImportAnimConClass> AllState = new Dictionary<string, ImportAnimConClass>();

    [@MenuItem("ProjectC/ImportAnimConWindow", false, 14)]
    private static void Open()
    {
        myWindow = GetWindow<ImportAnimConWindow>();
        myWindow.Show();
    }

    private void OnGUI()
    {
        animConPath = EditorGUILayout.TextField("动画状态机位置:", animConPath);
        if (GUILayout.Button("选择动画状态机相对位置", GUILayout.Width(160)))
        {
            var targetDir = new DirectoryInfo(string.Format(Application.dataPath + @"\Anim")); //相对与Assets的相对路径
            string path1 = EditorUtility.OpenFilePanel("选择需要生成的动画", targetDir.FullName.Replace("\\", "/"), "controller"); //选择.controller 文件
            if (string.IsNullOrEmpty(path1))
                return;
            animConPath = path1;
        }
        animClipPath = EditorGUILayout.TextField("动画片段位置:", animClipPath);
        if (GUILayout.Button("选择动画片段位置", GUILayout.Width(160)))
        {
            var targetDir = new DirectoryInfo(string.Format(Application.dataPath + @"\Anim"));//相对与Assets的相对路径
            string path1 = EditorUtility.OpenFolderPanel("Load Folder", targetDir.FullName.Replace("\\", "/"), "选择动画片段");//选择文件夹文件
            if (string.IsNullOrEmpty(path1))
                return;
            animClipPath = path1;
        }

        if (GUILayout.Button("生成动画状态机"))
        {
            Debug.LogError("点击生成动画状态机");
            if (animConPath == null || animClipPath == null)
            {
                Debug.LogError("请填充相对应的位置");
                return;
            }
            //获取新动画放置目录
            var targetDir = new DirectoryInfo(string.Format(@"{0}\..\", animClipPath));  //获取动画片段同目录下
            string animConFullPath = animConPath.Substring(animConPath.IndexOf("Assets/"));
            string[] fullNum1 = animConFullPath.Split('/');
            string[] half_Name = fullNum1[fullNum1.Length - 1].Split('_');
            //AnimatorController animationClip = (AnimatorController)AssetDatabase.LoadAssetAtPath(animConFullPath, typeof(AnimatorController));
            string copyPath = string.Format(@"{0}{1}_{2}", targetDir.FullName, targetDir.Name, half_Name[half_Name.Length - 1]);//生成的新的动画状态机位置名字
            File.Copy(animConPath, copyPath, true);  //复制并移动新的目录下
            AssetDatabase.Refresh();                 //刷新

            string copyFullPath = copyPath.Substring(copyPath.IndexOf("Assets\\"));
            //获取新复制的动画状态机
            AnimatorController animationClip = (AnimatorController)AssetDatabase.LoadAssetAtPath(copyFullPath, typeof(AnimatorController));

            DirectoryInfo direction = new DirectoryInfo(animClipPath);
            FileInfo[] files = direction.GetFiles("*.anim", SearchOption.AllDirectories);  //获取动画片段
            AllState.Clear();                                                              //清空本地缓存
            for (int i = 0; i < files.Length; i++)
            {
                Debug.Log("Name:" + files[i].Name);
                FileInfo file = files[i];
                string fileName = file.Name.Substring(0, file.Name.IndexOf("."));
                string fullName = file.FullName.Substring(file.FullName.IndexOf("Assets\\"));
                string[] fileNum = fileName.Split('_');
                string file_Name = fileNum[fileNum.Length - 1];
                AnimationClip clip = (AnimationClip)AssetDatabase.LoadAssetAtPath(fullName, typeof(AnimationClip));
                AllState.Add(file_Name, new ImportAnimConClass                             //按照动画实际作用名称来保存本地
                {
                    fullName = fileName,
                    clip = clip
                });
            }

            for (int i = 0; i < animationClip.layers.Length; i++)                            //获取动画状态机层级
            {
                for (int j = 0; j < animationClip.layers[i].stateMachine.states.Length; j++) //动画状态机层级的片段
                {
                    var state = animationClip.layers[i].stateMachine.states[j].state;
                    //根据动画片段名字来查找
                    string[] strNum = state.name.Split('_');                                 //实际动画名称来查找
                    string state_HalfName = strNum[strNum.Length - 1];
                    if (AllState.ContainsKey(state_HalfName))
                    {
                        state.motion = AllState[state_HalfName].clip;
                        state.name = AllState[state_HalfName].fullName;
                    }
                    else
                    {
                        Debug.LogError(string.Format("未找到相关动画片段:{0}", state.name));
                    }
                }
            }
            Close();
        }
    }
}

public class ImportAnimConClass
{
    public string fullName;
    public AnimationClip clip;
    public ImportAnimConClass()
    {
    }
}

注意事项

1:动画片段名字和动画状态机的名字保持部分一致性;如Characters001_Theme001_Watering 和 Characters002_Theme001_Watering ;
保持Watering一致性;
2:复制的动画状态机和原本的动画状态机路径名字不可保持一致;

包体资源下载

https://download.csdn.net/download/Zjl956321111/20665674

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

一键自动状态机复用 的相关文章

  • Unity集成Leap Motion

    转载自 http www cocoachina com game 20150716 12625 html 演示视频文章最后 如果你已经熟悉编程的概念 理解并在C 语言方面有一定的经验 并且对面向对象编程思想和设计概念有所熟悉 如果你了解3D
  • Unity的C#编程教程_59_字典 Dictionary 详解及应用练习

    文章目录 C Dictionary Introduction C Dictionary Looping through Dictionary C Dictionary When to Use C Dictionary Using Dicti
  • Unity之Animation动画

    Unity之Animation动画 Unity之Animation绘制动画 这篇文章做最简单的动画 让一个立方体从左边移动到右边 1 创建一个Unity的新工程 名为TestAnimation 点击Create And Open按键 打开工
  • URP——后期处理特效

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

    代码 var v Input GetAxis Vertical var h Input GetAxis Horizontal transform Translate transform forward Time deltaTime move
  • Unity3d中使用OnGUI()函数判断“键盘按下抬起”功能的新方法。

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

    今天有个同事问我如何在程序中修改子物体的层级关系来改变遮挡关系 我给他敲出来一句代码 UI的层级关系是通过渲染表现出来的 在canvas下的物体 排序越靠前的越先被渲染 这样一来就会 被后来渲染的遮挡 总结一下有三句代码是修改子物体的层级的
  • Unity Cinemachine插件学习笔记,实现单目标和多目标之间切换

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

    Desktop RGB Compressed DXT1 压缩的RGB纹理 这是最常见的漫反射纹理格式 4位 像素 32 KB 256x256 RGBA Compressed DXT5 压缩的RGBA纹理 这是漫反射和高光控制纹理的主要格式
  • Unity笔记:修改代码执行的默认打开方式

    使用 External Tools 偏好设置可设置用于编写脚本 处理图像和进行源代码控制的外部应用程序 External Script Editor 选择 Unity 应使用哪个应用程序来打开脚本文件 Unity 会自动将正确的参数传递给内
  • Unity编辑器扩展——进度条显示通用方法

    在我们使用Unity编辑器扩展做一些批处理的工具时 通常会需要显示一个进度条 这样不会让Unity一直卡住不动 使得使用者不知道当前的进展 那么如何显示进度条呢 涉及的相关API有 EditorUtility ClearProgressBa
  • RAIN{INDIE} 自动寻路

    Unity游戏中有较多的自动寻路插件 看过几个 大同小异 而RAIN中的Behavior Tree感觉很好 听名字就知道很条理 下面 就用它做个简单的寻路小例子 首先 导入RAIN的包 结构如下 在使用的过程当中还会产生几个文件夹用来存放E
  • Unity3D 官方文档 平台特殊化之Standalone和多显示器的处理

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

    目录 常用的Rigidbody属性和方法 rigidbody AddForce rigidbody AddTorque rigidbody velocity rigidbody angularVelocity rigidbody Sleep
  • Unity3D如何修改Button显示的文字以及深入了解Button组件

    在创建了一个Button后 结构如图 先仔细观察一下Button的Inspector视图 发现其中竟然有一个叫Button的脚本组件 新建脚本 代码如下 并将该脚本绑定给Canvas组件 using UnityEngine UI using
  • [3dsMax]2018版下拉菜单项的子菜单无法选中

    软件自身问题 安装更新补丁即可解决 不想更新补丁也可以使用键盘的方向键进行选中 补丁百度云链接 https pan baidu com s 1LDxRFwQnR0GSONuz7wcEfA 提取码 6gpk
  • Unity3D:按键生成物件,Instantia…

    在按下按键之后 可以在画面中生成之前定义好了的物体 这里使用了Instantiate函数来生成 1 先在游戏中定一个空物件GameObject 创建空物件快捷键 ctrl shift n 2 在视图中放置 3 编写脚本 脚本 SpaceCh
  • Unity3d 插件 系列——DoTweenPro介绍(图文详细+案例)

    Unity3d 插件 系列 DoTweenPro介绍 图文详细 案例 前言 一 DoTweenPro简介 二 DoTweenPro安装 三 DoTweenPro主要组件 1 DoTweenAnimation 2 DoTweenPath 3
  • java中Keytool的使用总结

    java中Keytool的使用总结 2011 02 26 15 30 15 分类 在申请Android Map API Key的时候使用到了java中Keytool 下面转一篇介绍java中Keytool的文章 http blog csdn
  • Unity在UI界面上显示3D模型/物体,控制模型旋转

    https blog csdn net ChinarCSDN article details 81058773

随机推荐

  • 16位片内地址的I2C SLAVE接口设计

    8位片内地址的I2C SLAVE在OPENCORS org上面有 但是我没有找到16位的 我打算用B210的接EEPROM的I2C总线实现跟FPGA通讯就对照24C256的数据手册写了一个 以下代码2022 6 6更新已经实际运行通过 i2
  • YOLOv5——报错解决:UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xb2 in position 6:invalidstartbyte

    在提示报错的torch utils py文件58行 将原来的decode 改成decode encoding gbk
  • 一文读懂伪回归、协整、格兰杰

    一 什么叫做伪回归 若是所建立的回归模型在经济意义上没有因果关系 那么这个就是伪回归 例如路边小树年增长率和国民经济年增长率之间存在很大的相关系数 但是建立的模型却是伪回归 如果你直接用数据回归 那肯定存在正相关 而其实这个是没有意义的回归
  • 【AI实战】最强开源 6B 中文大语言模型ChatGLM2-6B,从零开始搭建

    AI实战 最强开源 6B 中英文大语言模型ChatGLM2 6B 从零开始搭建 ChatGLM2 6B 简介 ChatGLM2 6B 评测结果 ChatGLM2 6B 搭建 参考 ChatGLM2 6B 简介 ChatGLM2 6B 是开源
  • 区块链相关概念与简介

    摘要 2017 2018年 互联网界最火热的话题之一就是区块链 各大公司相继宣布对区块链方面的投资和开发 各大互联网公司也前后推出自己区块链产品 例如阿里的麻吉宝 百度的莱次狗 腾讯的TrustSQL等等 那么区块链到底是什么 本文简单介绍
  • strace 命令来查看系统调用

    strace p pid strace p pid i i 显示函数地址
  • Android Service两种启动方式

    1 Context startService 方式启动 Context startService 方式的生命周期 启动时 startService gt onCreate gt onStart 可多次调用 Service running 停
  • 并发编程集合

    转载自郑金维老师 一 synchronized 一 原子性 有序性 可见性 1 1 原子性 数据库的事务 ACID A 原子性 事务是一个最小的执行的单位 一次事务的多次操作要么都成功 要么都失败 并发编程的原子性 一个或多个指令在CPU执
  • AutoSAR系列讲解(实践篇)7.7-实验:配置SWC&RTE(下)

    AutoSAR系列讲解 实践篇 7 7 实验 配置SWC RTE 下 实验 配置SWC RTE 下 三 步骤二 配置Runnable及其Tasks映射 1 添加及配置Runnable 2 打开Cfg并同步工程 3 导入DBC文件 4 创建T
  • 一图读懂FISCO BCOS MVP计划

    点击填写FISCO BCOS MVP申请表 问卷系统 了解更多干货内容 请关注FISCO BCOS开源社区公众号 访问FISCO BCOS代码仓库可下载项目所有源代码 https github com FISCO BCOS FISCO BC
  • 从连续时间傅里叶级数到快速傅里叶变换

    在计算机上编程做信号处理时 我们通常用的是FFT 但是开始学信号处理时 一般是从FS开始的 所以这里整理一下从FS到FFT 演变 的过程 以下是傅里叶 家族 的一些名称 FS Fourier Series 连续时间周期信号的傅里叶级数 FT
  • GET请求,接收多个对象参数

    非常简单 如下 GetMapping test public void test String name City city 省略 还没看懂 详细解释一下 例如City类有id describe字段 Data public class Ci
  • STM32F407写超声波传感器HC-SR04程序

    1 给超声波模块接入电源和地 2 给trig输入一个长为20us的高电平方波 3 输入方波后 模块会自动发射8个40KHz的声波 echo的电平会由0变为1 4 当超声波返回被模块接收到时 回波引 脚端的电平会由1变为0 定时器记下的这个时
  • 开发场景运维操作命令

    uname a 查看内核 操作系统 CPU信息的linux系统信息命令 head n 1 etc issue 查看操作系统版本 是数字1不是字母L cat proc cpuinfo 查看CPU信息的linux系统信息命令 hostname
  • 【gperftools】使用gperftools分析

    文章目录 使用gperftools分析 配置环境 Demo 使用gperftools分析 配置环境 perftools http code google com p gperftools downloads list libunwind h
  • 常用HTML标签属性

    跑马灯
  • python基础_包引入,OS模块和异常处理

    包引入 库 提供一系列的功能 1 内置库 包 不需要安装可以直接使用 安装路径在 Lip 2 第三方库 包 先pip安装在使用 安装路径在 Lip site packages 3 自定义的模块 包 有2种 a 同级目录 import 模块名
  • 「第六篇」对于电赛,我们应该看重什么?

    这几天更新了一些关于电赛的帖子 有设计方案 也有一些经验贴 大家可以在下面的链接找到 第一篇 大学生电子设计竞赛 等你来提问 第二篇 全国一等奖 经验帖 第三篇 全国电子设计竞赛 这些你必须知道的比赛细节 文末附上近十年电赛题目下载 第四篇
  • 【学习】对于AndroidStudio 中 Local History还原文件的理解

    1 理解结果 2 理解过程 2016年7月21日 星期四 因为很少使用AS的LocalHistory 所以对LocalHistory的不怎么理解 平时也就是拿来看看旧的代码 但是今天在使用LocalHistory的时候出了一个问题 就是在P
  • 一键自动状态机复用

    一键自动状态机复用 代码块 using System Collections Generic using System IO using UnityEditor using UnityEditor Animations using Unit