购买管理

请按照以下分步教程了解基本SDK功能的使用。

显示商品目录

本教程介绍如何使用SDK方法在游戏内商店中显示以下商品:

  • 虚拟物品
  • 虚拟物品组
  • 捆绑包
  • 虚拟货币套餐

开始之前,请在发布商帐户中配置商品:

  1. 配置虚拟物品和虚拟物品组
  2. 配置虚拟货币套餐
  3. 配置捆绑包

本教程介绍以下逻辑的实现:

示例中的逻辑与界面比您实际在应用程序中的要简单得多。演示项目提供了一种可能的游戏内商店商品目录实现方案。

注:

目录中的每个商品示例显示以下内容:

  • 商品名称
  • 商品描述
  • 商品价格
  • 图片

如果游戏内商店中还存储了其他信息,也可以显示那些信息。

实现虚拟物品的显示

创建商品小组件

  1. 创建一个空游戏对象。方法是前往主菜单,然后选择GameObject > Create Empty
  2. Hierarchy面板拖动一个游戏对象到Project面板,以转换预制件中创建的游戏对象。
  3. 选择一个创建的预制件,然后在Inspector面板中单击Open Prefab
  4. 将以下UI元素添加为预制件子对象并配置其视觉显示:
    • 商品背景图片
    • 商品名称
    • 商品描述
    • 商品价格
    • 商品图片

下图为小组件结构的示例。

创建商品小组件脚本

  1. 创建一个继承自MonoBehaviour基类的脚本VirtualItemWidget
  2. 声明商品小组件界面元素的变量并Inspector面板中设置它们的值

小组件脚本的示例:

Copy
Full screen
Small screen
 1using UnityEngine;
 2using UnityEngine.UI;
 3
 4namespace Recipes
 5{
 6	public class VirtualItemWidget : MonoBehaviour
 7	{
 8		// Declaration of variables for UI elements
 9		
10		public Text NameText;
11
12		public Text DescriptionText;
13
14		public Text PriceText;
15
16		public Image IconImage;
17	}
18}

创建显示商品列表的页面

  1. 在场景上创建一个空游戏对象。方法是前往主菜单,然后选择GameObject > Create Empty
  2. 将以下UI元素添加为预制件子对象并配置其视觉显示:
    • 页面背景图片
    • 商品小组件显示区域

下图为页面结构的示例。

创建页面控制器

  1. 创建继承自MonoBehaviour基类的脚本VirtualItemsPage
  2. 声明以下变量:
    • WidgetsContainer — 小组件的容器
    • WidgetPrefab — 商品小组件预制件
  1. 将脚本与页面游戏对象关联:
    1. Hierarchy面板中选择一个对象。
    2. Inspector面板中,单击Add Component,然后选择一个VirtualItemsPage脚本。
  2. Inspector面板中设置变量的值。
  1. 通过在Start方法中调用XsollaLogin.Instance.SignIn SDK方法添加登录逻辑,并向其传入:
    • 用户名或邮箱地址,包含在username参数中
    • 用户密码,包含在password参数中
注:
在登录脚本示例中我们使用的是演示帐户的凭证(用户名:xsolla,密码:xsolla)。
    • rememberUser参数中记住帐户的标志
    • OnAuthenticationSuccess回调方法,用于成功的用户登录
    • OnError回调方法,用于发生错误的情况
  1. 添加获取商品列表的逻辑。在OnAuthenticationSuccess方法中调用XsollaStore.Instance.GetCatalog SDK方法,并向其传入:
    • 项目ID,包含在projectId参数中
注:
您可以在发布商帐户的项目设置中找到项目ID。脚本示例中,我们将值从SDK设置传入参数。
    • OnItemsRequestSuccess,用于成功的获取商品列表操作
    • OnError回调方法,用于发生错误的情况
    • 基于列表第一个商品的偏移量,包含在offset参数中
    • 加载商品的数量,包含在limit参数中
注:
offsetlimit参数非必需。它们用于分页 — 多页显示目录中的商品。页面上商品的最大数量是50。如果目录中包含的商品超过50个,则需要分页。
  1. OnItemsRequestSuccess方法中,添加为每个收到的商品创建小组件的逻辑:
    1. 实例化一个商品小组件预制件作为容器子对象。
    2. 将收到的VirtualItemWidget组件附加到widget变量上。
  1. 将以下数据传入商品小组件:
    1. storeItem.name变量值传入商品名元素。
    2. storeItem.description变量值传入商品描述元素。
    3. 实现以下逻辑来显示商品价格:
      • 如果storeItem.price变量的值不等于null,则该商品以真实货币形式销售。请以{amount} {currency}格式指定价格并将其传入小组件元素。
      • 如果storeItem.virtual_prices变量的值不等于null,则该商品以虚拟货币形式销售。请以{name}: {amount}格式指定价格并将其传入小组件元素。
注:
storeItem.virtual_prices变量是同一商品在不同货币下的价格数组。示例显示的是发布商帐户商店 > 虚拟物品中商品设置里指定的默认价格。
    1. 要显示商品图片,请使用ImageLoader.Instance.GetImageAsync工具方法并向其传入:
      • 图片URL。
      • 作为回调的匿名函数。在该函数中,将收到的精灵添加为商品图片。

页面控制器脚本示例:

Copy
Full screen
Small screen
 1uusing System.Linq;
 2using UnityEngine;
 3using Xsolla.Core;
 4using Xsolla.Login;
 5using Xsolla.Store;
 6
 7namespace Recipes
 8{
 9	public class VirtualItemsPage : MonoBehaviour
10	{
11		// Declaration of variables for containers and widget prefabs
12
13		public Transform WidgetsContainer;
14
15		public GameObject WidgetPrefab;
16
17		private void Start()
18		{
19			// Starting the authentication process
20
21			XsollaLogin.Instance.SignIn("xsolla", "xsolla", true, null, OnAuthenticationSuccess, OnError);
22		}
23
24		private void OnAuthenticationSuccess(string token)
25		{
26			// After successful authentication starting the request for catalog from store
27
28			XsollaStore.Instance.GetCatalog(XsollaSettings.StoreProjectId, OnItemsRequestSuccess, OnError, offset: 0, limit: 50);
29		}
30
31		private void OnItemsRequestSuccess(StoreItems storeItems)
32		{
33			// Iterating the items collection and assign values for appropriate ui elements
34
35			foreach (var storeItem in storeItems.items)
36			{
37				var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false);
38				var widget = widgetGo.GetComponent<VirtualItemWidget>();
39
40				widget.NameText.text = storeItem.name;
41				widget.DescriptionText.text = storeItem.description;
42
43				if (storeItem.price != null)
44				{
45					var realMoneyPrice = storeItem.price;
46					widget.PriceText.text = $"{realMoneyPrice.amount} {realMoneyPrice.currency}";
47				}
48				else if (storeItem.virtual_prices != null)
49				{
50					var virtualCurrencyPrice = storeItem.virtual_prices.First(x => x.is_default);
51					widget.PriceText.text = $"{virtualCurrencyPrice.name}: {virtualCurrencyPrice.amount}";
52				}
53
54				ImageLoader.Instance.GetImageAsync(storeItem.image_url, (url, sprite) => widget.IconImage.sprite = sprite);
55			}
56		}
57
58		private void OnError(Error error)
59		{
60			UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
61		}
62	}
63}

下图为脚本的运行结果。

实现虚拟物品组的显示

