Highlight
Apple 在 2020 年把 Game Center 重新放回游戏内:玩家通过 Access Point 打开 Dashboard,直接查看资料、好友、排行榜和成就,开发者用 GameKit 的现有控制器接入这套界面。
核心内容
很多游戏原来接入 Game Center 时,入口要自己设计,资料页要跳出游戏,排行榜、成就、好友信息也分散在不同位置。玩家想看自己和朋友的进度,常常要离开当前流程。对开发者来说,这意味着要维护一套游戏内 UI,还要处理登录、隐私、未成年人限制和 tvOS 共享设备上的用户切换。
这场 session 的第一件事,是把 Game Center 变成游戏里的固定入口。游戏启动后仍会显示欢迎横幅,随后出现 Access Point(访问点)。它可以先展示成就数量或排行榜名次,再折叠成玩家头像。玩家点击头像后进入 Dashboard(仪表盘),在同一个覆盖界面里查看资料、排行榜、成就、挑战和好友信息。
第二件事,是让开发者少写界面。Dashboard 仍然由 GKGameCenterViewController 呈现,只是新增了 .dashboard 和 .localPlayerProfile 等状态。Access Point 由 GKAccessPoint.shared 控制位置、亮点和显示状态。游戏只需要在主菜单打开它,在过场、玩法和设置页隐藏它。
第三件事,是把玩家身份变成更明确的开发模型。GKLocalPlayer 表示当前设备上的玩家,GKPlayer 表示其他玩家。认证要尽早开始,因为认证完成后,游戏才能调用 Game Center API,接收邀请、挑战和用户变化通知。玩家隐私、未成年人状态、多人游戏限制和个性化通信限制,也要在认证后检查。
详细内容
用 GKGameCenterViewController 打开 Dashboard
(10:05)新的 Dashboard 是 Game Center 功能的统一入口。它仍然使用熟悉的 GKGameCenterViewController,差异在初始化状态。
// GKGameCenterViewController
public init(state:)
[...]
// Example: Display Main Dashboard
let vc = GKGameCenterViewController(state: .dashboard)
vc.gameCenterDelegate = self
present(vc, animated: true, completion: nil)
[...]
enum GKGameCenterViewControllerState : Int {
case `default`
case leaderboards
case achievements
case challenges
case localPlayerProfile
case dashboard
}
关键点:
GKGameCenterViewController(state: .dashboard)直接打开顶层 Dashboard。gameCenterDelegate仍然负责处理控制器关闭等委托回调。leaderboards、achievements、challenges和localPlayerProfile可以把玩家带到指定区域。- 这段代码适合主菜单的“Game Center”按钮,也适合从自定义 UI 进入统一面板。
(10:51)如果游戏里已经有一个具体排行榜按钮,可以继续深链接到单个排行榜。
// Display scores for a specific leaderboard
let vc = GKGameCenterViewController(
leaderboardID: "grp.xyz.laketahoe",
playerScope: .global,
timeScope: .allTime)
vc.gameCenterDelegate = self
present(vc, animated: true, completion: nil)
关键点:
leaderboardID对应 App Store Connect 中配置的排行榜。playerScope控制显示全局玩家还是好友范围。timeScope控制今天、本周或所有时间这类时间窗口。- 深链接进入单个排行榜后,玩家仍可在 Dashboard 中浏览可用区域。
在主菜单显示 Access Point
(13:18)Access Point 是一个常驻入口,适合放在游戏主菜单,而不是玩法画面。它的位置会随语言方向变化,例如 topLeading 在从右到左语言中会换到右上角。
// Configure and show Access Point
func showMainMenu() {
// Call your code to setup the main menu
self.setupMainMenu()
// Place access point on top left
GKAccessPoint.shared.location = .topLeading
// Show highlights
GKAccessPoint.shared.showHighlights = true
// Show it!
GKAccessPoint.shared.isActive = true
}
关键点:
GKAccessPoint.shared.location选择访问点所在角落。showHighlights打开成就数量或默认排行榜名次等摘要信息。isActive = true才会显示 Access Point。- session 建议在主菜单显示,在电影式开场、玩法中和设置页隐藏。
在 Dashboard 弹出时暂停菜单动画
(14:00)玩家点击 Access Point 后,游戏可能需要暂停主菜单动画或其他背景效果。isPresentingGameCenter 提供了这个信号。
let observation = GKAccessPoint.shared.observe(
\.isPresentingGameCenter
) { [weak self] _,_ in
self.paused = GKAccessPoint.shared.isPresentingGameCenter
}
关键点:
observe(\.isPresentingGameCenter)监听 Game Center 界面是否正在展示。- 回调里把游戏自己的
paused状态同步到 Access Point 状态。 - 这能避免 Dashboard 覆盖在游戏上方时,背景仍然播放昂贵动画。
- 观察对象要由游戏保存,生命周期结束后再释放。
避开 Access Point 的屏幕区域
(14:44)Access Point 可能挡住游戏主菜单上的标题、角色或按钮。frameInScreenCoordinates 可以把它的位置交给布局系统。
// Observable properties
// frameInScreenCoordinates
let observation = GKAccessPoint.shared.observe(
\.frameInScreenCoordinates
) { [weak self] _,_ in
let screenFrame = GKAccessPoint.shared.frameInScreenCoordinates
let accessPointFrame = myView.convert(screenFrame, from: nil)
// adjust your layout
}
关键点:
frameInScreenCoordinates给出 Access Point 当前屏幕矩形。myView.convert(screenFrame, from: nil)把屏幕坐标转到游戏视图坐标。- Access Point 展示不同 highlight 时,尺寸可能变化,所以这里适合用观察。
- 游戏可以移动标题图、按钮或装饰元素,避免被头像入口盖住。
支持 Apple TV 和手柄焦点
(15:18)在 tvOS 或手柄场景中,游戏可能自己绘制焦点反馈。此时仍然要把 Access Point 纳入焦点判断。
// Apple TV and controllers
// track and update focus
func trackController(position: CGPoint) {
let screenFrame = GKAccessPoint.shared.frameInScreenCoordinates
let accessFrame = myView.convert(screenFrame, from: nil)
// if the point is in the access point turn on feedback
accessPointElement.focusFeedback = CGRectContainsPoint(accessFrame, position)
}
关键点:
position是游戏正在追踪的遥控器或手柄焦点位置。- 代码先取得 Access Point 的屏幕区域,再转换到游戏视图坐标。
CGRectContainsPoint判断焦点是否落在 Access Point 内。- 命中后,游戏可以给自己的 Access Point 代理元素绘制焦点反馈。
(15:38)当玩家按下选择键时,用程序化 API 打开 Dashboard。
// Apple TV and controllers
// Handle selection
func accessPointSelected() {
GKAccessPoint.shared.triggerAccessPoint {}
}
关键点:
triggerAccessPoint模拟玩家触发 Access Point。- 这让遥控器和手柄流程不用依赖触摸点击。
- 调用后,系统会进入与点击头像相同的 Dashboard 流程。
打开本地玩家资料并处理限制
(20:01)玩家资料从设置页进入游戏内。开发者可以直接呈现本地玩家资料页。
// Local player profile
let profileVC = GKGameCenterViewController(state: .localPlayerProfile)
profileVC.gameCenterDelegate = self
present(profileVC, animated: true, completion: nil)
关键点:
.localPlayerProfile直接进入当前玩家的资料页。- 玩家可以在这里查看成就、找朋友、查看朋友正在玩的游戏。
- 这段代码适合放在“我的资料”按钮后面。
(20:28)认证完成后,游戏还要读取本地玩家限制,决定是否隐藏功能。
// Local player restrictions
GKLocalPlayer.local.authenticateHandler = { viewController, error in
let isGameCenterReady = (viewController == nil) && (error == nil)
if isGameCenterReady {
if GKLocalPlayer.local.isUnderage {
// Hide explicit game content
}
if GKLocalPlayer.local.isMultiplayerGamingRestricted {
// Disable multiplayer game features
}
if GKLocalPlayer.local.isPersonalizedCommunicationRestricted {
// Disable in game communication UI
}
}
}
关键点:
authenticateHandler会自动启动 Game Center 认证,并在状态变化时回调。viewController == nil且error == nil表示本地玩家已准备好。isUnderage用来隐藏不适合未成年玩家的内容。isMultiplayerGamingRestricted用来关闭多人游戏入口。isPersonalizedCommunicationRestricted是 iOS 14 新增限制,用来关闭游戏内语音或消息等个性化通信 UI。
核心启发
-
做一个零干扰的 Game Center 主菜单入口:把 Access Point 放在主菜单角落,打开
showHighlights展示成就数量或默认排行榜名次;值得做的原因是玩家不用离开游戏就能找到个人资料和社交信息;开始时先在主菜单生命周期里设置GKAccessPoint.shared.location、showHighlights和isActive。 -
做一个“我的游戏资料”页按钮:在游戏设置页或存档页加入本地玩家资料入口;值得做的原因是玩家可以在同一处查看成就、好友和最近游玩信息;开始时用
GKGameCenterViewController(state: .localPlayerProfile)呈现系统资料页。 -
做一个可降级的多人游戏入口:认证后检查
isMultiplayerGamingRestricted,限制打开时隐藏多人按钮,限制关闭时进入匹配流程;值得做的原因是家长控制和账号限制会直接影响多人功能;开始时把限制检查放进GKLocalPlayer.local.authenticateHandler的成功分支。 -
做一个适配手柄的 Dashboard 入口:在 tvOS 或外接手柄菜单中,用
frameInScreenCoordinates判断焦点是否落在 Access Point 上;值得做的原因是客厅场景没有触摸操作,玩家仍需要清楚的焦点反馈;开始时把手柄追踪坐标转换到同一视图坐标,再调用triggerAccessPoint。 -
做一个不被系统入口遮挡的主菜单布局:观察
frameInScreenCoordinates,当 Access Point 展示 highlight 导致尺寸变化时移动标题图或按钮;值得做的原因是系统入口会常驻主菜单,遮挡会让玩家误触或看不清核心操作;开始时为主菜单元素增加可响应的安全边距。
关联 Session
- Tap into Game Center: Leaderboards, Achievements, and Multiplayer — 接在本 session 后,深入排行榜、成就、挑战和多人游戏的具体 API。
- Design for Game Center — 讲解 Dashboard 和 Game Center 资料页所需的视觉资产、主题色和展示规范。
- Support multiple users in your tvOS app — 补充 tvOS 共享设备上的多用户支持,与 Game Center 本地玩家切换相关。
- What’s new in App Store Connect — 了解后台配置更新,适合配合 Game Center 功能开关和资源管理一起阅读。
评论
GitHub Issues · utterances