一键自动状态机复用

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(使用前将#替换为@)

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

  • Unity3D研究院之游戏开发中的人工智能AI

    人工智能这个东西在游戏中是非常重要的 人工智能说简单了就是根据随机的数字让敌人执行一些动作或逻辑 说难了TA需要一个非常复杂的算法 本文我主要说说Unity3D中人工智能的脚本如何来编写 首先你应该搞清楚的一点AI脚本属于一个工具类脚本 工
  • Unity3D C#数学系列之点积

    文章目录 1 定义 2 几何意义 3 向量a 向量b xaxb yayb zazb 4 应用案例 4 1 求两向量的夹角 4 2 判断两向量是否垂直 4 3 判断NPC是否在攻击范围内 4 4 已知入射光线和表面法线求反射光线 5 项目 1
  • 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
  • unity多个贴图shader

    在一个Material上放多个贴图的测试 比如一个plane上放四个贴图 Shader aaa Properties MainTex Texture 2D white MainTex2 Texture 2D white MainTex3 T
  • Unity_场景之间的跳转

    跳转场景之前 需要在 File gt Build Settings gt Add Open Scenes 或者 直接把 场景 拖拽进来 跳转场景方法1 已过时 跳转场景方法 public void OnStartGame string Sc
  • Unity+Pico 手柄按键控制

    一 定义手柄按键API 1 InputDevices GetDeviceAtXRNode 通过XRNode获取对应的设备 2 XRNode是一个枚举类型 包含LeftEye RightEye CenterEye Head LeftHand
  • untiy的纹理格式介绍

    Desktop RGB Compressed DXT1 压缩的RGB纹理 这是最常见的漫反射纹理格式 4位 像素 32 KB 256x256 RGBA Compressed DXT5 压缩的RGBA纹理 这是漫反射和高光控制纹理的主要格式
  • HLSL 偏导数 ddx / ddy

    HLSL ddx ddy 在光栅化的时刻 GPUs会在同一时刻并行运行很多Fragment Shader 但是并不是一个pixel一个pixel去执行的 而是将其组织在2x2的一组pixels分块中 去并行执行 偏导数就正好是计算的这一块像
  • Unity编辑器扩展——进度条显示通用方法

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

    Input inputString 获取输入的文字 正在打的中文是接受不到的 只有在文字写到文本框才能获取 Input imeCompositionMode 是否是激活输入框状态 on 是 Input compositionString 空
  • 【Unity灯光与渲染技术】Global Illumination全局光照

    本系列主要参考Unity灯光与渲染技术教程Unity Lighting And Rendering 同时会加上一点个人实践过程和理解 分割线 这篇文章主要讲全局光照 在看教程的时候就有一个点不是很理解 就是作者开启物体的static这个选项
  • 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 Engine Architecture

    原文 http www umingo de doku php id paper mechs and tanks section03 Architecture To better understand the game s software
  • Unity3d 插件 系列——DoTweenPro介绍(图文详细+案例)

    Unity3d 插件 系列 DoTweenPro介绍 图文详细 案例 前言 一 DoTweenPro简介 二 DoTweenPro安装 三 DoTweenPro主要组件 1 DoTweenAnimation 2 DoTweenPath 3
  • unity的LOD组件

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

    1 World Space 世界坐标 我们在场景中添加物体 如 Cube 他们都是以世界坐标显示在场景中的 transform position可以获得该位置坐标 2 Screen Space 屏幕坐标 以像素来定义的 以屏幕的左下角为 0
  • Unity3d + NGUI 的多分辨率适配

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