文档

​
​

Development

User Acquisition

Monetization

工业

Cloud Code

Open Unity Dashboard

Cloud Code

LiveOps
​
​
Cloud Code
  • Overview
  • Get started
  • Server authority
  • Cloud Code C# modules
    • Overview
    • Get started
    • Concepts
      • Authentication
      • Module structure
      • Token support
      • Error handling
      • Module reference files
    • Tutorials
    • Reference
  • Cloud Code JavaScript scripts
  • Logging
  • Use-case samples
  • Privacy and consent
  1. Cloud Code

模块结构

Understand the structure of a Cloud Code module project and how it exposes endpoints.
阅读时间16 分钟
最后更新于 8 个月前

Cloud Code 模块是简单的 .NET 项目,其中公开了游戏客户端可以调用的终端。模块采用与 .NET 类库类似的范式。例如,一个标准 C# 类可能如下所示:
namespace ModulesExample;public class Example{ private static string[] GetCheatCodes() { return new string[] { "LEAVEMEALONE", "ASPIRINE", "BIGBANG" }; } public void ChangeHaircut(string haircutName) { }}
编译后,任何对
Example
类的引用都只能使用
ChangeHaircut()
方法。
using ModulesExample;class UsageExample{ public void GameLoop() { Example.ChangeHaircut("buzzcut"); // Compile error "Cannot access private method 'GetCheatCodes()' here" var cheatCodes = Example.GetCheatCodes(); }}
开发者可以通过访问修饰符选择库接口。Cloud Code 模块的工作方式相同,但使用的是
[CloudCodeFunction("ChangeHaircut")]
属性。
借助 Cloud Code 模块,您可以创建独立的服务器授权库。因此,您可以在服务器上运行游戏逻辑,并从客户端调用游戏逻辑,从而将游戏逻辑与客户端分离并提高安全性。模块支持代码重用,并提供可用于管理游戏逻辑的接口。

C# 项目

Cloud Code 模块项目是类库 C# 项目。此项目也可以是某个解决方案的一部分。最简单的项目结构如下所示:
├─ Main.csproj └─ Dependencies └─ HelloWorld.cs
如果是在一个解决方案中,可能如下所示:
Sample.sln├─ Main.csproj └─ Dependencies └─ HelloWorld.cs
这个解决方案还可以包含相互引用的多个项目。因此,您可以轻松添加测试项目,并启用代码重用。以下示例显示了一个有效的项目结构:
Sample.sln├─ Main.csproj └─ Dependencies └─ HelloWorld.cs├─ Tests.csproj └─ Dependencies └─ Tests.cs├─ Other.csproj └─ Dependencies └─ Class1.cs
但是,只有主项目可以包含 Cloud Code 函数。
请参阅编写单元测试,详细了解如何为 Cloud Code 模块编写单元测试。
请参阅 Cloud Code 限制,了解适用的存储限制。

主项目

尽管解决方案可以包含多个 C# 项目,但每个模块只能有一个主项目。主项目包含所有模块入口点(即具有
CloudCodeFunction
属性的函数)。
警告
重要:如果您将任何具有
CloudCodeFunction
属性的函数置于主项目外部,则 Cloud Code 服务不会将此类函数识别为入口点。
主项目也是您部署到 Cloud Code 服务的项目。主项目中未引用的项目和依赖项不会部署到 Cloud Code 服务。
您需要让主项目的名称与部署到 Cloud Code 服务的存档文件的名称匹配。
注意
注意:您可以创建一个包含多个 Cloud Code 模块主项目的解决方案。在这种情况下,每个主项目对应一个不同的模块。

示例项目

最简单的模块项目可以具有以下结构:
Sample.sln├─ Main.csproj └─ Dependencies └─ HelloWorld.cs
以下示例定义的 Cloud Code 模块包含一个返回
Hello World!
字符串的
Hello
函数:
using Unity.Services.CloudCode.Core;namespace Sample;public class HelloWorld{ [CloudCodeFunction("Hello")] public string PrintHello() { return "Hello World!"; }}

Cloud Code NuGet 包

作为 .NET 项目,Cloud Code 模块项目也使用 NuGet 来共享打包的代码。
要了解有关 NuGet 的更多信息,请参阅 Microsoft 文档。
Cloud Code 提供了两个可以包含在模块中的包:
  • com.Unity.Services.CloudCode.Core
    :此包中包含 Cloud Code 的核心功能,包括
    CloudCodeFunction
    属性。所有 Cloud Code 模块都需要此包。
  • com.Unity.Services.CloudCode.Apis
    :这是一个可选包,其中包含可用于与 Cloud Code 服务交互的 Unity Gaming Services(Unity 游戏服务)API。您可以使用此包调用其他 Cloud Code SDK,例如 Cloud Save。
如需了解更多信息,请参阅有关如何使用 Jetbrains Rider 或 Visual Studio 在项目中安装和使用 NuGet 包的文档。
注意
注意:还可以安装要在模块项目中使用的任何外部 NuGet 包。如需了解更多信息,请参阅与外部服务集成。

代码结构

为了避免代码结构问题,请遵循以下准则。

CloudCodeFunction 属性

要将方法标记为 Cloud Code 函数并使其成为可行的 Cloud Code 模块终端,请使用
CloudCodeFunction
属性。您只能在模块的主类中使用 Cloud Code 函数属性。
为了调用该函数,需要调用属性的名称。

方法签名

使用以下结构作为模块函数的方法签名。
[CloudCodeFunction("FunctionName")]public async Task<ReturnType> FunctionName(IGameApiClient gameApiClient, IExecutionContext ctx, string parameter1, string parameter2){ ...}
警告
重要:
async void
模式会导致错误。始终返回
Task
或
Task<T>
。请参阅官方 Microsoft 文档以了解有关异步编程的最佳做法。
警告
重要:Cloud Code 不支持 Cloud Code 函数的静态方法。

对模块使用单例模式

您可以使用单例模式来与 Cloud Code C# 包和外部服务调用进行集成。单例模式可提高 Cloud Code 中的性能和可扩展性,并确保您不会为同一对象创建多个实例。
您可以使用依赖项注入将
IGameApiClient
和
IPushClient
接口注入到模块中。
警告
重要:不要依赖模块函数调用之间的共享状态,因为当有多个工作线程时,不能保证 API 调用会落在同一个工作线程上。
警告
重要:Cloud Code 工作线程的内存限制为 256 MB。超过此限制的工作线程最终会崩溃。

传递参数

您可以将参数传递给模块函数。

原始类型和复杂类型

包括任何原始类型(例如
int
、
string
、
bool
和
float
)以及复杂类型(例如
List<T>
、
Dictionary<T>
和
Dictionary<string, T>
)。
例如,可以将
string
和
List<string>
传递给模块函数:
{ "params": { "parameter1": "a", "parameter2": ["b", "c"] }}
定义具有相同参数的模块函数:
[CloudCodeFunction("SimpleParams")]public async Task SimpleParams(IExecutionContext ctx, string parameter1, List<string> parameter2){ return parameter1 + parameter2[0] + parameter2[1];}

自定义类型

您还可以传递在模块项目中定义的任何自定义类型。
例如,可以将 JSON 对象传递给模块对象:
{ "params": { "player": { "name": "player", "health": 50, "stamina": 20, "inventory": { "count": 5, "weight": 20 } } }}
在您的模块项目中定义一个
Player
和
Inventory
类和一个函数:
public class Player{ public string Name { get; set; } public int Health { get; set; } public int Stamina { get; set; } public Inventory Inventory { get; set; }}public class Inventory{ public int Count { get; set; } public int Weight { get; set; }}[CloudCodeFunction("CustomParams")]public async Task<string> CustomParams(IExecutionContext ctx, Player player){ return $"{player.Name} has {player.Health} health and {player.Stamina} stamina and {player.Inventory.Count} items in their inventory with a total weight of {player.Inventory.Weight}";}

可用接口

Cloud Code 模块可以使用
IGameApiClient
、
IAdminApiClient
、
IPushClient
和
IExecutionContext
接口来扩展模块的功能。
ICloudCodeSetup
接口可用于管理模块的依赖项。请在依赖项注入文档中了解更多相关信息。

IGameApiClient 接口

IGameApiClient
接口提供了一种访问 Cloud Code C# Client SDK 的方法。您可以使用依赖项注入将
IGameApiClient
注入到模块中。
  1. 定义一个实现
    ICloudCodeSetup
    接口的类,并添加
    GameApiClient
    为单例:
    public class ModuleConfig : ICloudCodeSetup { public void Setup(ICloudCodeConfig config) { config.Dependencies.AddSingleton(GameApiClient.Create()); } }
  2. 将
    IGameApiClient
    接口作为函数参数传入模块函数。

IAdminApiClient 接口

IAdminApiClient
接口提供了一种访问 Cloud Code C# Admin SDK 的方法。您可以使用依赖项注入将
IAdminApiClient
注入到模块中。
  1. 定义一个实现
    ICloudCodeSetup
    接口的类,并添加
    AdminApiClient
    为单例:
    public class ModuleConfig : ICloudCodeSetup { public void Setup(ICloudCodeConfig config) { config.Dependencies.AddSingleton(AdminApiClient.Create()); } }
  2. 将
    IAdminApiClient
    接口作为函数参数传入模块函数。

IPushClient 接口

IPushClient
接口提供了一种向玩家发送推送通知的方法。您可以使用依赖项注入将
IPushClient
注入到模块中。
  1. 定义一个实现
    ICloudCodeSetup
    接口的类,并添加
    PushClient
    为单例:
    public class ModuleConfig : ICloudCodeSetup { public void Setup(ICloudCodeConfig config) { config.Dependencies.AddSingleton(PushClient.Create()); } }
  2. 将
    PushClient
    对象作为函数参数传入模块函数。
要详细了解如何从 Cloud Code 发送推送消息,请参阅推送消息。

IExecution 上下文

要在模块中调用其他 UGS 服务,可以使用
IExecutionContext
接口获取有关当前调用的额外信息。您可以使用以下值访问服务 SDK,并查看哪个玩家发出了请求。
  • ProjectId
    :调用方通过身份验证的 Project ID。
  • PlayerId
    :执行脚本的玩家 ID。注意:当服务调用脚本时,玩家 ID 不可用。
  • EnvironmentId
    :模块的环境 ID。
  • EnvironmentName
    :模块的环境名称。
  • AccessToken
    :玩家用于向 Cloud Code 进行身份验证的 JSON Web Token (JWT) 凭据。
  • UserId
    :服务帐户的用户 ID(注意:当服务调用脚本时,用户 ID 不可用)。
  • Issuer
    :签发者或服务帐户令牌(注意:当玩家调用脚本时,签发者不可用)。例如,如果 Multiplay 发出调用,则签发者为
    multiplay
    。
  • ServiceToken
    :Cloud Code 服务帐户 JWT 凭据。
  • AnalyticsUserId
    :玩家的 Analytics 用户 ID(注意:当服务调用脚本时,Analytics 用户 ID 不可用)。
  • UnityInstallationId
    :玩家的 Unity 设备安装 ID(注意:当服务调用脚本时,Unity 安装 ID 不可用)。
您可以使用执行上下文获取玩家 ID 并向不同的 Unity Gaming Services(Unity 游戏服务)进行身份验证。您可以通过类的构造函数以及具有
CloudCodeFunction
属性的任何方法获取执行上下文。
例如,您可以使用执行上下文来调用 Cloud Save 获取玩家密钥:
using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Logging;using Unity.Services.CloudCode.Apis;using Unity.Services.CloudCode.Core;using Unity.Services.CloudCode.Shared;namespace Sample;public class HelloWorld{ private static ILogger<HelloWorld> _logger; public CloudSaveSdkSample(ILogger<HelloWorld> logger) { _logger = logger; } [CloudCodeFunction("GetData")] public async Task<object> GetData(IExecutionContext context, IGameApiClient gameApiClient, string key) { try { var result = await gameApiClient.CloudSaveData.GetItemsAsync(context, context.AccessToken, context.ProjectId, context.PlayerId, new List<string> { key }); return result.Data.Results.First().Value; } catch (ApiException ex) { _logger.LogError("Failed to get data from Cloud Save. Error: {Error}", ex.Message); throw new Exception($"Failed to get data for playerId {ctx.PlayerId}. Error: {e.Message}"); } } public class ModuleConfig : ICloudCodeSetup { public void Setup(ICloudCodeConfig config) { config.Dependencies.AddSingleton(GameApiClient.Create()); } }}

令牌身份验证

AccessToken
和
ServiceToken
是 JWT,也是
IExecutionContext
接口的属性。
您可以使用这些令牌对 Cloud Code 的其他 Unity Gaming Services(Unity 游戏服务)调用进行身份验证。

令牌类型

来源

数据访问

用途

accessToken
由 Authentication 服务生成。仅限经过身份验证的玩家。
AccessToken
是用于对 Cloud Code 调用进行身份验证的 JWT。您可以将此令牌传递给其他 UGS 服务来访问经过身份验证的玩家的数据。
serviceToken
由 Cloud Code 生成。跨玩家数据访问。
ServiceToken
是用于调用其他 UGS 服务并处理跨玩家数据的令牌。
您配置的任何访问控制规则都会影响
AccessToken
。
以下示例显示了如何使用
AccessToken
通过 Cloud Save 访问经过身份验证的玩家的数据:
using Microsoft.Extensions.DependencyInjection;using Unity.Services.CloudCode.Apis;using Unity.Services.CloudCode.Core;using Unity.Services.CloudCode.Shared;using Unity.Services.CloudSave.Model;namespace TokenSample;public class TokenSample{ [CloudCodeFunction("GetKeysForAuthenticatedPlayer")] public Task<ApiResponse<GetKeysResponse>> GetPlayerKeys(IExecutionContext ctx, IGameApiClient gameApiClient) { try { // Using ctx.AccessToken to access the data for the player calling the function return gameApiClient.CloudSaveData.GetKeysAsync(ctx, ctx.AccessToken, ctx.ProjectId, ctx.PlayerId); } catch (ApiException e) { throw new Exception($"Failed to get keys for playerId {ctx.PlayerId}. Error: {e.Message}"); } } public class ModuleConfig : ICloudCodeSetup { public void Setup(ICloudCodeConfig config) { config.Dependencies.AddSingleton(GameApiClient.Create()); } }}
要访问所有玩家的数据,您可以使用
ServiceToken
并传入
playerId
的参数:
using Microsoft.Extensions.DependencyInjection;using Unity.Services.CloudCode.Apis;using Unity.Services.CloudCode.Core;using Unity.Services.CloudCode.Shared;using Unity.Services.CloudSave.Model;namespace TokenSample;public class TokenSample{ [CloudCodeFunction("GetKeysForAnyPlayer")] public Task<ApiResponse<GetKeysResponse>> GetPlayerKeys(IExecutionContext ctx, IGameApiClient gameApiClient, string playerId) { try { // Using ctx.ServiceToken to access the data for any player return gameApiClient.CloudSaveData.GetKeysAsync(ctx, ctx.ServiceToken, ctx.ProjectId, playerId); } catch (ApiException e) { throw new Exception($"Failed to get keys for playerId {ctx.PlayerId}. Error: {e.Message}"); } } public class ModuleConfig : ICloudCodeSetup { public void Setup(ICloudCodeConfig config) { config.Dependencies.AddSingleton(GameApiClient.Create()); } }}
如需了解这两个令牌之间差异的深入说明,请参阅服务和访问令牌文档。

Cloud Code 模块元数据

要获取 Cloud Code 模块及其元数据,您可以向 Cloud Code 服务发送
GET
请求。响应是具有以下结构的 JSON 对象:
{ "name": "string", "language": "CS", "tags": { "property1": "string", "property2": "string" }, "signedDownloadURL": "string", "dateCreated": "2022-04-05T09:12:13Z", "dateModified": "2022-04-05T09:12:13Z"}

标签

标签是可以附加到 Cloud Code 模块的键/值对。您可以在标签中记录所需的任何信息,例如模块的版本、作者或提交哈希(如果使用版本控制)。
模块最多可以存储 10 个标签,每个标签键和标签值最多可以使用 128 个字符。
注意
注意:仅当您使用 Cloud Code API 进行创作时才支持自定义标签。使用 Unity Gaming Services(Unity 游戏服务)CLI 和 Unity 编辑器进行创作时,Cloud Code 会忽略标签。

签名下载 URL

签名下载 URL (Signed Download URL) 是一种可用于下载模块存档文件的临时 URL。

Copyright © 2026 Unity Technologies
法律信息隐私政策CookiesDocumentation Terms of Use请勿出售或分享我的个人信息您的隐私选择(Cookie 设置)

“Unity”、Unity 徽标及其他 Unity 商标是 Unity Technologies 或其附属公司在美国和其他地方的商标或注册商标(此处查看更多信息)。其他名称或品牌是其各自所有者的商标。

为方便起见,一些页面是机器翻译的,可能包含不准确的内容。如有信息不一致的情况,以英文版本为准。

  • 在本页上
    • C# 项目

      • 主项目

      • 示例项目

    • Cloud Code NuGet 包

    • 代码结构

      • CloudCodeFunction 属性

      • 方法签名

      • 对模块使用单例模式

    • 传递参数

      • 原始类型和复杂类型

      • 自定义类型

    • 可用接口

      • IGameApiClient 接口

      • IAdminApiClient 接口

      • IPushClient 接口

      • IExecution 上下文

        • 令牌身份验证

    • Cloud Code 模块元数据

      • 标签

      • 签名下载 URL


报告此页面的问题