创建商品小组件

  1. 创建一个空游戏对象。方法是前往主菜单,然后选择GameObject > Create Empty
  2. Hierarchy面板拖动一个游戏对象到Project面板,以转换预制件中创建的游戏对象。
  3. 选择一个创建的预制件,然后在Inspector面板中单击Open Prefab
  4. 将以下UI元素添加为预制件子对象并配置其视觉显示:
    • 商品背景图片
    • 商品名称
    • 商品描述
    • 商品价格
    • 商品图片

下图为小组件结构的示例。

创建商品小组件脚本

  1. 创建一个继承自MonoBehaviour基类的脚本VirtualItemWidget
  2. 声明商品小组件界面元素的变量并Inspector面板中设置它们的值

小组件脚本的示例:

Copy
Full screen
Small screen
 1using UnityEngine;
 2using UnityEngine.UI;
 3
 4namespace Recipes
 5{
 6	public class VirtualItemWidget : MonoBehaviour
 7	{
 8		// Declaration of variables for UI elements
 9		
10		public Text NameText;
11
12		public Text DescriptionText;
13
14		public Text PriceText;
15
16		public Image IconImage;
17	}
18}

创建打开商品组按钮的小组件

  1. 创建一个空游戏对象。方法是前往主菜单,然后选择GameObject > Create Empty
  2. Hierarchy面板拖动一个游戏对象到Project面板,以转换预制件中创建的游戏对象。
  3. 选择一个创建的预制件,然后在Inspector面板中单击Open Prefab
  4. 将允许商品组显示的按钮添加为预制件的子对象并配置其视觉显示。

下图为小组件结构的示例。

创建打开商品组按钮的脚本

  1. 创建继承自MonoBehaviour基类的VirtualItemGroupButton脚本。
  2. 声明打开商品组按钮的变量,并在Inspector面板中设置变量的值。
  3. 向预制件的根对象添加一个脚本:
    1. Hierarchy面板中选择一个对象。
    2. Inspector面板中,单击Add Component,然后选择一个VirtualItemGroupButton脚本。

小组件脚本的示例:

Copy
Full screen
Small screen
 1using UnityEngine;
 2using UnityEngine.UI;
 3
 4namespace Recipes
 5{
 6	public class VirtualItemGroupButton : MonoBehaviour
 7	{
 8		// Declaration of variables for UI elements
 9		public Text NameText;
10
11		public Button Button;
12	}
13}

创建显示商品列表的页面

  1. 在场景上创建一个空游戏对象。方法是前往主菜单,然后选择GameObject > Create Empty
  2. 将以下UI元素添加为预制件子对象并配置其视觉显示:
    • 页面背景图片
    • 商品组按钮显示区域
    • 商品小组件显示区域

下图为页面结构的示例。

创建页面控制器

  1. 创建继承自MonoBehaviour基类的VirtualItemsByGroupsPage脚本。
  2. 声明变量:
    • GroupButtonsContainer — 组按钮的容器
    • GroupButtonPrefab — 按钮预制件
    • ItemWidgetsContainer — 商品小组件容器
    • WidgetPrefab — 商品小组件预制件
  1. 将脚本附加至页面游戏对象:
    1. Hierarchy面板中选择一个对象。
    2. Inspector面板中,单击Add Component,然后选择一个VirtualItemsByGroupsPage脚本。
  2. Inspector面板中设置变量的值。
  3. 通过在Start方法中调用XsollaLogin.Instance.SignIn SDK方法添加登录逻辑,并向其传入:
    • 用户名或邮箱地址,包含在username参数中
    • 用户密码,包含在password参数中
注:
在登录脚本示例中我们使用的是演示帐户的凭证(用户名:xsolla,密码:xsolla)。
    • rememberUser参数中记住帐户的标志
    • OnAuthenticationSuccess回调方法,用于成功的用户登录
    • OnError回调方法,用于发生错误的情况
  1. 添加获取商品列表的逻辑。在OnAuthenticationSuccess方法中调用XsollaStore.Instance.GetCatalog SDK方法,并向其传入:
    • 项目ID,包含在projectId参数中
注:
您可以在发布商帐户的项目设置中找到项目ID。脚本示例中,我们将值从SDK设置传入参数。
    • OnItemsRequestSuccess,用于成功的获取商品列表操作
    • OnError回调方法,用于发生错误的情况
    • 基于列表第一个商品的偏移量,包含在offset参数中
    • 加载商品的数量,包含在limit参数中
注:
offsetlimit参数非必需。它们用于分页 — 多页显示目录中的商品。页面上商品的最大数量是50。如果目录中包含的商品超过50个,则需要分页。
  1. OnItemsRequestSuccess方法中,添加形成商品组列表的逻辑:
    1. 从收到的商品列表中获取唯一组的列表。将其添加至显示所有商品(不论类别)的All元素。
    2. 删除所有子对象以清空按钮容器。方法是调用DeleteAllChildren方法,然后向其传入容器对象。
    3. 对于每个商品组:
      1. 实例化一个商品小组件预制件作为容器子对象。
      2. 将收到的VirtualItemGroupButton设置为groupButton变量。
      3. groupName变量值传入组名称元素。
      4. 向单击按钮的动作添加一个匿名方法。在该方法中,调用OnGroupSelected方法并将商品组的名称和商品列表作为参数传递。
    1. 要显示所有商品,请调用OnGroupSelected方法并传入All作为组名称。
  1. OnGroupSelected方法中,添加商品初始显示的逻辑:
    1. 创建itemsForDisplay变量并在商品组名称有All值时向其分配所有收到的商品。否则将组名称与groupName变量匹配的商品关联至itemsForDisplay变量。
    2. 删除所有子对象以清空按钮容器。方法是调用DeleteAllChildren方法,然后向其传入容器对象。
  1. 添加为每个收到的商品创建小组件的逻辑:
    1. 实例化一个商品小组件预制件作为容器子对象。
    2. 将收到的VirtualItemWidget组件附加到widget变量上。
  1. 将以下数据传入商品小组件:
    1. storeItem.name变量值传入商品名元素。
    2. storeItem.description变量值传入商品描述元素。
    3. 实现以下逻辑来显示商品价格:
      • 如果storeItem.price变量的值不等于null,则该商品以真实货币形式销售。请以{amount} {currency}格式指定价格并将其传入小组件元素。
      • 如果storeItem.virtual_prices变量的值不等于null,则该商品以虚拟货币形式销售。请以{name}: {amount}格式指定价格并将其传入小组件元素。
注:
storeItem.virtual_prices变量是同一商品在不同货币下的价格数组。示例显示的是发布商帐户商店 > 虚拟物品中商品设置里指定的默认价格。
    1. 要显示商品图片,请使用ImageLoader.Instance.GetImageAsync工具方法并向其传入:
      • 图片URL。
      • 作为回调的匿名函数。在该函数中,将收到的精灵添加为商品图片。
