【unity游戏开发——编辑器扩展】AssetDatabase公共类在编辑器环境中管理和操作项目中的资源

注意:考虑到编辑器扩展的内容比较多,我将编辑器扩展的内容分开,并全部整合放在【unity游戏开发——编辑器扩展】专栏里,感兴趣的小伙伴可以前往逐一查看学习。

文章目录

  • 前言
  • 一、AssetDatabase常用API
    • 1、创建资源
      • 1.1 API
      • 1.2 示例
    • 2、创建文件夹
      • 2.1 API
      • 2.2 示例
    • 3、拷贝资源
      • 3.1 API
      • 3.2 示例
    • 4、移动资源
      • 4.1 API
      • 4.2 示例
    • 5、删除资源
      • 5.1 API
      • 5.2 示例
    • 6、批量删除资源
      • 6.1 API
      • 6.2 示例
    • 7、获取资源路径
      • 7.1 API
      • 7.2 示例
    • 8、根据路径加载资源
      • 8.1 API
      • 8.2 示例
    • 9、刷新项目资源
      • 9.1 API
      • 9.2 示例
    • 10、返回资源所属的AB包名
      • 10.1 API
      • 10.2 示例
  • 二、最终代码
  • 专栏推荐
  • 完结

前言

AssetDatabase公共类是 Unity 引擎中的一个编辑器类,用于在编辑器环境中管理和操作项目中的资源(Assets)。它提供了一系列静态方法,使得开发者能够在编辑器脚本中进行资源的创建、拷贝、移动、删除等操作。

官方文档:AssetDatabase

一、AssetDatabase常用API

1、创建资源

1.1 API

我们可以通过代码动态创建一些资源

AssetDatabase.CreateAsset(资源,路径);

注意

  • 路径从 Assets/...开始
  • 不能在StreamingAssets中创建资源,
  • 不能创建预设体
  • 只能创建资源相关,例如材质球等
  • 路径需要写后缀

1.2 示例

