Managed Pricingを使用すると、地域別の価格をアイテムに提供し、より包括的でアクセスしやすいグローバル経済を構築できます。アイテムのデフォルトのグローバル価格を決定した後、Robloxは地域の購買力、通貨の為替レート、地域の消費行動などのさまざまな信号を使用して、地域ごとにそのアイテムに最も適した価格を設定します。
地域価格を設定するアイテムを選択できます。ゲーム内のアイテムにManaged Pricingを有効にすると、Robloxはユーザーの経済的な位置に基づいてそのアイテムの価格を自動的に調整します。
経済的な位置は、常にアカウントの位置と同じとは限りません。ユーザーの経済的な位置を決定するために、RobloxはVPNの使用、請求履歴、アカウント履歴などの信号を考慮します。経済的な位置が特定できない場合、ユーザーは代わりにアイテムのデフォルトのグローバル価格を表示します。
異なる管理価格を持つアイテムを贈与または取引する際の価格のアービトラージを防ぐために、 GetUsersPriceLevelsAsync APIを使用してゲーム内の転送を管理することができます。
地域価格を有効にする
パスの場合
地域価格は、Managed pricingを通じて、すべての新しいおよび既存のパスに対してデフォルトで有効になっています。
パスの管理価格を無効にするには:
- Creationsに移動し、ゲームを選択します。
- Monetization ⟩ Passes に移動します。
- 一つ以上の既存のパスを選択します。
- Disable Managed Pricingをクリックします。
- OPTIONAL管理価格を国または地域ごとに表示するには、パスを選択してそのSalesページに移動します。 Top Countries/Regionsリストは、パスのデフォルト価格に基づいて調整された価格を表示するように更新されます。すべての国と地域の価格を表示するには、View all countriesをクリックします。
開発者製品の場合
開発者製品のために管理価格を有効にするには:
- 開発者製品が[動的スクリプト価格]が設定されていることを確認します。(#check-for-dynamic-pricing)
- アイテムの転送をユーザーの価格レベルに基づいて管理するために、 GetUsersPriceLevelsAsync メソッドを実装します。
- Creationsに移動し、ゲームを選択します。
- Monetization ⟩ Developer Products に移動します。
- 一つ以上の既存の製品を選択するか、新しい製品を作成します。
- Enable Managed Pricingをクリックします。
- OPTIONAL国または地域ごとの管理価格を表示するには、製品を選択してそのBasic Settingsページに移動します。Top Countries/Regionsリストは、製品のデフォルト価格に基づいて調整された価格を表示するように更新されます。すべての国と地域の管理価格を表示するには、View all countriesをクリックします。
サブスクリプションの場合
管理価格は、Robuxで価格付けされたサブスクリプションに対してデフォルトで有効になっており、無効にすることはできません。詳細については、Create subscriptionsを参照してください。
地域通貨で価格付けされたサブスクリプションには管理価格は利用できません。
アバターアイテムの場合
アバターアイテムに対してManaged Pricingを有効にするには、Pricingを参照してください。
動的価格の確認
Managed Pricingを有効にすると、アイテムの価格はゲーム内外で異なる地域のユーザーに合わせて調整されます。しかし、ゲームのUIに価格がハードコーディングされている場合、その数値は動的ではなく、Robloxによってアクセスされないため、更新されません。その結果、ユーザーは正しい地域別の価格を請求されますが、UIにはハードコーディングされた値が表示され続けます。
動的価格チェックツールは、ゲーム内で販売されているすべてのアイテムの価格を偽のRobux価格または偽の経済的な位置で更新し、ゲームのUIにおいてどの価格がハードコーディングされていて、どの価格がMarketplaceServiceを使用して動的にスクリプトされているかを特定するのに役立ちます。ハードコーディングされたパスを特定した後、それらをMarketplaceService関数を使用して更新できます。
動的価格チェックツールを使用するには:
- Monetizationに移動します。
- パスの場合は、Passesに移動します。
- 開発者製品の場合は、Developer Productsに移動します。
- **…**をクリックし、Dynamic Price Checkを選択します。
- Add test accountsで、ハードコーディングされた価格をチェックするために最大5人のRobloxユーザーを入力します。
- テストタイプを選択します。
- Price pinnedは、すべての動的にスクリプトされた価格を設定された偽のRobux金額で更新します。
- Location pinnedは、偽の経済的位置に対して地域別の価格で動的スクリプトされたすべての価格を更新します。
- Enableをクリックします。数分後にゲームに入り、ハードコーディングされた価格を特定します。
動的価格チェックツールを無効にするには、Dynamic Price Checkページに移動し、Disableをクリックします。
ハードコーディングされた価格と動的スクリプト価格の詳細については、Check for dynamic pricingをPrice optimizationページでご覧ください。MarketplaceService関数を使用したパスおよび開発者製品の販売については、Sell a pass inside your gameとSell a developer product inside your gameを参照してください。
ゲーム内に地域価格を表示する
Managed Pricingを使用すると、ユーザーが見る価格はその位置に基づいて異なる場合があります。TextLabelのようなカスタムゲーム内UIに価格を表示する場合、購入プロンプトに表示される価格と一致するように商品の情報をランタイムで取得できます。
単一の開発者製品またはパスの地域価格を表示するには、GetProductInfoAsyncを使用します。
すべての開発者製品の地域価格を表示するには、GetDeveloperProductsAsyncを使用します。
取引と贈り物を保護する
Managed Pricingは、取引や贈り物などのゲーム内の転送に影響を及ぼす可能性があります。地域による価格の違いのため、価格アービトラージ(同じ製品の価格の違いを利用して利益を生むこと)が発生する可能性があります。価格アービトラージの可能性を管理するには、ボットを「Class.MarketplaceService.GetUsersPriceLevelsAsync|GetUsersPriceLevelsAsync」APIを使用して、ユーザーの相対価格レベルを判断できるようにします。この価格レベルを基にして、アイテムの転送を規制するロジックを実装できます。
GetUsersPriceLevelsAsyncは、1から1000の間の数値を提供し、ユーザーの価格レベルを示します。この値は、ユーザーが支払うと予想される価格のフルプライスの割合を表すことを目的としています。価格レベル1000はフルグローバル価格を表し、低い価格レベルは通常、経済的位置のためにユーザーが低価格を支払っていることを示します。
低い価格レベルの差は、フルグローバル価格とユーザーの管理価格の間の差が小さいことを意味します。高い価格レベルの差は、二者間の価格差が大きいことを意味します。例えば:
- ユーザーAは価格レベル1000を持っており、これはフルグローバル価格を表します。このユーザーはアイテムのベース価格の100%を支払います。
- ユーザーBは価格レベル500を持っており、これはフルグローバル価格の50%を表します。このユーザーはアイテムのベース価格の50%を支払います。
- 各ユーザーの価格レベルを知った後、価格レベルの差500に基づいて、ユーザーAとユーザーBの間の贈与または取引を承認またはブロックすることを選択できます。
GetUsersPriceLevelsAsyncの実装
アイテムの転送に関与するユーザーの価格レベルを取得するには、MarketplaceServiceのGetUsersPriceLevelsAsync関数を呼び出します。この関数は、ユーザーIDの配列を引数に取り、次のフィールドを持つPriceLevelInfoオブジェクトの配列を返します。
type PriceLevelInfo = {UserId: number,PriceLevel: number}
関数を実装した後、返された価格レベルを使用して、アイテム転送を許可するかどうかを選択します。例えば、価格レベルの高いユーザーが、価格レベルの低いユーザーにアイテムを贈ることを許可することはできますが、価格レベルが同じユーザー同士の取引だけを許可します。詳細については、available examplesを参照してください。
GetUsersPriceLevelsAsyncAPIの詳細については、MarketplaceServiceを参照してください。
例
地域価格でGetUsersPriceLevelsAsyncを使用する方法の例。
例1: 複数ユーザーの価格レベルを確認
この例では、アイテムの転送を許可するかどうかを選択するのに役立つ、複数ユーザーの価格レベルを取得する方法を示します。
-- Get the MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- ユーザーのリストの価格レベルを取得し、UserIdからPriceLevelのルックアップテーブルを作成する関数を定義
local function getPriceLevelsLookup(userIds)
local success, result = pcall(function()
return MarketplaceService:GetUsersPriceLevelsAsync(userIds)
end)
if success then
-- 各PriceLevelInfoをUserId -> PriceLevelのルックアップテーブルにマッピング
local lookup = {}
for _, userData in ipairs(result) do
lookup[userData.UserId] = userData.PriceLevel
end
return lookup
else
warn("価格レベルの取得中にエラーが発生しました:", result)
return nil
end
end
-- プレースホルダーIDを使用した例
local user1Id = 123456789
local user2Id = 987654321
-- 関数を呼び出して結果を保存
local priceLevels = getPriceLevelsLookup({user1Id, user2Id})
-- 成功した場合は、各ユーザーのレベルを表示
if priceLevels then
print("ユーザー1の価格レベル:", priceLevels[user1Id])
print("ユーザー2の価格レベル:", priceLevels[user2Id])
else
print("価格レベルの取得に失敗しました。")
end
例2: 送信者の価格レベルと受取人の価格レベルを比較
この例では、送信者の価格レベルを受取人の価格レベルと比較するサンプル実装を示します。これにより、価格の高い地域から価格の低い地域のユーザーへの贈り物を管理できます。
-- Get the MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- ユーザーのリストの価格レベルを取得し、UserIdからPriceLevelのルックアップテーブルを作成する関数を定義
local function getPriceLevelsLookup(userIds)
local success, result = pcall(function()
return MarketplaceService:GetUsersPriceLevelsAsync(userIds)
end)
if success then
-- 各PriceLevelInfoをUserId -> PriceLevelのルックアップテーブルにマッピング
local lookup = {}
for _, userData in ipairs(result) do
lookup[userData.UserId] = userData.PriceLevel
end
return lookup
else
warn("価格レベルの取得中にエラーが発生しました:", result)
return nil
end
end
-- 送信者が受取人と同じまたは高い価格レベルを持っているかを確認する関数を定義
-- パラメーターは、アイテムを送信するプレイヤーと受け取るプレイヤーです
-- 関数は、送信者の価格レベルが受取人の価格レベル以上であればtrueを返します
function isSenderPriceLevelHigherOrEqualforGifting(sender, recipient)
local priceLevelsLookup = getPriceLevelsLookup({ sender.UserId, recipient.UserId })
if not priceLevelsLookup then
error("MarketplaceService:GetUsersPriceLevelsAsyncが失敗しました。ユーザー価格レベルの取得に失敗しました。")
end
local senderPriceLevel = priceLevelsLookup[sender.UserId]
local recipientPriceLevel = priceLevelsLookup[recipient.UserId]
return senderPriceLevel >= recipientPriceLevel
end
例3: 2人のユーザーが同じ価格レベルか確認する
この例では、2人のユーザーが同じ価格レベルを持っているかを確認するサンプル実装を示します。これにより、取引を管理し、異なる地域のユーザー間で公正な交換を確保できます。
-- Get the MarketplaceService
local MarketplaceService = game:GetService("MarketplaceService")
-- ユーザーのリストの価格レベルを取得し、UserIdからPriceLevelのルックアップテーブルを作成する関数を定義
local function getPriceLevelsLookup(userIds)
local success, result = pcall(function()
return MarketplaceService:GetUsersPriceLevelsAsync(userIds)
end)
if success then
-- 各PriceLevelInfoをUserId -> PriceLevelのルックアップテーブルにマッピング
local lookup = {}
for _, userData in ipairs(result) do
lookup[userData.UserId] = userData.PriceLevel
end
return lookup
else
warn("価格レベルの取得中にエラーが発生しました:", result)
return nil
end
end
-- 2人のユーザーが同じ価格レベルを持っているか確認する関数を定義
-- パラメーターは、比較する2人のユーザーです
-- 関数は、両方のユーザーが同じ価格レベルを持っていればtrueを返します
function haveSamePriceLevelForTrading(userA, userB)
local priceLevelsLookup = getPriceLevelsLookup({ userA.UserId, userB.UserId })
if not priceLevelsLookup then
error("MarketplaceService:GetUsersPriceLevelsAsyncが失敗しました。ユーザー価格レベルの取得に失敗しました。")
end
local userAPriceLevel = priceLevelsLookup[userA.UserId]
local userBPriceLevel = priceLevelsLookup[userB.UserId]
return userAPriceLevel == userBPriceLevel
end