Copy
Full screen
Small screen
  1using System.Collections.Generic;
  2using System.Linq;
  3using UnityEngine;
  4using Xsolla.Core;
  5using Xsolla.Login;
  6using Xsolla.Store;
  7
  8namespace Recipes
  9{
 10	public class VirtualItemsByGroupsPage : MonoBehaviour
 11	{
 12		// Declaration of variables for containers and widget prefabs
 13		public Transform GroupButtonsContainer;
 14
 15		public GameObject GroupButtonPrefab;
 16
 17		public Transform ItemWidgetsContainer;
 18
 19		public GameObject ItemWidgetPrefab;
 20
 21		private void Start()
 22		{
 23			// Starting the authentication process
 24			XsollaLogin.Instance.SignIn("xsolla", "xsolla", true, null, onSuccess: OnAuthenticationSuccess, onError: OnError);
 25		}
 26
 27		private void OnAuthenticationSuccess(string token)
 28		{
 29			// After successful authentication starting the request for catalog from store
 30			XsollaStore.Instance.GetCatalog(XsollaSettings.StoreProjectId, OnItemsRequestSuccess, OnError, offset: 0, limit: 50);
 31		}
 32
 33		private void OnItemsRequestSuccess(StoreItems storeItems)
 34		{
 35			// Selecting the group’s name from items and order them alphabetical
 36			var groupNames = storeItems.items
 37				.SelectMany(x => x.groups)
 38				.GroupBy(x => x.name)
 39				.Select(x => x.First())
 40				.OrderBy(x => x.name)
 41				.Select(x => x.name)
 42				.ToList();
 43
 44			// Add group name for “all groups”, which will mean show all items regardless of group affiliation
 45			groupNames.Insert(0, "All");
 46
 47			// Clear container
 48			DeleteAllChildren(GroupButtonsContainer);
 49
 50			// Iterating the group names and creating ui-button for each
 51			foreach (var groupName in groupNames)
 52			{
 53				var buttonObj = Instantiate(GroupButtonPrefab, GroupButtonsContainer, false);
 54				var groupButton = buttonObj.GetComponent<VirtualItemGroupButton>();
 55
 56				groupButton.NameText.text = groupName;
 57				groupButton.Button.onClick.AddListener(() => OnGroupSelected(groupName, storeItems));
 58			}
 59
 60			// Calling method for redraw page
 61			OnGroupSelected("All", storeItems);
 62		}
 63
 64		private void OnGroupSelected(string groupName, StoreItems storeItems)
 65		{
 66			// Declaring variable for items which will display on page
 67			IEnumerable<StoreItem> itemsForDisplay;
 68			if (groupName == "All")
 69			{
 70				itemsForDisplay = storeItems.items;
 71			}
 72			else
 73			{
 74				itemsForDisplay = storeItems.items.Where(item => item.groups.Any(group => group.name == groupName));
 75			}
 76
 77			// Clear container
 78			DeleteAllChildren(ItemWidgetsContainer);
 79
 80			// Iterating the items collection and assign values for appropriate ui elements
 81			foreach (var storeItem in itemsForDisplay)
 82			{
 83				var widgetGo = Instantiate(ItemWidgetPrefab, ItemWidgetsContainer, false);
 84				var widget = widgetGo.GetComponent<VirtualItemWidget>();
 85
 86				widget.NameText.text = storeItem.name;
 87				widget.DescriptionText.text = storeItem.description;
 88
 89				if (storeItem.price != null)
 90				{
 91					var realMoneyPrice = storeItem.price;
 92					widget.PriceText.text = $"{realMoneyPrice.amount} {realMoneyPrice.currency}";
 93				}
 94				else if (storeItem.virtual_prices != null)
 95				{
 96					var virtualCurrencyPrice = storeItem.virtual_prices.First(x => x.is_default);
 97					widget.PriceText.text = $"{virtualCurrencyPrice.name}: {virtualCurrencyPrice.amount}";
 98				}
 99
100				ImageLoader.Instance.GetImageAsync(storeItem.image_url, (url, sprite) => widget.IconImage.sprite = sprite);
101			}
102		}
103
104		// Utility method for delete all children of container
105		private static void DeleteAllChildren(Transform parent)
106		{
107			var childList = parent.Cast<Transform>().ToList();
108			foreach (var childTransform in childList)
109			{
110				Destroy(childTransform.gameObject);
111			}
112		}
113
114		private void OnError(Error error)
115		{
116			UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
117		}
118	}
119}

页面控制器脚本示例:

实现捆绑包的显示

创建捆绑小组件

  1. 创建一个空游戏对象。方法是前往主菜单,然后选择GameObject > Create Empty
  2. Hierarchy面板拖动一个游戏对象到Project面板,以转换预制件中创建的游戏对象。
  3. 选择一个创建的预制件,然后在Inspector面板中单击Open Prefab
  4. 将以下UI元素添加为预制件子对象并配置其视觉显示:
    • 小组件背景图片
    • 捆绑包名称
    • 捆绑包描述
    • 捆绑包价格
    • 捆绑包内容描述(商品及其数量)
    • 捆绑包图片

下图为小组件结构的示例。

创建小组件脚本

  1. 创建一个继承自MonoBehaviour基类的脚本BundleWidget
  2. 声明商品小组件界面元素的变量并Inspector面板中设置它们的值

小组件脚本的示例:

Copy
Full screen
Small screen
 1using UnityEngine;
 2using UnityEngine.UI;
 3
 4namespace Recipes
 5{
 6	public class BundleWidget : MonoBehaviour
 7	{
 8		// Declaration of variables for UI elements
 9		public Text NameText;
10
11		public Text DescriptionText;
12
13		public Text PriceText;
14
15		public Text ContentText;
16
17		public Image IconImage;
18	}
19}

创建显示捆绑包的页面

  1. 在场景上创建一个空游戏对象。方法是前往主菜单,然后选择GameObject > Create Empty
  2. 将以下UI元素添加为预制件子对象并配置其视觉显示:
    • 页面背景图片
    • 捆绑包小组件显示区域

下图为页面结构的示例。

创建页面控制器

  1. 创建继承自MonoBehaviour基类的BundlesPage脚本。
  2. 声明变量:
    • WidgetsContainer — 小组件的容器
    • WidgetPrefab — 捆绑包小组件预制件
  1. 将脚本附加到页面游戏对象上:
    1. Hierarchy面板中选择一个对象。
    2. Inspector面板中,单击Add Component,然后选择一个BundlesPage脚本。
  1. Inspector面板中设置变量的值。
  2. 通过在Start方法中调用XsollaLogin.Instance.SignIn SDK方法添加登录逻辑,并向其传入:
    • 用户名或邮箱地址,包含在username参数中
    • 用户密码,包含在password参数中
注:
在登录脚本示例中我们使用的是演示帐户的凭证(用户名:xsolla,密码:xsolla)。
    • rememberUser参数中记住帐户的标志
    • OnAuthenticationSuccess回调方法,用于成功的用户登录
    • OnError回调方法,用于发生错误的情况
  1. 添加获取捆绑包列表的逻辑。在OnAuthenticationSuccess方法中调用XsollaStore.Instance.GetBundles SDK方法,并向其传入:
    • 项目ID,包含在projectId参数中
注:
您可以在发布商帐户的项目设置中找到项目ID。脚本示例中,我们将值从SDK设置传入参数。
    • OnItemsRequestSuccess回调方法,用于成功的获取捆绑包列表操作
    • OnError回调方法,用于发生错误的情况
  1. OnBundlesRequestSuccess方法中,添加为每个收到的捆绑包创建小组件的逻辑:
    1. 实例化一个商品小组件预制件作为容器子对象。
    2. 将收到的BundleWidget组件附加到widget变量上。
  1. 将以下数据传入捆绑包小组件:
    1. bundleItem.name变量值传入商品名称元素。
    2. bundleItem.description变量值传入商品描述元素。
    3. 实现以下逻辑来显示捆绑包内容:
      1. 用捆绑包中的每个商品组成一行,其中包含商品名称及其数量。该行的格式为{name} x {quantity}
      2. 将所有行组成一行,用换行符分隔。
      3. 将新行传入小组件元素。
    1. 实现以下逻辑以显示捆绑包价格:
      • 如果bundleItem.price变量的值不等于null,则该捆绑包以真实货币形式销售。请以{amount} {currency}格式指定价格并将其传入小组件元素。
      • 如果bundleItem.virtual_prices变量的值不等于null,则该捆绑包以虚拟货币形式销售。请以{name}: {amount}格式指定价格并将其传入小组件元素。