using UnityEditor;
using UnityEngine;public class TestAssetDatabaseEditorWindow : EditorWindow
{[MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]private static void OpenWindow(){TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();win.Show();}private void OnGUI(){// 创建资源按钮if (GUILayout.Button("创建资源")){// 创建一个材质,使用URP的Lit着色器Material mat = new Material(Shader.Find("Universal Render Pipeline/Lit"));// 将材质保存为Assets/Resources/TestURPLitMaterial.matAssetDatabase.CreateAsset(mat, "Assets/Resources/TestURPLitMaterial.mat");}}
}

效果
在这里插入图片描述

2、创建文件夹

2.1 API

AssetDatabase.CreateFolder(父文件夹路径,新文件夹名)

注意

  • 父文件夹路径从 Assets/...开始

2.2 示例

using UnityEditor;
using UnityEngine;public class TestAssetDatabaseEditorWindow : EditorWindow
{[MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]private static void OpenWindow(){TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();win.Show();}private void OnGUI(){// 创建文件夹按钮if (GUILayout.Button("创建文件夹")){// 在Assets/Resources下创建一个名为MyTestFolder的文件夹AssetDatabase.CreateFolder("Assets/Resources", "MyTestFolder");}}
}

效果
在这里插入图片描述

3、拷贝资源

3.1 API

AssetDatabase.CopyAsset(源资源路径,目标路径)

注意

  • 需要写后缀名
  • 路径从 Assets/...开始

3.2 示例

using UnityEditor;
using UnityEngine;public class TestAssetDatabaseEditorWindow : EditorWindow
{[MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]private static void OpenWindow(){TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();win.Show();}private void OnGUI(){// 拷贝资源按钮if (GUILayout.Button("拷贝资源")){// 将Assets/Resources/TestURPLitMaterial.mat拷贝到Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.matAssetDatabase.CopyAsset("Assets/Resources/TestURPLitMaterial.mat", "Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.mat");}}
}

效果
在这里插入图片描述

4、移动资源

4.1 API

AssetDatabase.MoveAsset(老路径, 新路径);

注意

  • 路径从 Assets/...开始

4.2 示例

using UnityEditor;
using UnityEngine;public class TestAssetDatabaseEditorWindow : EditorWindow
{[MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]private static void OpenWindow(){TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();win.Show();}private void OnGUI(){// 移动资源按钮if (GUILayout.Button("移动资源")){// 将Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.mat移动到Assets/Resources/TestURPLitMaterialCopy.matAssetDatabase.MoveAsset("Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.mat","Assets/Resources/TestURPLitMaterialCopy.mat");}}
}

在这里插入图片描述

5、删除资源

5.1 API

AssetDatabase.DeleteAsset(资源路径)

注意

  • 路径从 Assets/...开始

5.2 示例

using UnityEditor;
using UnityEngine;public class TestAssetDatabaseEditorWindow : EditorWindow
{[MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]private static void OpenWindow(){TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();win.Show();}private void OnGUI(){// 删除资源按钮if (GUILayout.Button("删除资源")){// Assets/Resources/TestURPLitMaterialCopy.matAssetDatabase.DeleteAsset("Assets/Resources/TestURPLitMaterialCopy.mat");}}
}

效果
在这里插入图片描述

6、批量删除资源

6.1 API

AssetDatabase.DeleteAssets(string[] 路径们, List<string> 用于存储删除失败的路径)

注意

  • 路径从 Assets/...开始

6.2 示例

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;public class TestAssetDatabaseEditorWindow : EditorWindow
{[MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]private static void OpenWindow(){TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();win.Show();}private void OnGUI(){// 批量删除资源按钮if (GUILayout.Button("批量删除资源")){// 创建一个列表,用于存储删除失败的资源List<string> failList = new List<string>();// 批量删除Assets/Resources/TestURPLitMaterial.mat和Assets/Resources/TestURPLitMaterial2.matAssetDatabase.DeleteAssets(new string[] { "Assets/Resources/TestURPLitMaterial.mat", "Assets/Resources/TestURPLitMaterial2.mat" }, failList);// 遍历删除失败的资源列表,并输出到控制台for (int i = 0; i < failList.Count; i++){Debug.Log(failList[i]);}}}
}

效果
在这里插入图片描述

7、获取资源路径

7.1 API

AssetDatabase.GetAssetPath(资源)

注意

  • 可以配合Selection选中资源一起使用

7.2 示例

using UnityEditor;
using UnityEngine;public class TestAssetDatabaseEditorWindow : EditorWindow
{[MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]private static void OpenWindow(){TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();win.Show();}private void OnGUI(){// 获取资源路径按钮if (GUILayout.Button("获取资源路径")){// 输出当前选中的资源的路径Debug.Log(AssetDatabase.GetAssetPath(Selection.activeObject));}}
}

效果
在这里插入图片描述

8、根据路径加载资源

8.1 API

AssetDatabase.LoadAssetAtPath(资源路径) 

注意

  • 路径从Assets/...开始

8.2 示例

using UnityEditor;
using UnityEngine;public class TestAssetDatabaseEditorWindow : EditorWindow
{[MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]private static void OpenWindow(){TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();win.Show();}private void OnGUI(){// 加载资源按钮if (GUILayout.Button("加载资源")){// 加载Assets/测试文件.txt,并输出其名称TextAsset txt = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/测试文件.txt");Debug.Log(txt.name);}}
}

效果
在这里插入图片描述

9、刷新项目资源

9.1 API

AssetDatabase.Refresh()是Unity编辑器API中的一个重要方法,用于刷新项目资源数据库。当你在Unity项目文件夹中添加、删除或修改资源文件时,这个方法可以确保Unity编辑器能够识别这些更改。

AssetDatabase.Refresh()

Unity通常会自动在适当时候调用刷新,但有时需要手动触发。比如当你通过代码创建或修改了资源文件,需要执行刷新,我们才能在Project窗口中显示最新的内容,否则每次都需要手动调用ctrl+R刷新,这个API其实就是帮我们省略手动刷新这一步。

9.2 示例

using System.IO;
using UnityEditor;
using UnityEngine;public class TestAssetDatabaseEditorWindow : EditorWindow
{[MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]private static void OpenWindow(){TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();win.Show();}private void OnGUI(){// 创建文件并刷新资源按钮if (GUILayout.Button("创建文件并刷新资源")){// 创建文件时,如果不使用Unity相关API的话,需要调用刷新,才能在Project窗口中显示File.WriteAllText(Application.dataPath + "/Resources/test2.txt", "内容内容内容");AssetDatabase.Refresh();}}
}

效果
在这里插入图片描述

10、返回资源所属的AB包名

10.1 API

string bundleName = AssetDatabase.GetImplicitAssetBundleName(资源路径);

注意

  • 路径从Assets/...开始
  • 返回该资源隐式关联的AssetBundle名称(如果有的话)
  • 如果资源没有被分配到任何AssetBundle,返回空字符串(“”)

10.2 示例

using UnityEditor;
using UnityEngine;public class TestAssetDatabaseEditorWindow : EditorWindow
{[MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]private static void OpenWindow(){TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();win.Show();}private void OnGUI(){// 返回资源所属的AB包名按钮if (GUILayout.Button("返回资源所属的AB包名")){string assetPath = "Assets/Resources/MyPrefab.prefab";string bundleName = AssetDatabase.GetImplicitAssetBundleName(assetPath);if (!string.IsNullOrEmpty(bundleName)){Debug.Log($"资源 {assetPath} 属于AssetBundle: {bundleName}");}else{Debug.Log($"资源 {assetPath} 不属于任何AssetBundle");}}}
}

效果
在这里插入图片描述

二、最终代码

using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;public class TestAssetDatabaseEditorWindow : EditorWindow
{[MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]private static void OpenWindow(){TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();win.Show();}private void OnGUI(){// 创建资源按钮if (GUILayout.Button("创建资源")){// 创建一个材质,使用URP的Lit着色器Material mat = new Material(Shader.Find("Universal Render Pipeline/Lit"));// 将材质保存为Assets/Resources/TestURPLitMaterial.matAssetDatabase.CreateAsset(mat, "Assets/Resources/TestURPLitMaterial.mat");}// 创建文件夹按钮if (GUILayout.Button("创建文件夹")){// 在Assets/Resources下创建一个名为MyTestFolder的文件夹AssetDatabase.CreateFolder("Assets/Resources", "MyTestFolder");}// 拷贝资源按钮if (GUILayout.Button("拷贝资源")){// 将Assets/Resources/TestURPLitMaterial.mat拷贝到Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.matAssetDatabase.CopyAsset("Assets/Resources/TestURPLitMaterial.mat", "Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.mat");}// 移动资源按钮if (GUILayout.Button("移动资源")){// 将Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.mat移动到Assets/Resources/TestURPLitMaterialCopy.matAssetDatabase.MoveAsset("Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.mat","Assets/Resources/TestURPLitMaterialCopy.mat");}// 删除资源按钮if (GUILayout.Button("删除资源")){// Assets/Resources/TestURPLitMaterialCopy.matAssetDatabase.DeleteAsset("Assets/Resources/TestURPLitMaterialCopy.mat");}// 批量删除资源按钮if (GUILayout.Button("批量删除资源")){// 创建一个列表,用于存储删除失败的资源List<string> failList = new List<string>();// 批量删除Assets/Resources/TestURPLitMaterial.mat和Assets/Resources/TestURPLitMaterial2.matAssetDatabase.DeleteAssets(new string[] { "Assets/Resources/TestURPLitMaterial.mat", "Assets/Resources/TestURPLitMaterial2.mat" }, failList);// 遍历删除失败的资源列表,并输出到控制台for (int i = 0; i < failList.Count; i++){Debug.Log(failList[i]);} }// 获取资源路径按钮if (GUILayout.Button("获取资源路径")){// 输出当前选中的资源的路径Debug.Log(AssetDatabase.GetAssetPath(Selection.activeObject));}// 加载资源按钮if (GUILayout.Button("加载资源")){// 加载Assets/测试文件.txt,并输出其名称TextAsset txt = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/测试文件.txt");Debug.Log(txt.name);}// 创建文件并刷新资源按钮if (GUILayout.Button("创建文件并刷新资源")){// 创建文件时,如果不使用Unity相关API的话,需要调用刷新,才能在Project窗口中显示File.WriteAllText(Application.dataPath + "/Resources/test2.txt", "内容内容内容");AssetDatabase.Refresh();}// 返回资源所属的AB包名按钮if (GUILayout.Button("返回资源所属的AB包名")){string assetPath = "Assets/Resources/MyPrefab.prefab";string bundleName = AssetDatabase.GetImplicitAssetBundleName(assetPath);if (!string.IsNullOrEmpty(bundleName)){Debug.Log($"资源 {assetPath} 属于AssetBundle: {bundleName}");}else{Debug.Log($"资源 {assetPath} 不属于任何AssetBundle");}}}
}

专栏推荐

地址
【unity游戏开发入门到精通——C#篇】
【unity游戏开发入门到精通——unity通用篇】
【unity游戏开发入门到精通——unity3D篇】
【unity游戏开发入门到精通——unity2D篇】
【unity实战】
【制作100个Unity游戏】
【推荐100个unity插件】
【实现100个unity特效】
【unity框架/工具集开发】
【unity游戏开发——模型篇】
【unity游戏开发——InputSystem】
【unity游戏开发——Animator动画】
【unity游戏开发——UGUI】
【unity游戏开发——联网篇】
【unity游戏开发——优化篇】
【unity游戏开发——shader篇】
【unity游戏开发——编辑器扩展】

完结

好了,我是向宇,博客地址:https://xiangyu.blog.csdn.net,如果学习过程中遇到任何问题,也欢迎你评论私信找我。

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/907837.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css实现文字渐变

在前端开发中&#xff0c;给文字设置渐变色是完全可以实现的&#xff0c;常用的方式是结合 CSS 的 background、-webkit-background-clip 和 -webkit-text-fill-color 属性。下面是一个常见的实现方法&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> …

WSL 开发环境搭建指南:Java 11 + 中间件全家桶安装实战

在WSL&#xff08;Windows Subsystem for Linux&#xff09;环境下一站式安装开发常用工具&#xff0c;能极大提升工作效率。接下来我将分步为你介绍如何在WSL中安装Java 11、Maven、Redis、MySQL、Nacos、RabbitMQ、RocketMQ、Elasticsearch&#xff08;ES&#xff09;和Node.…

vue3: baidusubway using typescript

项目结构&#xff1a; <!--npm install -D tailwindcss-3d BaiduSubwayMap.vue npm install -D tailwindcss postcss autoprefixer--> <template><div class"relative w-full h-screen"><!-- 地图容器 --><div id"subway-container…

【iptables防火墙】-- URL过滤 (Hexstring、IP、DoT和DoH)

在路由器中使用iptables工具对URL地址进行过滤涉及到如下几个方面&#xff0c;hexstring、ip、DoT和DoH。 以过滤www.baidu.com为例 1、DNS阻断 m string --hex-string是iptables中一个以​十六进制格式​定义要匹配的二进制特征并且支持混合明文和二进制数据的模块。由于DN…

mysql-本地编译 MySQL 源码

完全理解你的感受&#xff01;MySQL 源码本地调试确实是一个“坑多”的过程&#xff0c;尤其是当你第一次尝试从源码构建和调试 MySQL 时。但别担心&#xff0c;我来一步步帮你梳理整个流程&#xff0c;并提供一个详细、可操作的指南&#xff0c;让你可以顺利跑起来 MySQL 源码…

深入理解 shared_ptr 与 enable_shared_from_this

在 C++ 的智能指针体系中,std::shared_ptr 是一个非常重要的工具,它通过引用计数机制帮助我们管理动态分配的对象生命周期,避免内存泄漏。然而,在某些情况下,我们可能需要从一个对象内部获取指向自身的 shared_ptr,这时候就需要使用 std::enable_shared_from_this 这个辅…

通义开源视觉感知多模态 RAG 推理框架 VRAG-RL:开启多模态推理新时代

通义实验室的自然语言智能团队&#xff0c;凭借深厚的技术积累与创新精神&#xff0c;成功研发并开源了视觉感知多模态 RAG 推理框架 VRAG-RL&#xff0c;为 AI 在复杂视觉信息处理领域带来了重大突破。 传统 RAG 方法的局限 传统的检索增强型生成&#xff08;RAG&#xff0…

【iOS】方法交换

方法交换 method-swizzling是什么相关API方法交换的风险method-swizzling使用过程中的一次性问题在当前类中进行方法交换类方法的方法交换 方法交换的应用 method-swizzling是什么 method-swizzling的含义是方法交换&#xff0c;他的主要作用是在运行的时候将一个方法的实现替…

Python - 爬虫;Scrapy框架之插件Extensions(四)

阅读本文前先参考 https://blog.csdn.net/MinggeQingchun/article/details/145904572 在 Scrapy 中&#xff0c;扩展&#xff08;Extensions&#xff09;是一种插件&#xff0c;允许你添加额外的功能到你的爬虫项目中。这些扩展可以在项目的不同阶段执行&#xff0c;比如启动…

95套HTML高端大数据可视化大屏源码分享

概述​​ 在大数据时代&#xff0c;数据可视化已成为各行各业的重要需求。这里精心整理了95套高端HTML大数据可视化大屏源码&#xff0c;这些资源采用现代化设计风格&#xff0c;可帮助开发者快速构建专业的数据展示界面。 ​​主要内容​​ ​​1. 设计风格与特点​​ 采用…

redis未授权(CVE-2022-0543)

概述 Redis 默认绑定在 0.0.0.0:6379&#xff0c;在未配置防火墙或访问控制的情况下会将服务暴露在公网上。若未设置访问密码&#xff08;默认通常为空&#xff09;&#xff0c;攻击者可直接未授权访问 Redis。利用 Redis 提供的 CONFIG 命令&#xff0c;攻击者可修改配置并将…

(面试)OkHttp实现原理

OkHttp 是一个高效的 HTTP 客户端&#xff0c;被广泛应用于 Android 和 Java 应用中。它提供了许多强大的特性&#xff0c;例如连接池、透明的 GZIP 压缩、HTTP/2 支持等。理解 OkHttp 的实现原理有助于更好地使用和调试它。 以下是 OkHttp 的一些核心实现原理&#xff1a; 1…

Netty 实战篇:构建简易注册中心,实现服务发现与调用路由

本文将为前面构建的轻量级 RPC 框架添加“服务注册与发现”功能&#xff0c;支持多服务节点动态上线、自动感知与调用路由&#xff0c;为构建真正可扩展的分布式系统打好基础。 一、背景&#xff1a;为什么需要注册中心&#xff1f; 如果每个客户端都硬编码连接某个 IP/端口的…

c++之分支

深入理解 C 分支结构&#xff1a;从基础到实战 在 C 编程的世界里&#xff0c;分支结构是控制程序流程的重要手段&#xff0c;它赋予程序 “思考” 和 “选择” 的能力&#xff0c;让程序能够根据不同的条件执行不同的代码块。本文将带大家深入探索 C 分支结构&#xff0c;结合…

LLMs之MCP:如何使用 Gradio 构建 MCP 服务器

LLMs之MCP&#xff1a;如何使用 Gradio 构建 MCP 服务器 导读&#xff1a;本文详细介绍了如何使用Gradio构建MCP服务器&#xff0c;包括前提条件、构建方法、关键特性和相关资源。通过一个简单的字母计数示例&#xff0c;演示了如何将Gradio应用转换为LLM可以使用的工具。Gradi…

ubuntu20.04.5-arm64版安装robotjs

ubuntu20.04.5arm上使用robotjs #ssh&#xff0c;可选 sudo apt update sudo apt install openssh-server sudo systemctl status ssh sudo systemctl enable ssh sudo systemctl enable --now ssh #防火墙相关&#xff0c;可选 sudo ufw allow ssh sudo ufw allow 2222/tc…

craw4ai 抓取实时信息,与 mt4外行行情结合实时交易,基本面来觉得趋势方向,搞一个外汇交易策略

结合实时信息抓取、MT4行情数据、基本面分析的外汇交易策略框架&#xff0c;旨在通过多维度数据融合提升交易决策质量&#xff1a;行不行不知道先试试&#xff0c;理论是对的&#xff0c;只要基本面方向没错 策略名称&#xff1a;Tri-Sync 外汇交易系统 核心理念 「基本面定方…

Python中scapy库详细使用(强大的交互式数据包操作程序和库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、scapy概述1.1 scapy介绍1.2 安装1.3 交互模式1.4 安全注意事项二、基本使用2.1 数据包构造基础2.2 数据包发送2.3 数据包嗅探2.4 数据包分析与操作2.5 网络扫描技术2.6 协议实现示例三、高级功能3.1 数据包重放3.2 …

基于Web的濒危野生动物保护信息管理系统设计(源码+定制+开发)濒危野生动物监测与保护平台开发 面向公众参与的野生动物保护与预警信息系统

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

[SAP] 矩阵复制(Matrix Copy)

SAP中的复制粘贴功能被称为矩阵复制&#xff0c;通过点击对话框或屏幕&#xff0c;并执行下述命令&#xff0c;使用矩阵复制就可以复制多行文本 ① 按下Ctrl-Y&#xff0c;从左上到右下拖拉鼠标来选择文本 ② 文本高亮显示后&#xff0c;按下Ctrl-C ③ 移到新的位置插入文本…