如何使用Docker搭建Unity引擎开发环境?

使用 Docker 搭建 Unity 引擎开发环境

Unity 开发环境虽然不是最典型的 Docker 应用场景,但对于持续集成、自动化构建和多平台测试来说,Docker 化 Unity 环境有着显著优势。以下是详细的实现方法:

1. Unity 容器化挑战与解决方案

主要挑战

Unity 容器化面临几个关键挑战:

  1. Unity 需要图形界面,而 Docker 容器通常是无头的
  2. Unity 授权和许可验证复杂
  3. 资源需求较高(GPU 访问、大量内存)
  4. 跨平台构建复杂

解决方案概述

我们将主要聚焦于以下场景的 Docker 化:

  • Unity 项目的自动构建
  • 持续集成与测试
  • 服务器端构建与部署
  • 无头模式下的游戏服务器

2. 基础 Unity 构建容器

Dockerfile 创建

创建一个基础的 Unity 构建环境 Dockerfile:

FROM ubuntu:22.04

# 避免交互式提示
ARG DEBIAN_FRONTEND=noninteractive

# 安装依赖
RUN apt-get update && apt-get install -y \
    curl \
    wget \
    zip \
    unzip \
    xvfb \
    libglu1-mesa \
    libglib2.0-0 \
    libxcursor1 \
    libxrandr2 \
    libasound2 \
    libnss3 \
    libpci3 \
    libxcomposite1 \
    libxdamage1 \
    libgl1-mesa-glx \
    libcanberra-gtk-module \
    gnupg \
    software-properties-common \
    && rm -rf /var/lib/apt/lists/*

# 创建Unity安装目录和工作目录
RUN mkdir -p /opt/unity /unity_project

# 设置工作目录
WORKDIR /unity_project

# 安装特定版本的Unity
# 注意:这里使用Unity Hub命令行安装特定版本
ARG UNITY_VERSION=2022.3.12f1
ARG UNITY_CHANGESET=a7ad3FC73a2F

RUN wget -qO - https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg \
    && mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg \
    && sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-$(lsb_release -cs)-prod $(lsb_release -cs) main" > /etc/apt/sources.list.d/dotnetdev.list' \
    && apt-get update \
    && apt-get install -y dotnet-sdk-7.0 \
    && wget -O UnitySetup https://beta.unity3d.com/download/${UNITY_CHANGESET}/UnitySetup-${UNITY_VERSION} \
    && chmod +x UnitySetup \
    && ./UnitySetup --unattended --install-location=/opt/unity --components=Unity \
    && rm UnitySetup

# 设置环境变量
ENV PATH="/opt/unity/Editor:${PATH}"
ENV UNITY_PATH="/opt/unity/Editor/Unity"

# 设置一个卷,用于挂载Unity项目
VOLUME ["/unity_project"]

# 默认命令,显示Unity版本
CMD ["bash"]

3. 高级 Unity CI/CD 容器

针对持续集成的更完善配置:

FROM ubuntu:22.04

ARG DEBIAN_FRONTEND=noninteractive
ARG UNITY_VERSION=2022.3.12f1
ARG UNITY_CHANGESET=a7ad3FC73a2F
ARG UNITY_LICENSE_FILE=Unity_v2022.x.ulf

# 安装基础依赖
RUN apt-get update && apt-get install -y \
    curl wget gzip ca-certificates xvfb \
    libglu1 libxcursor1 libxrandr2 libnss3 libasound2 libpci3 \
    libxcomposite1 libxdamage1 libasound2 libgtk-3-0 \
    && rm -rf /var/lib/apt/lists/*

# 安装Unity
WORKDIR /tmp
RUN wget -q https://beta.unity3d.com/download/${UNITY_CHANGESET}/UnitySetup-${UNITY_VERSION} -O UnitySetup && \
    chmod +x UnitySetup && \
    ./UnitySetup --unattended --install-location=/opt/unity --components=Unity,Windows-Mono,Mac-Mono,Linux-Mono && \
    rm UnitySetup

# 设置环境变量
ENV PATH="/opt/unity/Editor:${PATH}"
ENV UNITY_PATH="/opt/unity/Editor/Unity"

# 添加激活和构建脚本
COPY scripts/activate_unity.sh /usr/local/bin/activate_unity
COPY scripts/build_unity.sh /usr/local/bin/build_unity
RUN chmod +x /usr/local/bin/activate_unity /usr/local/bin/build_unity

# 设置工作目录
WORKDIR /unity_project
VOLUME ["/unity_project"]

# 默认入口点
ENTRYPOINT ["/usr/local/bin/build_unity"]

激活脚本 (activate_unity.sh)

#!/bin/bash
set -e

# 检查环境变量
if [ -z "$UNITY_USERNAME" ] || [ -z "$UNITY_PASSWORD" ]; then
    echo "请设置 UNITY_USERNAME 和 UNITY_PASSWORD 环境变量"
    exit 1
fi

# 使用 xvfb 创建虚拟显示
Xvfb :99 -screen 0 1024x768x24 &
export DISPLAY=:99

# 使用Unity命令行登录
echo "正在登录 Unity 账户..."
"$UNITY_PATH" -batchmode -nographics -logFile - -quit -username "$UNITY_USERNAME" -password "$UNITY_PASSWORD"

echo "Unity 激活完成"

构建脚本 (build_unity.sh)

#!/bin/bash
set -e

# 默认参数
BUILD_TARGET=${1:-"StandaloneLinux64"}
BUILD_PATH=${2:-"./Build"}
UNITY_PROJECT_PATH=${3:-"."}

# 使用 xvfb 创建虚拟显示
Xvfb :99 -screen 0 1024x768x24 &
export DISPLAY=:99

echo "开始构建 Unity 项目,目标平台:$BUILD_TARGET"
echo "构建路径:$BUILD_PATH"
echo "项目路径:$UNITY_PROJECT_PATH"

# 执行Unity构建
"$UNITY_PATH" \
    -batchmode \
    -nographics \
    -logFile /dev/stdout \
    -projectPath "$UNITY_PROJECT_PATH" \
    -buildTarget "$BUILD_TARGET" \
    -executeMethod BuildScript.PerformBuild \
    -buildPath "$BUILD_PATH" \
    -quit

echo "Unity 构建完成!"

4. Docker Compose 集成

创建一个 docker-compose.yml 文件以整合 Unity 构建环境:

version: '3.8'

services:
  unity-builder:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        UNITY_VERSION: 2022.3.12f1
        UNITY_CHANGESET: a7ad3FC73a2F
    container_name: unity-builder
    volumes:
      - ./:/unity_project
      - unity_cache:/root/.cache/unity3d
    environment:
      - UNITY_USERNAME=${UNITY_USERNAME}
      - UNITY_PASSWORD=${UNITY_PASSWORD}
      - UNITY_SERIAL=${UNITY_SERIAL}
      - BUILD_TARGET=StandaloneLinux64
      - BUILD_PATH=./Builds/Linux
    command: ["StandaloneLinux64", "./Builds/Linux", "."]

  unity-builder-windows:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: unity-builder-windows
    volumes:
      - ./:/unity_project
      - unity_cache:/root/.cache/unity3d
    environment:
      - UNITY_USERNAME=${UNITY_USERNAME}
      - UNITY_PASSWORD=${UNITY_PASSWORD}
      - UNITY_SERIAL=${UNITY_SERIAL}
      - BUILD_TARGET=StandaloneWindows64
      - BUILD_PATH=./Builds/Windows
    command: ["StandaloneWindows64", "./Builds/Windows", "."]
    profiles: ["windows"]

  unity-builder-android:
    build:
      context: .
      dockerfile: Dockerfile.android
    container_name: unity-builder-android
    volumes:
      - ./:/unity_project
      - unity_cache:/root/.cache/unity3d
      - android_sdk:/opt/android-sdk
    environment:
      - UNITY_USERNAME=${UNITY_USERNAME}
      - UNITY_PASSWORD=${UNITY_PASSWORD}
      - UNITY_SERIAL=${UNITY_SERIAL}
      - BUILD_TARGET=Android
      - BUILD_PATH=./Builds/Android
    command: ["Android", "./Builds/Android", "."]
    profiles: ["android"]

  unity-test:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: unity-test
    volumes:
      - ./:/unity_project
      - unity_cache:/root/.cache/unity3d
    environment:
      - UNITY_USERNAME=${UNITY_USERNAME}
      - UNITY_PASSWORD=${UNITY_PASSWORD}
      - UNITY_SERIAL=${UNITY_SERIAL}
    command: ["/usr/local/bin/run_tests.sh"]
    profiles: ["test"]

volumes:
  unity_cache:
  android_sdk:

5. Android 构建支持

创建一个额外的 Dockerfile 以支持 Android 平台:

FROM ubuntu:22.04

ARG DEBIAN_FRONTEND=noninteractive
ARG UNITY_VERSION=2022.3.12f1
ARG UNITY_CHANGESET=a7ad3FC73a2F
ARG ANDROID_SDK_VERSION=commandlinetools-linux-9477386_latest.zip

# 安装基础依赖
RUN apt-get update && apt-get install -y \
    curl wget gzip openjdk-11-jdk ca-certificates xvfb \
    libglu1 libxcursor1 libxrandr2 libnss3 libasound2 libpci3 \
    libxcomposite1 libxdamage1 libasound2 libgtk-3-0 \
    && rm -rf /var/lib/apt/lists/*

# 安装Android SDK
RUN mkdir -p /opt/android-sdk/cmdline-tools && \
    wget -q https://dl.google.com/android/repository/${ANDROID_SDK_VERSION} -O android-sdk.zip && \
    unzip -q android-sdk.zip -d /opt/android-sdk/cmdline-tools && \
    mv /opt/android-sdk/cmdline-tools/cmdline-tools /opt/android-sdk/cmdline-tools/latest && \
    rm android-sdk.zip

# 设置Android环境变量
ENV ANDROID_HOME=/opt/android-sdk
ENV PATH=${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools

# 安装Android组件
RUN yes | sdkmanager --licenses && \
    sdkmanager "platform-tools" "platforms;android-33" "build-tools;33.0.2" "ndk;25.2.9519653"

# 安装Unity
WORKDIR /tmp
RUN wget -q https://beta.unity3d.com/download/${UNITY_CHANGESET}/UnitySetup-${UNITY_VERSION} -O UnitySetup && \
    chmod +x UnitySetup && \
    ./UnitySetup --unattended --install-location=/opt/unity --components=Unity,Android && \
    rm UnitySetup

# 设置环境变量
ENV PATH="/opt/unity/Editor:${PATH}"
ENV UNITY_PATH="/opt/unity/Editor/Unity"

# 添加激活和构建脚本
COPY scripts/activate_unity.sh /usr/local/bin/activate_unity
COPY scripts/build_unity.sh /usr/local/bin/build_unity
RUN chmod +x /usr/local/bin/activate_unity /usr/local/bin/build_unity

# 设置工作目录
WORKDIR /unity_project
VOLUME ["/unity_project", "/opt/android-sdk"]

# 默认入口点
ENTRYPOINT ["/usr/local/bin/build_unity"]

6. Unity 测试运行器

创建 Unity 测试脚本 (run_tests.sh):

#!/bin/bash
set -e

# 使用 xvfb 创建虚拟显示
Xvfb :99 -screen 0 1024x768x24 &
export DISPLAY=:99

echo "开始运行 Unity 测试..."

# 执行Unity测试
"$UNITY_PATH" \
    -batchmode \
    -nographics \
    -logFile /dev/stdout \
    -projectPath "." \
    -runTests \
    -testPlatform PlayMode \
    -testResults /unity_project/test-results.xml \
    -quit

echo "Unity 测试完成!"

7. Unity 项目准备

为了让 Docker 构建正常工作,需要在 Unity 项目中添加构建脚本。创建 Assets/Editor/BuildScript.cs

using UnityEditor;
using UnityEngine;
using System;

public class BuildScript
{
    [MenuItem("Build/Build All")]
    public static void PerformBuild()
    {
        // 获取命令行参数
        string buildTarget = GetArgument("-buildTarget");
        string buildPath = GetArgument("-buildPath");
        
        // 设置默认值
        if (string.IsNullOrEmpty(buildTarget))
            buildTarget = "StandaloneLinux64";
        if (string.IsNullOrEmpty(buildPath))
            buildPath = "Builds/" + buildTarget;
            
        // 确定构建目标
        BuildTarget target = BuildTarget.StandaloneLinux64;
        switch(buildTarget)
        {
            case "StandaloneWindows":
                target = BuildTarget.StandaloneWindows;
                break;
            case "StandaloneWindows64":
                target = BuildTarget.StandaloneWindows64;
                break;
            case "StandaloneLinux64":
                target = BuildTarget.StandaloneLinux64;
                break;
            case "Android":
                target = BuildTarget.Android;
                break;
            case "iOS":
                target = BuildTarget.iOS;
                break;
            case "WebGL":
                target = BuildTarget.WebGL;
                break;
            // 如有需要,可添加更多平台支持
        }
        
        // 获取场景列表
        string[] scenes = new string[EditorBuildSettings.scenes.Length];
        for (int i = 0; i < scenes.Length; i++)
        {
            scenes[i] = EditorBuildSettings.scenes[i].path;
        }
        
        // 执行构建
        Debug.Log("开始构建 " + buildTarget + " 到路径: " + buildPath);
        BuildPipeline.BuildPlayer(scenes, buildPath, target, BuildOptions.None);
        Debug.Log("构建完成!");
    }
    
    private static string GetArgument(string name)
    {
        string[] args = Environment.GetCommandLineArgs();
        for (int i = 0; i < args.Length; i++)
        {
            if (args[i] == name && i < args.Length - 1)
            {
                return args[i + 1];
            }
        }
        return null;
    }
}

8. GitLab CI/CD 集成

创建 .gitlab-ci.yml 文件实现自动化构建:

stages:
  - test
  - build
  - deploy

variables:
  UNITY_VERSION: "2022.3.12f1"
  DOCKER_DRIVER: overlay2
  GIT_STRATEGY: fetch

.unity_before_script: &unity_before_script
  before_script:
    - chmod +x ./ci/activate_unity.sh
    - ./ci/activate_unity.sh

unity_test:
  stage: test
  image: 
    name: $CI_REGISTRY_IMAGE/unity-builder:$UNITY_VERSION
    entrypoint: [""]
  <<: *unity_before_script
  script:
    - /usr/local/bin/run_tests.sh
  artifacts:
    paths:
      - test-results.xml
    reports:
      junit: test-results.xml

build_linux:
  stage: build
  image: 
    name: $CI_REGISTRY_IMAGE/unity-builder:$UNITY_VERSION
    entrypoint: [""]
  <<: *unity_before_script
  script:
    - /usr/local/bin/build_unity StandaloneLinux64 ./Builds/Linux .
  artifacts:
    paths:
      - Builds/Linux
    expire_in: 1 week

build_windows:
  stage: build
  image: 
    name: $CI_REGISTRY_IMAGE/unity-builder:$UNITY_VERSION
    entrypoint: [""]
  <<: *unity_before_script
  script:
    - /usr/local/bin/build_unity StandaloneWindows64 ./Builds/Windows .
  artifacts:
    paths:
      - Builds/Windows
    expire_in: 1 week

build_android:
  stage: build
  image: 
    name: $CI_REGISTRY_IMAGE/unity-builder-android:$UNITY_VERSION
    entrypoint: [""]
  <<: *unity_before_script
  script:
    - /usr/local/bin/build_unity Android ./Builds/Android .
  artifacts:
    paths:
      - Builds/Android/*.apk
    expire_in: 1 week

deploy_dev:
  stage: deploy
  image: alpine:latest
  script:
    - apk add --no-cache curl
    - echo "上传构建结果到开发服务器"
    # 这里添加上传或部署脚本
  environment:
    name: development
  only:
    - develop

9. 优化和最佳实践

缓存优化

为了加速构建过程,可以实现多级缓存:

  1. Unity 缓存
    使用命名卷保存 Unity 缓存:

    volumes:
      - unity_cache:/root/.cache/unity3d
    
  2. 项目库缓存

    volumes:
      - unity_library:/unity_project/Library
    
  3. Gradle 缓存 (Android 构建)

    volumes:
      - gradle_cache:/root/.gradle
    

多阶段构建

使用多阶段构建减小最终镜像大小:

# 构建阶段
FROM ubuntu:22.04 AS builder

# ... Unity安装和构建过程 ...

# 运行阶段(用于游戏服务器)
FROM ubuntu:22.04

COPY --from=builder /opt/unity/Editor/Data/PlaybackEngines/LinuxStandaloneSupport /opt/unity/linux
COPY --from=builder /unity_project/Builds/Linux /app

WORKDIR /app
ENTRYPOINT ["./GameServer.x86_64"]

10. 配置 Unity Hub (可选)

如果需要在容器中使用 Unity Hub:

# 安装Unity Hub
RUN wget -qO - https://hub.unity3d.com/linux/keys/public | gpg --dearmor > /etc/apt/trusted.gpg.d/unity-hub.gpg \
    && sh -c 'echo "deb [arch=amd64] https://hub.unity3d.com/linux/repos/deb stable main" > /etc/apt/sources.list.d/unity-hub.list' \
    && apt-get update \
    && apt-get install -y unity-hub \
    && rm -rf /var/lib/apt/lists/*

# 安装特定Unity版本
RUN unity-hub install --version ${UNITY_VERSION} --changeset ${UNITY_CHANGESET} --module "windows-mono" "linux-mono" "android"

11. Unity 专用工具集成

Unity Cloud Build 替代方案

设置一个带有 Web UI 的构建服务器:

services:
  unity-build-server:
    build:
      context: .
      dockerfile: Dockerfile.build-server
    ports:
      - "8080:8080"
    volumes:
      - unity_projects:/projects
      - unity_builds:/builds
      - unity_cache:/root/.cache/unity3d
    environment:
      - UNITY_USERNAME=${UNITY_USERNAME}
      - UNITY_PASSWORD=${UNITY_PASSWORD}
      - UNITY_SERIAL=${UNITY_SERIAL}
      
  unity-build-agent:
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
      - unity-build-server
    volumes:
      - unity_projects:/unity_project
      - unity_builds:/builds
      - unity_cache:/root/.cache/unity3d
    environment:
      - UNITY_USERNAME=${UNITY_USERNAME}
      - UNITY_PASSWORD=${UNITY_PASSWORD}
      - UNITY_SERIAL=${UNITY_SERIAL}
      - BUILD_SERVER_URL=http://unity-build-server:8080

volumes:
  unity_projects:
  unity_builds:
  unity_cache:

12. GPU 支持 (高级)

在支持 NVIDIA GPU 的主机上,使用 NVIDIA Docker 运行时:

services:
  unity-gpu:
    build:
      context: .
      dockerfile: Dockerfile.gpu
    container_name: unity-gpu
    volumes:
      - ./:/unity_project
    environment:
      - UNITY_USERNAME=${UNITY_USERNAME}
      - UNITY_PASSWORD=${UNITY_PASSWORD}
      - UNITY_SERIAL=${UNITY_SERIAL}
      - DISPLAY=${DISPLAY}
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

Dockerfile.gpu:

FROM nvidia/cuda:11.8.0-devel-ubuntu22.04

# ... Unity安装过程 ...

# 安装 NVIDIA 图形驱动
RUN apt-get update && apt-get install -y \
    mesa-utils \
    libgl1-mesa-glx \
    libvulkan1 \
    nvidia-opencl-dev \
    && rm -rf /var/lib/apt/lists/*

# ... 其余安装过程 ...

13. 实际使用场景示例

场景1: 持续集成工作流

# 准备环境变量
echo "UNITY_USERNAME=your_email@example.com" > .env
echo "UNITY_PASSWORD=your_password" >> .env
echo "UNITY_SERIAL=your_serial_key" >> .env

# 运行测试
docker-compose --env-file .env run --rm unity-test

# 构建Linux版本
docker-compose --env-file .env run --rm unity-builder

# 构建Windows版本
docker-compose --env-file .env --profile windows run --rm unity-builder-windows

# 构建Android版本
docker-compose --env-file .env --profile android run --rm unity-builder-android

场景2: 游戏服务器部署

# 构建服务器镜像
docker build -t my-game-server -f Dockerfile.server .

# 运行游戏服务器容器
docker run -d -p 7777:7777 --name game-server my-game-server

14. 疑难解答与常见问题

许可证问题

Unity 需要有效的许可证。使用环境变量或授权文件:

# 使用授权文件
COPY Unity_v2022.x.ulf /root/.local/share/unity3d/Unity/Unity_lic.ulf

# 或者使用账户登录
export UNITY_USERNAME=your_email@example.com
export UNITY_PASSWORD=your_password
export UNITY_SERIAL=your_serial_key

构建失败问题

常见错误包括权限问题和缺少依赖:

# 检查Unity日志
docker-compose logs unity-builder

# 进入容器调试
docker-compose run --rm unity-builder bash

总结

虽然 Docker 化 Unity 开发环境有一定挑战,但它为自动化构建、测试和 CI/CD 流程提供了强大基础。这种方法特别适合:

  1. 持续集成系统中自动构建游戏项目
  2. 在多个平台上进行自动化测试
  3. 部署游戏服务器
  4. 标准化团队构建环境

通过上述配置,您可以创建一个完全自动化的 Unity 构建管道,显著提高开发效率,确保构建质量和一致性。特别是对于大型团队和需要频繁构建的项目,这种方法可以节省大量时间和资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小宝哥Code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值