注:
bundleItem.virtual_prices变量是同一捆绑包在不同货币下的价格的数组。示例显示的是发布商帐户商店 > 捆绑包中商品设置里指定的默认价格。
    1. 要显示商品图片,请使用ImageLoader.Instance.GetImageAsync工具方法并向其传入:
      • 图片URL。
      • 作为回调的匿名函数。在该函数中,将收到的精灵添加为捆绑包图片。

页面控制器脚本示例:

Copy
Full screen
Small screen
 1using System.Linq;
 2using UnityEngine;
 3using Xsolla.Core;
 4using Xsolla.Login;
 5using Xsolla.Store;
 6
 7namespace Recipes
 8{
 9	public class BundlesPage : MonoBehaviour
10	{
11		// Declaration of variables for containers and widget prefabs
12		public Transform WidgetsContainer;
13
14		public GameObject WidgetPrefab;
15
16		private void Start()
17		{
18			// Starting the authentication process
19			XsollaLogin.Instance.SignIn("xsolla", "xsolla", true, null, onSuccess: OnAuthenticationSuccess, onError: OnError);
20		}
21
22		private void OnAuthenticationSuccess(string token)
23		{
24			// After successful authentication starting the request for bundles from store
25			XsollaStore.Instance.GetBundles(XsollaSettings.StoreProjectId, OnBundlesRequestSuccess, OnError);
26		}
27
28		private void OnBundlesRequestSuccess(BundleItems bundleItems)
29		{
30			// Iterating the bundles collection and assign values for appropriate ui elements
31			foreach (var bundleItem in bundleItems.items)
32			{
33				var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false);
34				var widget = widgetGo.GetComponent<BundleWidget>();
35
36				widget.NameText.text = bundleItem.name;
37				widget.DescriptionText.text = bundleItem.description;
38
39				var bundleContent = bundleItem.content.Select(x => $"{x.name} x {x.quantity}");
40				widget.ContentText.text = string.Join("\n", bundleContent);
41
42				if (bundleItem.price != null)
43				{
44					var realMoneyPrice = bundleItem.price;
45					widget.PriceText.text = $"{realMoneyPrice.amount} {realMoneyPrice.currency}";
46				}
47				else if (bundleItem.virtual_prices != null)
48				{
49					var virtualCurrencyPrice = bundleItem.virtual_prices.First(x => x.is_default);
50					widget.PriceText.text = $"{virtualCurrencyPrice.name}: {virtualCurrencyPrice.amount}";
51				}
52
53				ImageLoader.Instance.GetImageAsync(bundleItem.image_url, (url, sprite) => widget.IconImage.sprite = sprite);
54			}
55		}
56
57		private void OnError(Error error)
58		{
59			UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
60		}
61	}
62}

下图为脚本的运行结果。

实现虚拟货币套餐的显示

创建虚拟货币套餐的小组件

  1. 创建一个空游戏对象。方法是前往主菜单,然后选择GameObject > Create Empty
  2. Hierarchy面板拖动一个游戏对象到Project面板,以转换预制件中创建的游戏对象。
  3. 选择一个创建的预制件,然后在Inspector面板中单击Open Prefab
  4. 将以下UI元素添加为预制件子对象并配置其视觉显示:
    • 小组件背景图片
    • 套餐名称
    • 套餐描述
    • 套餐价格
    • 套餐图片

下图为小组件结构的示例。

创建小组件脚本

  1. 创建一个继承自MonoBehaviour基类的脚本VirtualCurrencyPackageWidget
  2. 声明商品小组件界面元素的变量并Inspector面板中设置它们的值

小组件脚本的示例:

Copy
Full screen
Small screen
 1using UnityEngine;
 2using UnityEngine.UI;
 3
 4namespace Recipes
 5{
 6	public class VirtualCurrencyPackageWidget : MonoBehaviour
 7	{
 8		// Declaration of variables for UI elements
 9
10		public Text NameText;
11
12		public Text DescriptionText;
13
14		public Text PriceText;
15
16		public Image IconImage;
17	}
18}

创建显示虚拟货币套餐的页面

  1. 在场景上创建一个空游戏对象。方法是前往主菜单,然后选择GameObject > Create Empty
  2. 将以下UI元素添加为预制件子对象并配置其视觉显示:
    • 页面背景图片
    • 虚拟货币套餐小组件显示区域

下图为页面结构的示例。

创建页面控制器

  1. 创建继承自MonoBehaviour基类的VirtualCurrencyPackagesPage脚本。
  2. 声明变量:
    • WidgetsContainer — 小组件的容器
    • WidgetPrefab — 虚拟货币套餐预制件
  1. 将脚本附加至页面游戏对象:
    1. Hierarchy面板中选择一个对象。
    2. Inspector面板中,单击Add Component,然后选择一个VirtualCurrencyPackagesPage脚本。
  2. Inspector面板中设置变量的值。
  3. 通过在Start方法中调用XsollaLogin.Instance.SignIn SDK方法添加登录逻辑,并向其传入:
    • 用户名或邮箱地址,包含在username参数中
    • 用户密码,包含在password参数中
注:
在登录脚本示例中我们使用的是演示帐户的凭证(用户名:xsolla,密码:xsolla)。
    • rememberUser参数中记住帐户的标志
    • OnAuthenticationSuccess回调方法,用于成功的用户登录
    • OnError回调方法,用于发生错误的情况
  1. 添加获取商品列表的逻辑。在OnAuthenticationSuccess方法中调用XsollaStore.Instance.GetVirtualCurrencyPackagesList SDK方法,并向其传入:
    • 项目ID,包含在projectId参数中
注:
您可以在发布商帐户的项目设置中找到项目ID。脚本示例中,我们将值从SDK设置传入参数。
    • OnItemsRequestSuccess,用于成功的获取商品列表操作
    • OnError回调方法,用于发生错误的情况
  1. OnPackagesRequestSuccess方法中,添加为每个收到的套餐创建小组件的逻辑:
    1. 实例化一个商品小组件预制件作为容器子对象。
    2. 将收到的VirtualCurrencyPackageWidget组件附加到widget变量上。
  1. 将以下数据传入套餐小组件:
    1. packageItem.name变量值传入套餐名元素。
    2. packageItem.description变量值传入套餐描述元素。
    3. 实现以下逻辑来显示套餐价格:
      • 如果packageItem.price变量的值不等于null,则该套餐以真实货币形式销售。请以{amount} {currency}格式指定价格并将其传入小组件元素。
      • 如果packageItem.virtual_prices变量的值不等于null,则该套餐以虚拟货币形式销售。请以{name}: {amount}格式指定价格并将其传入小组件元素。
