Unity for Python —— 强大的 Python 脚本支持提升 Unity 编辑器效率

内容将会持续更新,有错误的地方欢迎指正,谢谢!

Unity for Python ------ 强大的 Python 脚本支持提升 Unity 编辑器效率


|-----------------------------------------------------|
| TechX 坚持将创新的科技带给世界! 拥有更好的学习体验 ------ 不断努力,不断进步,不断探索 |

|---------------------------------------------------------|
| TechX ------ 心探索、心进取! 助力快速掌握 关键词 学习 为初学者节省宝贵的学习时间,避免困惑! |

前言:

在 Unity 开发过程中,我们常常面临一些重复性、繁琐的任务,尤其是在编辑器开发和自动化工作流方面。为了提高效率和扩展 Unity 编辑器,Unity 官方推出了 Python for Unity,它允许开发者在 Unity 编辑器中运行 Python 脚本,从而增强工作流、自动化任务和数据处理。

本文将详细介绍 Unity for Python 的功能、部署步骤、低级 API 和高级 API,举例说明如何在实际开发中使用它,并展示一些常见的应用案例,帮助你快速掌握如何利用 Python 在 Unity 中提高开发效率。

TechX 教程效果:


文章目录

  • [一、什么是 Unity for Python?](#一、什么是 Unity for Python?)
  • [二、Unity for Python 的功能和应用](#二、Unity for Python 的功能和应用)
  • [三、Unity for Python 使用条件与安装](#三、Unity for Python 使用条件与安装)
  • [四、Python for Unity 设置](#四、Python for Unity 设置)
  • [五、API 介绍](#五、API 介绍)
    • [1、Low-level API](#1、Low-level API)
    • [2、High-level API](#2、High-level API)
    • [3、 API 交互 ------ 带参调用与返回结果](#3、 API 交互 —— 带参调用与返回结果)
  • 六、实际应用案例

一、什么是 Unity for Python?

Unity for Python 是 Unity 编辑器的一个扩展,允许开发者通过 Python 脚本与 Unity 编辑器进行交互。它使得 Python 成为 Unity 编辑器的一部分,可以用于自动化开发流程、创建自定义工具、操作场景数据以及与外部系统进行交互。通过 Python,开发者可以利用 Python 在数据处理、科学计算、文件操作等方面的强大能力,从而提高开发效率。


二、Unity for Python 的功能和应用

Unity for Python 的主要功能包括:

  • 自动化任务:通过 Python 脚本自动化一些重复性任务,比如批量修改资源、更新游戏对象属性、批量处理场景元素等。
  • 自定义工具和编辑器扩展:使用 Python 脚本创建自定义工具,增强 Unity 编辑器功能,提供更多灵活的操作界面。
  • 数据导入与处理:通过 Python 导入外部数据(如 CSV、JSON 等),并在 Unity 中应用。
  • 与 Unity 编辑器和游戏对象的交互:Python 可以直接访问 Unity 编辑器 API,操作场景中的对象、资源以及材质等。

三、Unity for Python 使用条件与安装

1、使用条件

要使用 Unity for Python,你需要满足以下条件:

  • 系统要求:仅限 Windows 10+ 或 macOS High Sierra 10.13+,64 位版本。
  • Unity 版本:Unity 2021.2。我们建议通过 Unity Hub 安装最新版本的 Unity 2021.2;2020.2 是最小值。

2、安装

您可以通过 Package Manager 或项目的清单安装此包。

在 Unity 2022.1 及更高版本中:

  • 打开 Package Manager Project Settings。

  • 启用 Enable Pre-release packages 复选框。

  • 打开 Package Manager 窗口。

  • 单击 Packages 下拉列表,然后选择 Unity Registry。

  • 在包列表中找到并选择 Python for Unity,然后单击 Install。

在 Unity 2021.2 中:

  • 打开 Package Manager 窗口。

  • 单击 + 下拉列表,然后选择 Add package by name。

  • 输入 com.unity.scripting.python,然后单击 Add。

安装过程完成后,控制台中将显示"Python successfully installed"。

3、验证安装

安装和配置完成后,打开 Window > General > Python Console。如果 Python 控制台正常显示,且可以输入命令执行 Python 脚本,则说明安装成功。


四、Python for Unity 设置

在Unity中使用Python脚本时,可能需要安装额外的Python包。Python for Unity提供了多种方式来管理这些包:

1、使用requirements.txt文件

您可以在项目的ProjectSettings文件夹中创建一个名为requirements.txt的文件,列出所需的Python包及其版本。每次打开项目时,Unity会自动根据该文件安装或更新Python包。

请注意,只有在项目打开时才会应用requirements.txt中的更改,如果在Unity运行时修改了该文件,需要重新启动Unity以使更改生效。

2、手动安装Python包

您可以使用 pip 为您的项目安装 Python 包。它们将安装在项目的 Library/PythonInstall/Lib/site-packages 文件夹中。如果需要手动安装或更新Python包,可以按照以下步骤操作:

  • Windows:

    1. 在Project Settings > Python Scripting中,点击Launch Terminal按钮。

    2. 这将打开一个PowerShell窗口,其PATH 环境已配置为Unity的Python安装路径。

    3. 在该窗口中,使用pip3命令安装所需的包,例如:

      powershell 复制代码
      pip3 install numpy
    4. 安装完成后,运行以下命令将当前安装的包列表保存到requirements.txt:

      powershell 复制代码
      pip3 freeze > ProjectSettings/requirements.txt
  • macOS:

    1. 在Unity项目中,右键点击Assets文件夹,选择Reveal in Finder。

    2. 打开终端(Terminal),输入cd,然后将Library文件夹拖入终端窗口,按下回车。

    3. 接着输入:

      bash 复制代码
      cd PythonInstall/bin
    4. 使用以下命令安装所需的包:

      bash 复制代码
      ./pip3 install numpy
    5. 安装完成后,运行以下命令将当前安装的包列表保存到requirements.txt:

      bash 复制代码
      ./pip3 freeze > ../../../ProjectSettings/requirements.txt

请注意,修改requirements.txt文件后,需要重新启动Unity以应用更改。


五、API 介绍

Unity for Python 提供了多种 API,主要包括低级 API、高级 API 以及交互 API(用于传参和返回结果)。

1、Low-level API

您可以直接使用 Python for .NET,它包装了 CPython API。使用 C# dynamic 类型,您可以编写类似于 Python 的 C#。

低级 API 通过 PythonEngine 进行 Python 环境的初始化和代码执行,允许更精细的控制和复杂交互。

示例:使用 PythonEngine 执行 Python 代码

csharp 复制代码
using Python.Runtime;
using UnityEditor.Scripting.Python;

public class MyPythonScript
{
    [MenuItem("MyPythonScript/Run")]
    public static void Run()
    {
        PythonRunner.EnsureInitialized();
        using (Py.GIL()) {
            try {
                dynamic sys = Py.Import("sys");
                UnityEngine.Debug.Log($"python version: {sys.version}");
            } catch(PythonException e) {
                UnityEngine.Debug.LogException(e);
            }
        }
    }
}

通过调用 PythonRunner.EnsureInitialized() 确保 Python 已正确初始化。

始终获取 CPython 全局解释器锁 (GIL)。

您需要添加程序集引用,以便编译器知道在 Python.Runtime 中的何处可以找到低级 API。在项目视图中,右键单击并创建新的程序集引用:

然后添加对 com.unity.scripting.python.editor 的引用 :

2、High-level API

高级 API 提供了更简洁的接口,通过 PythonRunner.RunString 和 PythonRunner.RunFile 快速执行 Python 脚本,无需手动管理 Python 环境,非常适合自动化任务和编辑器扩展。

示例:使用 PythonRunner.RunString 执行内联 Python 代码

csharp 复制代码
using UnityEditor;
using UnityEditor.Scripting.Python;
using UnityEngine;

public class HelloWorld
{
    [MenuItem("Python/Hello World")]
    static void PrintHelloWorldFromPython()
    {
        PythonRunner.RunString(@"
import UnityEngine
UnityEngine.Debug.Log('hello world')
        ");
    }
}

您可以使用 C# 中可用的任何程序集,只需使用 Python import 语句导入它 - 在示例中,我们展示了如何导入 UnityEngine。

示例:使用 PythonRunner.RunFile 执行 Python 脚本文件

您可以使用 PythonRunner.RunFile 方法执行整个 Python 脚本,而不是在 C# 脚本中内联 Python 代码。例如,此 Python 脚本循环访问场景中的所有 GameObject,并确保所有名称都以下划线结尾:

python 复制代码
import UnityEngine

all_objects = UnityEngine.Object.FindObjectsOfType(UnityEngine.GameObject)
for go in all_objects:
    if go.name[-1] != '_':
        go.name = go.name + '_'

将此文件放在 Assets/ensure_naming.py 中。脚本文件可以位于文件系统上的任何位置,它们不需要位于项目中。您可以从 C# 运行此 Python 脚本,如下所示:

csharp 复制代码
using UnityEditor.Scripting.Python;
using UnityEditor;
using UnityEngine;

public class EnsureNaming
{
    [MenuItem("Python/Ensure Naming")]
    static void RunEnsureNaming()
    {
        PythonRunner.RunFile($"{Application.dataPath}/ensure_naming.py");
    }
}

3、 API 交互 ------ 带参调用与返回结果

Unity for Python 同样支持调用 Python 中的单个函数、传递参数、获取返回值,甚至支持复杂数据结构的返回。

示例一:C# 调用Python

将 Python 脚本保存为 calculate_sum.py:

python 复制代码
# calculate_sum.py
import sys

def calculate_sum(a, b):
    return a + b

C# 调用代码如下:

csharp 复制代码
using UnityEditor;
using UnityEditor.Scripting.Python;
using UnityEngine;

public class PythonWithParamsFromFile
{
    [MenuItem("Python/Calculate Sum From File")]
    static void CalculateSumFromFile()
    {
        PythonRunner.EnsureInitialized();
		using (Py.GIL())
		{
		    try
		    {
		        dynamic sys = Py.Import("calculate_sum");
		        dynamic sum = sys.calculate_sum(1,2);
		        Debug.Log($"python version: {sum}");
		    }
		    catch (PythonException e)
		    {
		        Debug.LogException(e);
		    }
		}
    }
}

在这里要特别注意,Python 的 import 机制会在 当前目录 或 sys.path 列表中的目录 查找模块。因此,确保 calculate_sum.py 放在 Unity 可被 Python 识别的目录。

在Project Settings=>Python Scripting设置的Package Directories中,将你的py脚本所在目录添加到这个列表中,这样才可以导入这个模块并执行里面的方法。

**示例二:Python 调用 C# **

C# 脚本也定义一个计算两个数和的函数,可以供Python调用。

C# 脚本 PlayerController.py

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace PlayerController
{
    public class PlayerController : MonoBehaviour
    {
        public int Sum(int a, int b)
        { 
            return a + b;
        }
    }
}

Python 调用如下:

python 复制代码
import UnityEngine
import PlayerController

# 获取场景中的 Player
player = UnityEngine.GameObject.Find("Player")

# 获取 Player 的 PlayerController 组件
controller = player.GetComponent(PlayerController.PlayerController)

print(controller)

sum = controller.Sum(1,6)

print(sum)

在Python里面,所有的程序集已经自动加载,不在需要手动去加载

python 复制代码
#手动加载,但是这里不在需要这样去加载
import clr
clr.AddReference("Assembly-CSharp")

但是我们需要导入模块,这里的模块指的是C#中的命名空间名称,像这样namespace PlayerController,如果写的脚本没有命名空间,直接去导入类的话会报错找不到模块,这块是需要注意的


六、实际应用案例

下面通过几个实际案例展示 Unity for Python 能够实现哪些功能,帮助你在项目中灵活应用这一工具。

案例 1:批量修改资源

通过 Python 脚本批量处理项目中资源,例如重命名 Prefab 文件。

python 复制代码
import UnityEditor
import os

asset_paths = UnityEditor.AssetDatabase.GetAllAssetPaths()
prefix = "NewPrefix_"

for path in asset_paths:
    if path.endswith(".prefab"):
        file_name = os.path.basename(path)
        new_file_name = prefix + file_name
        UnityEditor.AssetDatabase.RenameAsset(path, new_file_name)
        
UnityEditor.AssetDatabase.Refresh()

案例 2:自动化构建流程

使用 Python 脚本自动构建项目、生成构建报告,并进行构建后处理。

python 复制代码
import UnityEditor
import datetime

build_target = UnityEditor.BuildTarget.StandaloneWindows
build_path = "Builds/MyGame.exe"
report_path = "Builds/BuildReport.txt"

UnityEditor.BuildPipeline.BuildPlayer(UnityEditor.EditorBuildSettings.scenes, build_path, build_target, UnityEditor.BuildOptions.None)

with open(report_path, 'w') as file:
    file.write(f"Build Report - {datetime.datetime.now()}\n")
    file.write(f"Build Path: {build_path}\n")
    file.write("Scenes Included:\n")
    for scene in UnityEditor.EditorBuildSettings.scenes:
        file.write(f"- {scene.path}\n")

案例 3:自定义编辑器工具

使用 Python 创建自定义编辑器窗口,实现对选中对象名称的快速修改。

python 复制代码
import UnityEditor
import UnityEngine

class CustomEditorWindow(UnityEditor.EditorWindow):
    @staticmethod
    def show_window():
        window = UnityEditor.EditorWindow.GetWindow(CustomEditorWindow, True, "Custom Editor Tool")
        window.Show()

    def OnGUI(self):
        self.obj_name = UnityEditor.EditorGUILayout.TextField("Object Name", self.obj_name)
        
        if UnityEditor.EditorGUILayout.Button("Change Object Name"):
            selected_objects = UnityEditor.Selection.objects
            for obj in selected_objects:
                if isinstance(obj, UnityEngine.GameObject):
                    obj.name = self.obj_name
                    UnityEditor.EditorUtility.SetDirty(obj)

CustomEditorWindow.show_window()

案例 4:数据导入与处理

从 CSV 文件导入数据,并将数据应用到场景中的游戏对象上。

bash 复制代码
Name,X,Y,Z
Cube1,10,10,10
Cube2,20,20,20
python 复制代码
import csv
import UnityEditor
import UnityEngine

file_path = "Assets/PositionData.csv"
with open(file_path, newline='') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        obj_name = row['Name']
        x, y, z = float(row['X']), float(row['Y']), float(row['Z'])
        obj = UnityEngine.GameObject.Find(obj_name)
        if obj:
            obj.transform.position = UnityEngine.Vector3(x, y, z)

|-----------------------------------------------|
| TechX ------ 心探索、心进取! 每一次跌倒都是一次成长 每一次努力都是一次进步 |


END 感谢您阅读本篇博客!希望这篇内容对您有所帮助。如果您有任何问题或意见,或者想要了解更多关于本主题的信息,欢迎在评论区留言与我交流。我会非常乐意与大家讨论和分享更多有趣的内容。
如果您喜欢本博客,请点赞和分享给更多的朋友,让更多人受益。同时,您也可以关注我的博客,以便及时获取最新的更新和文章。
在未来的写作中,我将继续努力,分享更多有趣、实用的内容。再次感谢大家的支持和鼓励,期待与您在下一篇博客再见!

相关推荐
程序猿多布7 分钟前
Unity Excel导表工具转Lua文件
unity·excel
笨鸟笃行7 分钟前
爬虫第七篇数据爬取及解析
开发语言·爬虫·python
java1234_小锋13 分钟前
一周学会Flask3 Python Web开发-response响应格式
开发语言·python·flask·flask3
大数据追光猿14 分钟前
Python中的Flask深入认知&搭建前端页面?
前端·css·python·前端框架·flask·html5
java1234_小锋15 分钟前
一周学会Flask3 Python Web开发-flask3模块化blueprint配置
开发语言·python·flask·flask3
莫忘初心丶17 分钟前
python flask 使用教程 快速搭建一个 Web 应用
前端·python·flask
不爱学英文的码字机器1 小时前
Python爬虫实战:从零到一构建数据采集系统
开发语言·爬虫·python
鹿鸣悠悠1 小时前
Python 类和对象详解
开发语言·python
老友@1 小时前
OnlyOffice:前端编辑器与后端API实现高效办公
前端·后端·websocket·编辑器·onlyoffice
laocooon5238578861 小时前
用Python实现的双向链表类,包含了头插、尾插、归并排序等功能
开发语言·python