# 行为事件上报

> 来源：https://help.gravity-engine.com/docs/client-sdk/unity/track-events
> 说明如何使用 Gravity Engine Unity SDK 上报业务事件，并管理事件公共属性。



本文档详细介绍了 SDK 提供的事件上报功能，帮助开发者全面采集用户行为事件数据，为业务分析和运营决策提供数据支持。

通过上报应用内用户行为事件，您可以：

* **完整记录用户行为**：追踪用户在应用内的关键操作路径
* **支持多维度分析**：通过事件属性丰富分析维度
* **构建数据闭环**：为产品优化和精准运营提供数据基础

通过 `GravityEngineAPI.Track()` 可以上报事件及其属性。一般情况下，您可能需要上传十几到上百个不同的事件，如果您是第一次使用引力引擎事件采集系统，我们推荐您先上传几个关键事件。

我们也支持了若干自动采集事件，包括游戏启动、关闭、异常、小游戏添加收藏、Unity 场景加载或者卸载等事件，您可以根据业务需求选择是否开启自动采集事件。

## 1. 自定义事件上报 [#1-自定义事件上报]

> **如需上报自定义事件，您必须先在[元事件](https://web.gravity-engine.com/#/manage/metadata/metaEvent)中添加，否则会上报失败！**

您必须先在[元事件](https://web.gravity-engine.com/#/manage/metadata/metaEvent)中添加自定义事件，然后在游戏中指定位置埋点调用 `Track` 方法上报自定义事件。

```csharp
Dictionary<string, object> properties = new Dictionary<string, object>();
properties["channel"] = "base"; // 字符串，长度不超过 2048
properties["age"] = 1; // 数字
properties["isVip"] = true; // 布尔
properties["birthday"] = DateTime.Now; // 时间
properties["movies"] = new List<string>() { "Interstellar", "The Negro Motorist Green Book" }; // 字符串元素的数组，最大元素个数为 500

GravityEngineAPI.Track("TEST_EVENT_NAME", properties);
```

* 事件名称是 `string` 类型，只能以字母开头，可包含数字、字母和下划线（\_），长度最大为 50 个字符。
* 事件属性是 `Dictionary<string, object>` 类型，其中每个元素代表一个属性。
  * 事件属性 `Key` 为属性名称，为 `string` 类型，规定只能以字母开头，包含数字、字母和下划线（\_），长度最大为 50 个字符。
  * 属性 `Value` 支持 `string`、`int`、`float`、`bool`、`DateTime`、`List<string>`。

当您调用 `Track()` 时，SDK 会取系统当前时间作为事件发生的时刻，如果您需要指定事件时间，可以传入 `DateTime` 类型的参数来设置事件触发时间。

SDK 提供了时间校准接口，允许使用服务器时间对 SDK 时间进行校准，具体请参考 Demo 中对 `CalibrateTime` 和 `CalibrateTimeWithNtp` 方法的使用。

> **尽管事件可以设置触发时间，但是接收端会做如下的限制：只接收相对服务器时间在前 10 天至后 1 小时的数据，超过时限的数据将会被视为异常数据，整条数据无法入库！**

## 2. 公共属性 [#2-公共属性]

公共事件属性指的就是每个事件都会带有的属性，对于一些重要的属性，譬如玩家的区服和渠道等，这些属性需要设置在每个事件中，此时您可以将这些属性设置为公共事件属性。

> **公共属性需要先在[事件属性](https://web.gravity-engine.com/#/manage/metadata/eventProperty)中添加，否则会上报失败！**

### 设置公共属性 [#设置公共属性]

您可以调用 `SetSuperProperties` 来设置公共事件属性，我们推荐您在发送事件前，先设置公共事件属性。

```csharp
Dictionary<string, object> superProperties = new Dictionary<string, object>()
{
    {"SERVER", 0},
    {"CHANNEL", "A3"}
};
GravityEngineAPI.SetSuperProperties(superProperties);
```

公共事件属性将会被保存到缓存中，无需每次启动 APP 时调用。如果调用 `SetSuperProperties` 上传了先前已设置过的公共事件属性，则会覆盖之前的属性。如果公共事件属性和 `Track()` 上传的某个属性的 Key 重复，则该事件的属性会覆盖公共事件属性。

### 删除公共属性 [#删除公共属性]

如果您需要删除某个公共事件属性，可以调用 `UnsetSuperProperty` 清除其中一个公共事件属性。

```csharp
// 清除属性名为 CHANNEL 的公共属性
GravityEngineAPI.UnsetSuperProperty("CHANNEL");
```

### 清空公共属性 [#清空公共属性]

如果您想要清空所有公共事件属性，则可以调用 `ClearSuperProperties`。

```csharp
// 清空所有公共属性
GravityEngineAPI.ClearSuperProperties();
```

### 获取公共属性 [#获取公共属性]

如果您想要获取所有公共事件属性，可以调用 `GetSuperProperties`。

```csharp
// 获取所有公共属性
GravityEngineAPI.GetSuperProperties();
```

## 3. 记录事件时长 [#3-记录事件时长]

如果您需要记录某个事件持续时长，您可以调用 `TimeEvent()` 来开始计时，配置您想要计时的事件名称，当您上传该事件时，将会自动在您的事件属性中加入 `$event_duration` 这一属性来表示记录的时长，单位为秒。

```csharp
// 调用 TimeEvent 开启对 TIME_EVENT 事件的计时
GravityEngineAPI.TimeEvent("TIME_EVENT");

// do some thing...

// 通过 Track 上传 TIME_EVENT 事件时，会在属性中添加 $event_duration 属性
GravityEngineAPI.Track("TIME_EVENT");
```

## 4. 立即上报事件 [#4-立即上报事件]

如果需要立即上报缓存的事件，可以调用 `Flush()` 来上报所有缓存的事件。

```csharp
// 调用 Flush() 上报缓存事件
GravityEngineAPI.Flush();
```