注:
packageItem.virtual_prices变量是同一套餐在不同货币下的价格的数组。示例显示的是发布商帐户商店 > 虚拟货币 > 套餐中套餐设置里指定的默认价格。
    1. 要显示商品图片,请使用ImageLoader.Instance.GetImageAsync工具方法并向其传入:
      • 图片URL。
      • 作为回调的匿名函数。在该函数中,将收到的精灵添加为商品图片。

页面控制器脚本示例:

Copy
Full screen
Small screen
 1using System.Linq;
 2using UnityEngine;
 3using Xsolla.Core;
 4using Xsolla.Login;
 5using Xsolla.Store;
 6
 7namespace Recipes
 8{
 9	public class VirtualCurrencyPackagesPage : MonoBehaviour
10	{
11		// Declaration of variables for containers and widget prefabs
12		public Transform WidgetsContainer;
13
14		public GameObject WidgetPrefab;
15
16		private void Start()
17		{
18			// Starting the authentication process
19			XsollaLogin.Instance.SignIn("xsolla", "xsolla", true, null, onSuccess: OnAuthenticationSuccess, onError: OnError);
20		}
21
22		private void OnAuthenticationSuccess(string token)
23		{
24			// After successful authentication starting the request for packages from store
25			XsollaStore.Instance.GetVirtualCurrencyPackagesList(XsollaSettings.StoreProjectId, OnPackagesRequestSuccess, OnError);
26		}
27
28		private void OnPackagesRequestSuccess(VirtualCurrencyPackages packageItems)
29		{
30			// Iterating the packages collection and assign values for appropriate ui elements
31			foreach (var packageItem in packageItems.items)
32			{
33				var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false);
34				var widget = widgetGo.GetComponent<VirtualCurrencyPackageWidget>();
35
36				widget.NameText.text = packageItem.name;
37				widget.DescriptionText.text = packageItem.description;
38
39				if (packageItem.price != null)
40				{
41					var realMoneyPrice = packageItem.price;
42					widget.PriceText.text = $"{realMoneyPrice.amount} {realMoneyPrice.currency}";
43				}
44				else if (packageItem.virtual_prices != null)
45				{
46					var virtualCurrencyPrice = packageItem.virtual_prices.First(x => x.is_default);
47					widget.PriceText.text = $"{virtualCurrencyPrice.name}: {virtualCurrencyPrice.amount}";
48				}
49
50				ImageLoader.Instance.GetImageAsync(packageItem.image_url, (url, sprite) => widget.IconImage.sprite = sprite);
51			}
52		}
53
54		private void OnError(Error error)
55		{
56			UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
57		}
58	}
59}

下图为脚本的运行结果。

本文对您的有帮助吗?
谢谢!
我们还有其他可改进之处吗? 留言
非常抱歉
请说明为何本文没有帮助到您。 留言
感谢您的反馈!
我们会查看您的留言并运用它改进用户体验。
隐藏

以真实货币计价的形式销售虚拟物品

本说明主要介绍如何使用SDK方法实现以真实货币计价的形式销售虚拟物品。

开始之前,需实现在目录中显示虚拟物品。下方示例中我们描述了如何实现虚拟物品的购买。其他商品类型的配置与此类似。

本教程介绍以下逻辑的实现:

示例中的逻辑与界面比您在应用程序中的简单得多。演示项目提供了一种以真实货币计价的形式销售商品以及显示商品目录的可能方案。

完成商品小组件

在商品小组件中添加购买按钮,并配置其显示元素。

下图为小组件结构的示例。

完成商品小组件脚本

  1. 打开VirtualItemWidget脚本。
  2. 声明购买按钮的变量并在Inspector面板中设置它们的值

小组件脚本的示例:

Copy
Full screen
Small screen
 1using UnityEngine;
 2using UnityEngine.UI;
 3
 4namespace Recipes
 5{
 6	public class VirtualItemWidget : MonoBehaviour
 7	{
 8		// Declaration of variables for UI elements
 9
10		public Text NameText;
11
12		public Text DescriptionText;
13
14		public Text PriceText;
15
16		public Image IconImage;
17
18		public Button BuyButton;
19	}
20}

完成显示商品列表的页面控制器

  1. 打开VirtualItemsPage脚本。
  2. OnAuthenticationSuccess方法中,向XsollaStore.Instance.Token变量传入授权令牌。
注:
可使用以下令牌之一:
  • 通过XsollaLogin.Instance.SignIn SDK方法进行用户授权过程中收到的JWT。
  • 通过XsollaLogin.Instance.GetUserAccessToken SDK方法进行用户授权过程中收到的支付中心访问令牌。如果您实现了自己的授权系统,请使用此令牌。
  1. 添加处理点击虚拟物品购买按钮的逻辑:
    1. OnItemsRequestSuccess方法中,订阅按钮点击事件。
    2. 添加发生按钮点击后调用的匿名方法。
    3. 在该方法中,调用XsollaStore.Instance.ItemPurchase SDK方法以生成一个订单并向其传入:
      • 项目ID(projectId参数中)
      • 商品标识符(itemSku参数中)
      • OnOrderCreateSuccess方法,以处理商品购买订单的成功生成
      • OnError回调方法,用于发生错误的情况
  1. 实现支付页面的打开。方法是添加OnOrderCreateSuccess方法并在其中调用:
    • XsollaStore.Instance.OpenPurchaseUi SDK方法,用于打开支付页面
    • TrackOrderStatus协程,用于跟踪订单状态中的改变
注:
默认情况下,支付页面在内置浏览器中打开。如要在外部浏览器中打开,请在Unity编辑器主菜单中前往Window > Xsolla > Edit Settings,然后取消勾选Inspector面板中的Enable in-app browser?复选框。如果要为Android应用使用外部浏览器,建议设置深度链接在用户完成支付后将其重定向到应用中。
  1. TrackOrderStatus协程中,实现每秒获取一次订单状态信息。方法是使用XsollaStore.Instance.CheckOrderStatus SDK方法,并向其传入:
    • 项目ID(projectId参数中)
    • 支付详情中的订单号(orderId参数中)
    • 用于处理成功收到订单状态信息的匿名方法
    • 用于错误处理的匿名方法
  1. 在用于处理成功收到订单状态信息的匿名方法中,实现订单支付过程中的OnPurchaseSuccess方法回调(支付状态donepaid)。
  2. OnPurchaseSuccess方法中,实现成功购买虚拟物品的处理。
注:

在脚本示例中,商品购买成功时调用了Debug.Log基方法。您还可以添加其他动作,例如物品库显示等。

不需要实现向物品库添加所购商品的逻辑——它会自动完成。

  1. 如果使用内置浏览器来打开支付页面,请关闭该浏览器。

页面脚本示例:

