Unity与Android Studio数据交互:从原生App传Token至Unity脚本
我刚好做过类似的Unity与Android原生集成的项目,给你分享下可行的解决方案:
1. 通过Intent向Unity脚本传递数据
这完全可行,分两种场景处理:
场景1:启动Unity库Activity时传递数据
在原生Android端启动Unity对应的Activity(通常是UnityPlayerActivity或你自定义的继承类)时,把数据存入Intent的Extra中,再在Unity的C#脚本中读取。
Android端代码(Kotlin示例):
val intent = Intent(this, UnityPlayerActivity::class.java) intent.putExtra("USER_TOKEN", yourEncryptedToken) // 可传加密或已解密的Token,按需选择 startActivity(intent)
Unity端C#代码:
在Unity的启动GameObject上挂载如下脚本,获取并读取Intent数据:
using UnityEngine; public class TokenHandler : MonoBehaviour { void Start() { // 获取Android当前Activity的Intent实例 AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); AndroidJavaObject intent = currentActivity.Call<AndroidJavaObject>("getIntent"); // 读取传递的Token if (intent.Call<bool>("hasExtra", "USER_TOKEN")) { string receivedToken = intent.Call<string>("getStringExtra", "USER_TOKEN"); Debug.Log("从Android端收到Token: " + receivedToken); // 后续用该Token处理服务器请求逻辑 } } }
场景2:UnityActivity已启动后传递数据
如果Unity已在后台运行,用UnityPlayer.UnitySendMessage直接调用Unity方法会比Intent更高效:
Android端发送数据:
// 参数说明:Unity中接收数据的GameObject名称、脚本中的方法名、传递的Token字符串 UnityPlayer.UnitySendMessage("TokenHandlerObject", "OnReceiveToken", decryptedToken)
Unity端接收方法:
public class TokenHandler : MonoBehaviour { // 方法名需与Android端调用的完全一致 public void OnReceiveToken(string token) { Debug.Log("通过UnitySendMessage收到Token: " + token); // 处理Token逻辑 } }
2. Unity中解密Token的可行方案
优先推荐在Android端解密后再传递给Unity,因为加密逻辑原本在原生层,解密也在原生层处理更安全,避免密钥等敏感信息暴露到Unity层。如果必须在Unity中解密,提供两种思路:
方案A:Android端解密后传递(推荐)
利用Encrypted SharedPreference的API在Android端解密Token,再通过上述UnitySendMessage传递:
Android端解密代码示例(Kotlin):
// 初始化加密SharedPreference val masterKey = MasterKey.Builder(this) .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) .build() val encryptedPrefs = EncryptedSharedPreferences.create( this, "your_encrypted_prefs_name", masterKey, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM ) // 获取并解密Token val decryptedToken = encryptedPrefs.getString("user_token", "") ?: "" // 传递给Unity UnityPlayer.UnitySendMessage("TokenHandlerObject", "OnReceiveToken", decryptedToken)
方案B:Unity端实现解密逻辑
如果必须在Unity中解密,要确保C#的解密算法与Android端Encrypted SharedPreference使用的完全一致(默认是AES-256-GCM/SIV组合)。但注意:Android的MasterKey存储在系统Keystore中,无法直接获取,这种方式存在安全风险,仅适合自定义加密场景(比如你自己管理密钥)。
Unity端AES解密示例(C#):
using System; using System.Security.Cryptography; using System.Text; public class TokenDecryptor { // 需保证key、iv、加密模式/填充方式与Android端完全一致 public static string DecryptAes(string encryptedToken, byte[] key, byte[] iv) { using (Aes aesAlg = Aes.Create()) { aesAlg.Key = key; aesAlg.IV = iv; aesAlg.Mode = CipherMode.CBC; aesAlg.Padding = PaddingMode.PKCS7; ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); byte[] encryptedBytes = Convert.FromBase64String(encryptedToken); byte[] decryptedBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length); return Encoding.UTF8.GetString(decryptedBytes); } } }
注意事项
- 安全层面:Token是敏感信息,尽量减少明文传递次数,在Android端解密后仅传递一次,用完及时销毁内存中的明文Token。
- 集成验证:确保Unity作为Library的集成步骤正确,
UnityPlayer类可正常调用。 - 数据类型:Intent传递优先用字符串,避免复杂对象带来的序列化问题。
内容的提问来源于stack exchange,提问作者Pankaj Sharma




