You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

2025年基于Unity 2022+与Android Studio将Unity项目嵌入现有原生Android应用的最新工作流问询

2025年基于Unity 2022+与Android Studio将Unity项目嵌入现有原生Android应用的最新工作流问询

作为长期深耕Unity-Android混合开发的开发者,我整理了2025年适配Unity 2022 LTS/2023/2024与Android Studio的完整嵌入工作流,覆盖导出、配置、启动全流程,同时针对近年版本的关键变更做了重点说明:


一、Unity 2022+ 正确导出为Android Library的步骤

近年Unity版本对Library导出流程做了标准化简化,以下是精准操作步骤:

  1. 基础平台与参数对齐设置

    • 打开Unity项目,进入File > Build Settings,选择Android平台后点击Switch Platform
    • 点击Build Settings窗口内的Player Settings,在Publishing Settings下勾选Export Project
    • 核心对齐操作:在Player Settings > Android > Other Settings中,将Minimum API LevelTarget API LevelCompile API Level设置为与你的原生Android项目完全一致的值(这是解决Gradle版本冲突的核心前提)
    • 禁用默认Activity:在Player Settings > Android > Other Settings > Identification中,清空Default Activity Name,避免与原生App的Activity冲突
  2. 导出方式选择(2023+新增AAR选项)

    • 对于Unity 2022 LTS:点击Build,选择导出目录,Unity会生成一个完整的Android模块项目
    • 对于Unity 2023/2024:推荐选择Export as Android Library (AAR),直接导出为轻量的AAR文件,简化后续导入流程

二、Android Studio中添加并引用Unity Library模块

方式1:导入Unity导出的模块项目(2022 LTS适用)

  1. 打开原生Android项目,选择File > New > Import Module,选中Unity导出的目录
  2. 检查项目根目录的settings.gradle,确保自动添加了include ':unityLibrary'且路径正确
  3. 在原生App的**Module级别build.gradle**中添加依赖:
    dependencies {
        // 引用Unity Library模块
        implementation project(':unityLibrary')
        // 导入Unity libs目录下的所有依赖
        implementation fileTree(dir: project(':unityLibrary').file('libs'), include: ['*.jar', '*.aar'])
    }
    

方式2:导入Unity导出的AAR(2023+推荐)

  1. 将Unity导出的unityLibrary.aar复制到原生App的app/libs目录下
  2. 在原生App的Module级别build.gradle中添加:
    dependencies {
        implementation files('libs/unityLibrary.aar')
        implementation fileTree(dir: 'libs', include: ['*.jar'])
    }
    

统一Gradle配置对齐(必须操作)

在原生App的Module级别build.gradle中添加以下配置解决资源与库冲突:

android {
    // 对齐Unity的编译版本
    compileSdkVersion 34 // 需与Unity的Compile API Level完全一致
    defaultConfig {
        minSdkVersion 21 // Unity 2022+最低强制要求,必须与Unity设置一致
        targetSdkVersion 34 // 与Unity的Target API Level完全一致
    }

    // 合并Unity的JNI库
    sourceSets {
        main {
            // 模块导入时的配置
            jniLibs.srcDirs += project(':unityLibrary').file('src/main/jniLibs')
            // AAR导入时替换为:jniLibs.srcDirs += 'libs/jniLibs'
        }
    }

    // 处理资源与库冲突
    packagingOptions {
        pickFirst '**/libc++_shared.so'
        pickFirst '**/libunity.so'
        pickFirst '**/libmain.so'
        exclude 'META-INF/*.kotlin_module'
        exclude 'META-INF/DEPENDENCIES'
    }
}

三、在Activity/Fragment中启动UnityPlayer的推荐方式

1. 在Activity中嵌入(最稳定的生产级方案)

创建专门承载Unity的Activity,必须正确传递生命周期给UnityPlayer:

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.unity3d.player.UnityPlayer

class UnityHostActivity : AppCompatActivity() {
    private lateinit var unityPlayer: UnityPlayer