Copy
Full screen
Small screen
 1using System.Collections;
 2using System.Linq;
 3using UnityEngine;
 4using Xsolla.Core;
 5using Xsolla.Login;
 6using Xsolla.Store;
 7
 8namespace Recipes
 9{
10	public class VirtualItemsPage : MonoBehaviour
11	{
12		// Declaration of variables for containers and widget prefabs
13
14		public Transform WidgetsContainer;
15
16		public GameObject WidgetPrefab;
17
18		private void Start()
19		{
20			// Starting the authentication process
21
22			XsollaLogin.Instance.SignIn("xsolla", "xsolla", true, null, onSuccess: OnAuthenticationSuccess, onError: OnError);
23		}
24
25		private void OnAuthenticationSuccess(string token)
26		{
27			// After successful authentication starting the request for catalog from store
28			Token.Instance = Token.Create(token);
29			XsollaStore.Instance.GetCatalog(XsollaSettings.StoreProjectId, OnItemsRequestSuccess, OnError, offset: 0, limit: 50);
30		}
31
32		private void OnItemsRequestSuccess(StoreItems storeItems)
33		{
34			// Iterating the items collection and assign values for appropriate ui elements
35
36			foreach (var storeItem in storeItems.items)
37			{
38				if (storeItem.price == null)
39					continue;
40
41				var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false);
42				var widget = widgetGo.GetComponent<VirtualItemWidget>();
43
44				widget.NameText.text = storeItem.name;
45				widget.DescriptionText.text = storeItem.description;
46
47				var realMoneyPrice = storeItem.price;
48				widget.PriceText.text = $"{realMoneyPrice.amount} {realMoneyPrice.currency}";
49
50				ImageLoader.Instance.GetImageAsync(storeItem.image_url, (url, sprite) => widget.IconImage.sprite = sprite);
51
52				widget.BuyButton.onClick.AddListener(() => { XsollaStore.Instance.ItemPurchase(XsollaSettings.StoreProjectId, storeItem.sku, OnOrderCreateSuccess, OnError); });
53			}
54		}
55
56		private void OnOrderCreateSuccess(PurchaseData purchaseData)
57		{
58			XsollaStore.Instance.OpenPurchaseUi(purchaseData);
59			StartCoroutine(TrackOrderStatus(purchaseData));
60		}
61
62		private IEnumerator TrackOrderStatus(PurchaseData purchaseData)
63		{
64			var isDone = false;
65			while (!isDone)
66			{
67				XsollaStore.Instance.CheckOrderStatus
68				(
69					XsollaSettings.StoreProjectId,
70					purchaseData.order_id,
71					status =>
72					{
73						if (status.status == "paid" || status.status == "done")
74						{
75							isDone = true;
76							OnPurchaseSuccess();
77						}
78					},
79					error => { OnError(error); }
80				);
81
82				yield return new WaitForSeconds(1f);
83			}
84		}
85
86		private void OnPurchaseSuccess()
87		{
88			UnityEngine.Debug.Log($"Purchase successful");
89			BrowserHelper.Instance.Close();
90		}
91
92		private void OnError(Error error)
93		{
94			UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
95		}
96	}
97}
本文对您的有帮助吗?
谢谢!
我们还有其他可改进之处吗? 留言
非常抱歉
请说明为何本文没有帮助到您。 留言
感谢您的反馈!
我们会查看您的留言并运用它改进用户体验。
隐藏

以虚拟货币计价的形式销售虚拟物品

本说明主要介绍如何使用SDK方法实现以虚拟货币计价的形式销售虚拟物品。

开始之前,需实现在目录中显示虚拟物品。下方示例中我们描述了如何实现虚拟物品的购买。其他商品类型的配置与此类似。

本教程介绍以下逻辑的实现:

示例中的逻辑与界面比您在应用程序中的简单得多。演示项目提供了一种以真实货币计价的形式销售商品以及显示商品目录的可能方案。

完成商品小组件

在商品小组件中添加购买按钮,并配置其显示元素。

下图为小组件结构的示例。

完成商品小组件脚本

  1. 打开VirtualItemWidget脚本。
  2. 声明购买按钮的变量并在Inspector面板中设置它们的值

小组件脚本的示例:

Copy
Full screen
Small screen
 1using UnityEngine;
 2using UnityEngine.UI;
 3
 4namespace Recipes
 5{
 6	public class VirtualItemWidget : MonoBehaviour
 7	{
 8		// Declaration of variables for UI elements
 9
10		public Text NameText;
11
12		public Text DescriptionText;
13
14		public Text PriceText;
15
16		public Image IconImage;
17
18		public Button BuyButton;
19	}
20}

完成显示商品列表的页面控制器

  1. 打开VirtualItemsPage脚本。
  2. OnAuthenticationSuccess方法中,向XsollaStore.Instance.Token变量传入授权令牌。
注:
可使用以下令牌之一:
  • 通过XsollaLogin.Instance.SignIn SDK方法进行用户授权过程中收到的JWT。
  • 通过XsollaLogin.Instance.GetUserAccessToken SDK方法进行用户授权过程中收到的支付中心访问令牌。如果您实现了自己的授权系统,请使用此令牌。
  1. 添加处理点击虚拟物品购买按钮的逻辑:
    1. OnItemsRequestSuccess方法中,订阅按钮点击事件。
    2. 添加发生按钮点击后调用的匿名方法。
    3. 在该方法中,调用XsollaStore.Instance.ItemPurchase SDK方法以生成一个订单并向其传入:
      • 项目ID(projectId参数中)
      • 商品标识符(itemSku参数中)
      • OnOrderCreateSuccess方法,以处理商品购买订单的成功生成
      • OnError回调方法,用于发生错误的情况
  1. OnOrderCreateSuccess方法中,实现订单状态检查过程。方法是使用XsollaStore.Instance.CheckOrderStatus SDK方法,并向其传入:
    • 项目ID(projectId参数中)
    • 支付详情中的订单号(orderId参数中)
    • 用于处理成功收到订单状态信息的匿名方法
    • 用于错误处理的匿名方法
  1. 在用于处理成功收到订单状态信息的匿名方法中,实现订单支付过程中的OnPurchaseSuccess方法回调(支付状态donepaid)。
  2. OnPurchaseSuccess方法中,实现成功购买虚拟物品的处理。
注:

在脚本示例中,商品购买成功时调用了Debug.Log基方法。您还可以添加其他动作,例如物品库显示虚拟货币余额更改等。

不需要实现向物品库添加所购商品的逻辑——它会自动完成。

页面脚本示例:

Copy
Full screen
Small screen
 1using System.Linq;
 2using UnityEngine;
 3using Xsolla.Core;
 4using Xsolla.Login;
 5using Xsolla.Store;
 6
 7namespace Recipes
 8{
 9	public class VirtualItemsPage : MonoBehaviour
10	{
11		// Declaration of variables for containers and widget prefabs
12
13		public Transform WidgetsContainer;
14
15		public GameObject WidgetPrefab;
16
17		private void Start()
18		{
19			// Starting the authentication process
20
21			XsollaLogin.Instance.SignIn("xsolla", "xsolla", true, null, onSuccess: OnAuthenticationSuccess, onError: OnError);
22		}
23
24		private void OnAuthenticationSuccess(string token)
25		{
26			// After successful authentication starting the request for catalog from store
27			Token.Instance = Token.Create(token);
28			XsollaStore.Instance.GetCatalog(XsollaSettings.StoreProjectId, OnItemsRequestSuccess, OnError, offset: 0, limit: 50);
29		}
30
31		private void OnItemsRequestSuccess(StoreItems storeItems)
32		{
33			// Iterating the items collection and assign values for appropriate ui elements
34			foreach (var storeItem in storeItems.items)
35			{
36				if (storeItem.virtual_prices.Length == 0)
37					continue;
38
39				var widget = Instantiate(WidgetPrefab, WidgetsContainer, false).GetComponent<VirtualItemWidget>();
40
41				widget.NameText.text = storeItem.name;
42				widget.DescriptionText.text = storeItem.description;
43
44				var defaultPrice = storeItem.virtual_prices.First(x => x.is_default);
45				widget.PriceText.text = $"{defaultPrice.name}: {defaultPrice.amount}";
46
47				ImageLoader.Instance.GetImageAsync(storeItem.image_url, (url, sprite) => widget.IconImage.sprite = sprite);
48
49				widget.BuyButton.onClick.AddListener(() =>
50				{
51					var price = storeItem.virtual_prices.First(x => x.is_default);
52					XsollaStore.Instance.ItemPurchaseForVirtualCurrency(XsollaSettings.StoreProjectId, storeItem.sku, price.sku, OnOrderCreateSuccess, OnError);
53				});
54			}
55		}
56
57		private void OnOrderCreateSuccess(PurchaseData purchaseData)
58		{
59			XsollaStore.Instance.CheckOrderStatus
60			(
61				XsollaSettings.StoreProjectId,
62				purchaseData.order_id,
63				status =>
64				{
65					if (status.status == "paid" || status.status == "done")
66					{
67						OnPurchaseSuccess();
68					}
69				},
70				error =>
71				{
72					OnError(error);
73				}
74			);
75		}
76
77
78		private void OnPurchaseSuccess()
79		{
80			UnityEngine.Debug.Log($"Purchase successful");
81		}
82
83		private void OnError(Error error)
84		{
85			UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
86		}
87	}
88}
本文对您的有帮助吗?
谢谢!
我们还有其他可改进之处吗? 留言
非常抱歉
请说明为何本文没有帮助到您。 留言
感谢您的反馈!
我们会查看您的留言并运用它改进用户体验。
隐藏

显示虚拟货币余额

本教程介绍如何使用SDK方法在应用中显示虚拟货币的余额。

示例中的逻辑与界面比您实际在应用程序中的要简单得多。演示项目提供了一种可能的游戏内商店商品目录实现方案。

创建显示余额的小组件

  1. 创建一个空游戏对象。方法是前往主菜单,然后选择GameObject > Create Empty
  2. Hierarchy面板拖动一个游戏对象到Project面板,以转换预制件中创建的游戏对象。
  3. 选择一个创建的预制件,然后在Inspector面板中单击Open Prefab
  4. 将以下UI元素添加为预制件子对象并配置其视觉显示:
    • 小组件背景图片
    • 虚拟货币名称
    • 虚拟货币数量
    • 虚拟货币图片

下图为小组件结构的示例。

创建显示余额的小组件脚本

  1. 创建一个继承自MonoBehaviour基类的脚本VirtualCurrencyWidget
  2. 声明商品小组件界面元素的变量并Inspector面板中设置它们的值

小组件脚本的示例:

Copy
Full screen
Small screen
 1using UnityEngine;
 2using UnityEngine.UI;
 3
 4namespace Recipes
 5{
 6	public class VirtualCurrencyWidget : MonoBehaviour
 7	{
 8		// Declaration of variables for UI elements
 9
10		public Text NameText;
11
12		public Text AmountText;
13
14		public Image IconImage;
15	}
16}

创建包含虚拟货币列表的页面

  1. 在场景上创建一个空游戏对象。方法是前往主菜单,然后选择GameObject > Create Empty
  2. 将以下UI元素添加为预制件子对象并配置其视觉显示:
    • 页面背景图片
    • 小组件显示区域

下图为页面结构的示例。

创建包含虚拟货币列表页面的控制器

  1. 创建继承自MonoBehaviour基类的脚本VirtualCurrenciesPage
  2. 声明以下变量:
    • WidgetsContainer — 小组件的容器
    • WidgetPrefab — 余额显示小组件预制件
  1. 将脚本附加到页面游戏对象上:
    1. Hierarchy面板中选择一个对象。
    2. Inspector面板中,单击Add Component,然后选择一个VirtualCurrenciesPage脚本。
  1. Inspector面板中设置变量的值。
  2. 通过在Start方法中调用XsollaLogin.Instance.SignIn SDK方法添加登录逻辑,并向其传入:
    • 用户名或邮箱地址,包含在username参数中
    • 用户密码,包含在password参数中
注:
在脚本示例中,我们使用了演示帐户的凭证进行登录(用户名:xsolla,密码:xsolla)。
    • rememberUser参数中记住帐户的标志
    • OnAuthenticationSuccess回调方法,用于成功的用户登录
    • OnError回调方法,用于发生错误的情况
  1. 添加获取虚拟货币列表的逻辑。方法是在OnAuthenticationSuccess方法中:
    1. 将授权令牌传入XsollaStore.Instance.Token变量。
注:
可使用以下令牌之一:
  • 通过XsollaLogin.Instance.SignIn SDK方法进行用户授权过程中收到的JWT。
  • 通过XsollaLogin.Instance.GetUserAccessToken SDK方法进行用户授权过程中收到的支付中心访问令牌。如果您实现了自己的授权系统,请使用此令牌。
    1. 调用XsollaStore.Instance.GetVirtualCurrencyBalance SDK方法并向其传入:
      • 项目ID,包含在projectId参数中
注:
您可以在发布商帐户的项目设置中找到项目ID。脚本示例中,我们将值从SDK设置传入参数。
      • OnBalanceRequestSuccess方法,用于获取商品列表成功的情况
      • OnError回调方法,用于发生错误的情况
  1. OnBalanceRequestSuccess方法中,添加为收到的每种虚拟货币创建小组件的逻辑:
    1. 实例化一个商品小组件预制件作为容器子对象。
    2. 将收到的VirtualCurrencyWidget组件附加到widget变量上。
  1. 将以下数据传入余额小组件:
    1. balanceItem.name变量值传入虚拟货币名元素。
    2. balanceItem.amount.ToString()变量值传入虚拟货币数量元素。
    3. 实现以下逻辑来显示商品价格。要显示虚拟货币图片,请使用ImageLoader.Instance.GetImageAsync工具方法并向其传入:
      • 图片URL。
      • 匿名回调函数。在该函数中,将收到的精灵添加为虚拟货币图片。

页面控制器脚本示例:

Copy
Full screen
Small screen
 1using UnityEngine;
 2using Xsolla.Core;
 3using Xsolla.Login;
 4using Xsolla.Store;
 5
 6namespace Recipes
 7{
 8	public class VirtualCurrenciesPage : MonoBehaviour
 9	{
10		// Declaration of variables for containers and widget prefabs
11
12		public Transform WidgetsContainer;
13
14		public GameObject WidgetPrefab;
15
16		private void Start()
17		{
18			// Starting the authentication process
19
20			XsollaLogin.Instance.SignIn("xsolla", "xsolla", true, null, OnAuthenticationSuccess, OnError);
21		}
22
23		private void OnAuthenticationSuccess(string token)
24		{
25			// After successful authentication starting the request for virtual currencies
26
27			Token.Instance = Token.Create(token);
28			XsollaStore.Instance.GetVirtualCurrencyBalance(XsollaSettings.StoreProjectId, OnBalanceRequestSuccess, OnError);
29		}
30
31		private void OnBalanceRequestSuccess(VirtualCurrenciesBalance balance)
32		{
33			// Iterating the virtual currencies list and assign values for appropriate ui elements
34
35			foreach (var balanceItem in balance.items)
36			{
37				var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false);
38				var widget = widgetGo.GetComponent<VirtualCurrencyWidget>();
39
40				widget.NameText.text = balanceItem.name;
41				widget.AmountText.text = balanceItem.amount.ToString();
42
43				ImageLoader.Instance.GetImageAsync(balanceItem.image_url, (url, sprite) => widget.IconImage.sprite = sprite);
44			}
45		}
46
47		private void OnError(Error error)
48		{
49			UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
50		}
51	}
52}