    override fun onCreate(savedInstanceState: Bundle?) {
        // 核心注意:必须在super.onCreate之前初始化UnityPlayer
        unityPlayer = UnityPlayer(this)
        super.onCreate(savedInstanceState)
        supportActionBar?.hide()
        // 将UnityPlayer视图设置为Activity内容
        setContentView(unityPlayer)
    }

    // 必须重写以下生命周期方法,传递给UnityPlayer
    override fun onResume() {
        super.onResume()
        unityPlayer.resume()
    }

    override fun onPause() {
        super.onPause()
        unityPlayer.pause()
    }

    override fun onDestroy() {
        unityPlayer.quit() // 必须释放Unity资源避免内存泄漏
        super.onDestroy()
    }

    override fun onBackPressed() {
        // 优先让Unity处理返回键事件
        if (unityPlayer.back()) return
        super.onBackPressed()
    }
}

2. 在Fragment中嵌入(需注意生命周期管理)

Fragment中嵌入需要更谨慎的资源释放逻辑,避免内存泄漏:

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.unity3d.player.UnityPlayer

class UnityHostFragment : Fragment() {
    private var unityPlayer: UnityPlayer? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // 仅在创建视图时初始化UnityPlayer
        unityPlayer = UnityPlayer(requireContext())
        return unityPlayer?.view
    }

    override fun onResume() {
        super.onResume()
        unityPlayer?.resume()
    }

    override fun onPause() {
        super.onPause()
        unityPlayer?.pause()
    }

    override fun onDestroyView() {
        // 视图销毁时立即释放Unity资源
        unityPlayer?.quit()
        unityPlayer = null
        super.onDestroyView()
    }
}

四、Unity 2022-2024导出流程的重大变更(必须知晓)

  1. Gradle模板升级:Unity 2022+使用AGP 7.0+,导出的build.gradle采用新格式,统一使用implementation替代旧的compile关键字
  2. UnityPlayer初始化简化:不再需要复制UnityPlayerActivity到原生项目,直接使用com.unity3d.player.UnityPlayer类,构造函数仅需Context参数
  3. minSdk强制要求:Unity 2022 LTS及以上最低支持API 21,原生App必须同步升级minSdk,无法再支持低于21的版本
  4. AAR导出支持:2023+新增直接导出AAR的选项,无需导入整个项目模块,大幅简化流程
  5. 资源合并逻辑变更:2023+导出的Library包含更多SO和资源文件,必须通过packagingOptions处理冲突

五、常见问题快速修复

1. minSdk/targetSdk版本不匹配

  • 解决方案:回到Unity的Player Settings,将版本参数与原生App完全对齐后重新导出
  • 禁止单独修改Gradle文件,必须从Unity端修改后导出,否则会被Unity的导出流程覆盖

2. 缺少UnityPlayer库或初始化失败

  • 检查Unity导出的模块/AAR中是否包含unity-classes.jarlibunity.so,若缺失则重新导出
  • 确保UnityPlayer的初始化在super.onCreate()之前执行(Activity场景)

3. 重复资源/库冲突

  • 严格按照上文的packagingOptions配置,pickFirst重复的SO文件,排除冲突的元数据文件

六、2025年可用的官方参考与示例

  1. Unity官方文档:选择Unity 2022 LTS/2023/2024版本的文档,查看《Unity as a Library for Android》章节(已更新至对应版本的流程)
  2. Unity官方示例:在Unity Package Manager中搜索并导入Unity as a Library示例项目,导出后可直接在Android Studio中测试
  3. Android Studio官方指南:参考Google官方的《Import third-party libraries》文档,Unity Library的导入逻辑与普通Android Library一致

总结:2025年的核心流程是「Unity端严格对齐原生App的版本参数 → 导出为模块/AAR → Android Studio中对齐Gradle配置 → 自定义Activity/Fragment承载UnityPlayer」。只要遵循版本对齐和生命周期传递的核心原则,就能解决绝大多数Gradle和初始化问题。

火山引擎 最新活动