下图为脚本的运行结果。

本文对您的有帮助吗?
谢谢!
我们还有其他可改进之处吗? 留言
非常抱歉
请说明为何本文没有帮助到您。 留言
感谢您的反馈!
我们会查看您的留言并运用它改进用户体验。
隐藏

显示物品库中的物品

本教程介绍如何使用SDK方法显示用户物品库中的商品。

示例中的逻辑与界面比您在应用程序中的简单得多。演示项目提供了一种可能的物品库实现方案。

创建商品小组件

  1. 创建一个空游戏对象。方法是前往主菜单,然后选择GameObject > Create Empty
  2. Hierarchy面板拖动一个游戏对象到Project面板,以转换预制件中创建的游戏对象。
  3. 选择一个创建的预制件,然后在Inspector面板中单击Open Prefab
  4. 将以下UI元素添加为预制件子对象并配置其视觉显示:
    • 商品背景图片
    • 商品名称
    • 商品描述
    • 商品数量
    • 商品图片

下图为小组件结构的示例。

创建商品小组件脚本

  1. 创建一个继承自MonoBehaviour基类的脚本InventoryItemWidget
  2. 声明商品小组件界面元素的变量并Inspector面板中设置它们的值

小组件脚本的示例:

Copy
Full screen
Small screen
 1using UnityEngine;
 2using UnityEngine.UI;
 3
 4namespace Recipes
 5{
 6	public class InventoryItemWidget : MonoBehaviour
 7	{
 8		// Declaration of variables for UI elements
 9
10		public Text NameText;
11
12		public Text DescriptionText;
13
14		public Text QuantityText;
15
16		public Image IconImage;
17	}
18}

创建显示物品库的页面

  1. 在场景上创建一个空游戏对象。方法是前往主菜单,然后选择GameObject > Create Empty
  2. 将以下UI元素添加为预制件子对象并配置其视觉显示:
    • 页面背景图片
    • 商品小组件显示区域

下图为页面结构的示例。

创建页面控制器

  1. 创建继承自MonoBehaviour基类的脚本InventoryItemsPage
  2. 声明以下变量:
    • WidgetsContainer — 商品小组件的容器
    • WidgetPrefab — 商品小组件预制件
  1. 将脚本附加到页面游戏对象上:
    1. Hierarchy面板中选择一个对象。
    2. Inspector面板中,单击Add Component,然后选择一个InventoryItemsPage脚本。
  1. Inspector面板中设置变量的值。
  2. 通过在Start方法中调用XsollaLogin.Instance.SignIn SDK方法添加登录逻辑,并向其传入:
    • 用户名或邮箱地址,包含在username参数中
    • 用户密码,包含在password参数中
注:
在脚本示例中,我们使用了演示帐户的凭证进行登录(用户名:xsolla,密码:xsolla)。
    • rememberUser参数中记住帐户的标志
    • OnAuthenticationSuccess回调方法,用于成功的用户登录
    • OnError回调方法,用于发生错误的情况
  1. 添加获取物品库中商品列表的逻辑。方法是在OnAuthenticationSuccess方法中:
    1. 将授权令牌传入XsollaStore.Instance.Token变量。
注:
可使用以下令牌之一:
  • 通过XsollaLogin.Instance.SignIn SDK方法进行用户授权过程中收到的JWT。
  • 通过XsollaLogin.Instance.GetUserAccessToken SDK方法进行用户授权过程中收到的支付中心访问令牌。如果您实现了自己的授权系统,请使用此令牌。
    1. 调用XsollaStore.Instance.GetInventoryItems SDK方法并向其传入:
      • 项目ID,包含在projectId参数中
注:
您可以在发布商帐户的项目设置中找到项目ID。脚本示例中,我们将值从SDK设置传入参数。
      • OnItemsRequestSuccess,用于获取商品列表成功的情况
      • OnError回调方法,用于发生错误的情况
  1. 对于OnItemsRequestSuccess方法中收到的每个商品,添加创建小组件的逻辑:
    1. 使用InventoryItem.IsVirtualCurrency方法添加一个检查,确保收到的商品不是虚拟货币。
注:
本例中,我们仅演示显示物品库中的虚拟物品、捆绑包和订阅。实现虚拟货币余额的显示另在单独页面上说明。
    1. 实例化一个商品小组件预制件作为容器子对象。
    2. 将收到的InventoryItemWidget组件附加到widget变量上。
  1. 将以下数据传入商品小组件:
    1. inventoryItem.name变量值传入商品名元素。
    2. inventoryItem.description变量值传入商品描述元素。
    3. inventoryItem.amount.ToString()传入商品数量元素。
    4. 要显示商品图片,请使用ImageLoader.Instance.GetImageAsync工具方法并向其传入:
      • 图片URL
      • 作为回调的匿名函数。在该函数中,将收到的精灵添加为商品图片。

页面控制器脚本示例:

Copy
Full screen
Small screen
 1using UnityEngine;
 2using Xsolla.Core;
 3using Xsolla.Login;
 4using Xsolla.Store;
 5
 6namespace Recipes
 7{
 8	public class InventoryItemsPage : MonoBehaviour
 9	{
10		// Declaration of variables for containers and widget prefabs
11		public Transform WidgetsContainer;
12
13		public GameObject WidgetPrefab;
14
15		private void Start()
16		{
17			// Starting the authentication process
18			XsollaLogin.Instance.SignIn("xsolla", "xsolla", true, null, OnAuthenticationSuccess, OnError);
19		}
20
21		private void OnAuthenticationSuccess(string token)
22		{
23			// After successful authentication starting the request for virtual currencies
24			Token.Instance = Token.Create(token);
25			XsollaStore.Instance.GetInventoryItems(XsollaSettings.StoreProjectId, OnItemsRequestSuccess, OnError);
26		}
27
28		private void OnItemsRequestSuccess(InventoryItems inventoryItems)
29		{
30			// Iterating the item list and assign values for appropriate ui elements
31
32			foreach (var inventoryItem in inventoryItems.items)
33			{
34				if (inventoryItem.IsVirtualCurrency())
35					continue;
36
37				var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false);
38				var widget = widgetGo.GetComponent<InventoryItemWidget>();
39
40				widget.NameText.text = inventoryItem.name;
41				widget.DescriptionText.text = inventoryItem.description;
42				widget.QuantityText.text = inventoryItem.quantity.ToString();
43
44				ImageLoader.Instance.GetImageAsync(inventoryItem.image_url, (url, sprite) => widget.IconImage.sprite = sprite);
45			}
46		}
47
48		private void OnError(Error error)
49		{
50			UnityEngine.Debug.LogError($"Error message: {error.errorMessage}");
51		}
52	}
53}

下图为脚本的运行结果。

本文对您的有帮助吗?
谢谢!
我们还有其他可改进之处吗? 留言
非常抱歉
请说明为何本文没有帮助到您。 留言
感谢您的反馈!
我们会查看您的留言并运用它改进用户体验。
隐藏
上次更新时间: 2025年6月12日

发现了错别字或其他内容错误? 请选择文本,然后按Ctrl+Enter。

报告问题
我们非常重视内容质量。您的反馈将帮助我们做得更好。
请留下邮箱以便我们后续跟进
感谢您的反馈!
无法发送您的反馈
请稍后重试或发送邮件至doc_feedback@xsolla.com与我们联系。