已归档 - 激战幽灵游戏: 面部跟踪技术在游戏《Mystery Mansion》*中的应用

英特尔® 实感™ SDK 已停产。 不再继续提供支持或更新。

Mystery Mansion* 是一款灵异类隐藏物品冒险游戏,由资深游戏开发人员 Cyrus Lum 倾力打造而成。 这款游戏在 2014 年英特尔® 实感™ 应用挑战赛中,凭借创新的实验性方法赢得评委们的肯定,一举夺得“创新先锋 (Pioneer)”类别的冠军。

在进行自我介绍时,Lum 表示希望通过这款游戏“带给玩家更多的悬念,让大家沉浸在我精心构建的故事和世界中。” 《Mystery Mansion》开创性地在用户界面 (UI) 中使用了面部跟踪技术,成功为玩家带来卓越的沉浸式体验。 然而,在 Lum 寻求实施直观控制,并使用简单 UI 打造满意的用户体验的过程中,这一跟踪面部的方法带来许多的开发挑战。 在本文中,我们将探讨 Lum 遇到的挑战,以及用于解决这些挑战的代码,包括如何准确地为不同玩家校准游戏 UI,以及使用有意限定的控制方案,移动和操纵物品。


《Mystery Mansion》* 闪屏,展现了其核心的灵异惊悚主题。

优化和挑战

面部跟踪

Lum 在研究使用英特尔® 实感™ SDK的功能,而非手势控制功能的过程中,产生了开发《Mystery Mansion》的灵感。 最终他决定开发一款游戏,完全通过面部跟踪技术来进行控制。

在研究了能够与相应简化的 UI 搭配的游戏主题和机制后,Lum 决定开发一款第一人称的点击式隐藏物品冒险游戏。 在研究仅用头部控制游戏的过程中(就像没有身体一样),Lum 产生了使用“无形”幽灵作为游戏主要角色的想法。 在《Mystery Mansion》中,玩家扮演一个困在公寓中的幽灵的角色,尝试找出自己死亡的秘密。

鼻子和眼睛

游戏要求玩家用眼睛探查环境,寻找并收集一系列物品。 针对水平和垂直移动,英特尔® 实感™ 摄像头 F200 会跟踪面部的移动(主要是鼻子),让玩家可以直观地观察周围的环境。 玩家面部的方向性移动在屏幕上以十字线呈现。


红色十字线由玩家面部的移动控制,面部移动使用英特尔® 实感™ 摄像头进行跟踪。

Lum 希望玩家能够 360 度探查环境,包括向左,向右,甚至向后看。 为了实现这一目标,他实施了一种机制,当玩家超越特定水平移动阈值时,视野就会向这一方向偏移,在玩家的视野靠近屏幕的边缘时,移动将会加速。

在放大和缩小环境时,英特尔实感摄像头会跟踪玩家眼睛与摄像头的距离。 用户眼睛距离摄像头越近,用户就会离环境越远,从而缩小环境(反之则放大环境)。 摄像头焦距进行了精心校准,确保玩家无需太靠近屏幕,就能有效放大物品。

/* get face data and calculate camera FOV based on eye distance.  Use face data to rotate camera. */	
	void OnFaceData(PXCMFaceData.LandmarksData data) {
		if (!visualizeFace) return;
		if (colorSize.width == 0 || colorSize.height == 0) return;
		
		PXCMFaceData.LandmarkPoint[] points;
		if (!data.QueryPoints(out points)) return;
		
		/* Use nose tip as the control point */
		PXCMPointF32 xy=points[data.QueryPointIndex(PXCMFaceData.LandmarkType.LANDMARK_NOSE_TIP)].image;
		
		/* Get Left and Right Eye to calculate distance */
		PXCMPointF32 xyEyeLeft=points[data.QueryPointIndex(PXCMFaceData.LandmarkType.LANDMARK_EYE_LEFT_CENTER)].image;
		PXCMPointF32 xyEyeRight=points[data.QueryPointIndex(PXCMFaceData.LandmarkType.LANDMARK_EYE_RIGHT_CENTER)].image;	

		float tmpEye = Mathf.Abs ((xyEyeLeft.x - xyEyeRight.x) * eyeDistScale);
		if (tmpEye < eyeDistNear) tmpEye = eyeDistNear;
		if (tmpEye > eyeDistFar) tmpEye = eyeDistFar;
		
		/* Use eyes apart distance to change FOV */
		Camera.current.fieldOfView = eyeFOVcenter - tmpEye;

代码示例 1:这一代码使用用户眼睛与摄像头的距离来计算其与屏幕的距离,然后相应调整视野。

优化 UI

校准

Lum 注意到每一个玩家的玩游戏方式均略有差异,同时每一个面部五官的大小和位置也切实存在不同。 这意味着在每一次游戏开始时校准面部跟踪功能至关重要,以确保每一名玩家均能够正确使用方向控制功能。 Lum 在每一次游戏开始时插入了一个校准环节,以便为玩家建立“起始位置”,确保他们处于摄像头的有效跟踪范围内。

要在校准阶段建立“起始位置”,玩家需要移动头部,使十字线处于屏幕中心的方框内。 这可以确保玩家在转动头部,向前或向后移动头部时,均能够始终处于摄像头范围内(跟踪范围)。 这一流程可确保每一名玩家不会受到面部形状、大小和相对于摄像头的位置的影响,始终能够获得出色体验。


每一次游戏开始时的校准环节确保可为每一名游戏玩家带来一致、准确的体验。

//check to see if target graphic is within the box
if (!calibrated && calibratedNose && gameStart && (295 * screenScaleWidth) < targetX && targetX < (345 * screenScaleWidth) && (235 * screenScaleHeight) < targetY && targetY < (285 * screenScaleHeight)) {
			calibrated = true;
			tutorialImg = tutorial1Img;
			LeanTween.alpha(tutorialRect, 1f, 2f) .setEase(LeanTweenType.easeInCirc).setDelay(1.5f);
			LeanTween.alpha(tutorialRect, 0f, 2f) .setEase(LeanTweenType.easeInCirc).setDelay(8f).setOnComplete (showTutorialTurn);
		}

代码示例 2:这一代码通过确保目标十字线位于校准屏幕截图上的红色框内,来校准游戏。

水平移动

摄像头在水平方向上的自由移动非常重要,有助于帮助创建出 Lum 希望为玩家提供的 360 度视野。 安全区和旋转加速功能对于使用游戏内建摄像头确保提供最佳用户体验至关重要。

//— rotate camera based on face data ———
		/* Mirror the facedata input, normalize */
		xy.x=(1-(xy.x/colorSize.width));
		xy.y=(xy.y/colorSize.height);

		/* exponentially accelerate the rate of rotation when looking farther away from the center of the screen, use rotateAccelerationScale to adjust */
		newX = (0.5f-xy.x)*(rotateAccelerationScale*Mathf.Abs((0.5f-xy.x)*(0.5f-xy.x)));
		newY = (0.5f-xy.y)*(rotateAccelerationScale*Mathf.Abs((0.5f-xy.y)*(0.5f-xy.y)));

		/* Camera is a hierarchy  mainCamBase  with Main Camera as a child of mainCamBase.  We will horizontally rotate the parent mainCamBase  */
		mainCamBase.transform.Rotate(0, (newX * (lookTimeScale*Time.deltaTime)), 0);

		/* angleY is a rotation accumulator */
		angleY += newY;
		if (angleY > lookUpMin && angleY < lookUpMax) {

			mainCam.transform.Rotate ((newY * (lookTimeScale * Time.deltaTime)), 0, 0);
			if(angleY < lookUpMin) angleY = lookUpMin;
			if(angleY > lookUpMax) angleY = lookUpMax;
		}
		else angleY -= newY;

代码示例 3:这一代码负责在用户将头部从屏幕中心转向周围时,控制摄像头的旋转和水平加速。

如果玩家将十字线保持在屏幕中心的特定区域,约水平范围的 50%,摄像头不会旋转,这可以确保玩家能够探查区域,同时摄像头不会无意中移动。 当十字线从该区域移出时,水平移动开始在玩家视线方向上发生,并随着玩家将十字线移向屏幕边缘进行加速。 这可以为玩家带来准确、直观的 360 度控制能力。

垂直移动

Lum 的实验显示,摄像头的自由移动在垂直方向上不太实用,因为如果两个方向都发生作用,玩家会失去方向感。 此外,考虑到游戏的互动元素集中在视野的水平地带,玩家看天花板或地板没有多大的用处。 然而,玩家也需要一定的垂直移动,以发现靠近地板或突起表面上的物品。 为了提供此功能,Lum 在上下方向上提供了 30 度的移动范围,这使得玩家能够观察四周而不会失去方向感。

游戏过程优化

在评估了各种游戏过程机制后,Lum 决定在核心的物品收集游戏内容之外,添加一些简单的解谜元素。 解谜元素能够无缝融入整个游戏设计之中,并可仅使用面部跟踪 UI 直观有效地完成实施。

玩家通过将十字线移动到物品上面将其捡起,就如同将鼠标指针放在物品上面一样。 在触发点,物品如同受到超自然力牵引一样,从环境中飞向玩家,进入屏幕上的物品背包中。


在上图中,玩家通过移动面部将十字线放在一个物品上将其选中,使得物品(本例中为一个药品箱)飞向玩家,进入背包。

Ray ray = Camera.current.ScreenPointToRay(new Vector3((float)targetX, (float)Screen.height-(float)targetY, (float)0.1f));
RaycastHit hit;
if (Physics.Raycast(ray, out hit,100 )) {
	if(hit.collider.name.Contains("MysItem")){
		hit.collider.transform.Rotate(new Vector3(0,-3,0));
	}
}

代码示例 4:这一代码让玩家可以使用面部跟踪 UI 捡起物品。

Lum 还需要玩家能够以一种适合简单 UI 和游戏逻辑的方式,从一个房间移动到另一个房间。 在此方面,每一个房间出口门,仅会在玩家收集到所有设定的物品后打开。 此时,玩家通过移动面部将十字线移动到门上,使门打开,然后移动游戏场景进入下一个空间。

为了增加游戏的多样性,Lum 评估并添加了不同的解谜机制,可以通过同样简单的逻辑方式加以操纵。 其中一个谜题是方块谜题,玩家需要使用方向控制键将方框移动到框架内。 Lum 以多种方式实施了此操作,包括移动方块到一个图片框以重建图像,以及移动门上的管道将其打开等。

else if(hit.collider.name.Contains("puzzleGame")){
	room currentRoom = (room)rooms[roomID];
	puzzleItem tmpPuzzleItem = (puzzleItem)currentRoom.puzzleItems[hit.collider.name];
	if(!LeanTween.isTweening(hit.collider.gameObject) && !tmpPuzzleItem.solved){
		if(hit.collider.name.Contains("_Rot")){
			LeanTween.rotateAroundLocal ( hit.collider.gameObject, Vector3.up, 90f, 2f ).setEase (LeanTweenType.easeInOutCubic).setOnCompleteParam (hit.collider.gameObject).setOnComplete (puzzleAnimFinished);
		}
	}
}

代码示例 5:这一代码允许玩家使用面部跟踪 UI 移动方块,以完成某些游戏谜题。


谜题包括此方框图。 玩家使用方向控制键移动组件,重建图像,从而找到线索。


在此谜题中,玩家使用面部跟踪方向控制键移动管道部件。

此外,当玩家需要离开房间时,屏幕上还会显示文本提示,帮助玩家确定下一步骤。

测试和分析

《Mystery Mansion》由 Lum 独自开发而成,因此大部分的测试工作也由他自己完成。 然而,在开发期间,他请求三个朋友帮助测试了游戏。

在视频游戏领域,没有玩家会以完全相同的方式玩游戏,对一名玩家直观的设定,对另一名可能就并非如此。 这一差异很快便在外部测试期间成为 Lum 亟需解决的一个挑战,尤其是在面部跟踪方面。 由于他们会以不同的方式为自己定位,或者仅仅是因为面部大小和五官位置的简单差异,测试人员很难推进游戏。 Lum 经过仔细观察,决定在开始游戏前实施一个校准环节,并在开始前添加了教程,以确保 UI 原理易于理解。


教程让玩家能够能好地了解如何进使用面部跟踪界面与游戏进行互动。

重要经验

对于 Lum 而言,在使用英特尔实感技术和人机界面技术的过程中,简单性至关重要。在其开发《Mystery Mansion》的过程中,一个核心理念就是 UI 将仅适用于面部跟踪。 他对于不进行太多工作添加机制和特性的重要性坚信不疑,尽管这些机制和特性在开始时看起来非常不错。 在环境中移动并仅使用面部跟踪 UI 操纵物品要求对精简的 UI 进行精心迭代开发,并提供详细的教程,以确保玩家永远不会不知道该做什么,或如何推进游戏。

测试在《Mystery Mansion》的开发过程中发挥了重要作用。 Lum 发现开发人员不应假定对一名玩家奏效的方式,会自动适用于其他玩家。 每一名玩家在游戏中均有不同的行为,在英特尔实感摄像头的人机界面中,每一名玩家的面部和手均具有不同的尺寸、形状、移动方式和位置属性,必须在代码中加以调整。

英特尔实感 SDK 的 Unity Toolkit 中包含的资源为 Lum 提供了一个直观的开发环境。 Unity* 是一个简单易用的开发环境,经过了英特尔实感 SDK 的全面测试,与该 SDK 具备出色的兼容性。它包含丰富的资源(包括通过英特尔实感 SDK 提供的资源),强大的支持社区,以及由 Asset Store 提供的可立即使用的广泛图形资产库。

Lum 认为开发人员应始终考虑长时间用手势控制玩游戏对健康的影响,如果 UI 未能针对玩家进行有效设计,此类游戏有时会导致四肢疲劳。

工具与资源

Lum 发现使用英特尔实感 SDK 开发游戏的过程非常简单直接。 他还投入时间观看可用的演示,来寻找实用的提示,包括在英特尔实感 SDK 中提供的 Nine Cubes 样本等。

Unity

Lum 选择使用 Unity 开发游戏,它兼容英特尔实感 SDK,提供了一个完整的开发环境。 Lum 在使用 C# 语言编程方面成就卓著,Unity 平台帮助他消除了许多基础的编程工作,让他能够在开发和测试原型方面快速进行迭代。

MonoDevelop*

为了开发 C# 游戏脚本,Lum 使用了由 Unity 提供的集成开发环境 MonoDevelop。 Lum 使用 MonoDevelop 放置物品,设置属性,添加行为和逻辑,以及为集成英特尔实感摄像头数据编写脚本。

Nine Cubes

构建《Mystery Mansion》的一个基础构建模块是 Nine Cubes 样本,它是一个在英特尔实感摄像头 SDK 中提供的 Unity 软件样本(可以在 SDK 的样本目录的框架文件夹中找到)。 这一演示让用户可以使用面部跟踪技术移动立方体,具体则主要是通过跟踪鼻子来完成。 这一功能为《Mystery Mansion》 的 UI 奠定了重要基础。

Unity Technologies Asset Store

Lum 在前一个项目中,已经在使用 Unity Technologies Asset Store 方面积累了丰富的经验。通过从这里为《Mystery Mansion》寻找图形元素,Lum 节省了宝贵的时间,依靠一己之力开发出了这一图形效果出色的游戏。 同时幸运的时,他在寻找素材的时候适逢万圣节,因此这让他能够轻松找到许多会将人尖叫不已的图形素材。

《Mystery Mansion》的未来发展

在提交《Mystery Mansion》参加英特尔实感应用挑战赛之后,Lum 继续试验各种特性,致力于营造出更加沉浸式的体验。 例如,最近的迭代开发允许玩家通过将箱子或容器倾向一边,查看里面的东西。 这一操作最终将会使得一些东西掉出来,营造出真正的惊悚感觉。 Lum 的观点是,实际操作在游戏中越真实,对于玩家的吸引力就越强,带给他们的体验就越精彩。

目前,《Mystery Mansion》主要适用于配备英特尔实感面板跟踪摄像头的笔记本电脑和台式机。 Lum 已经在 Google Tango* 平板电脑上进行了测试,渴望在采用英特尔实感技术的平板电脑和移动平台上开展类似的工作,尤其是考虑到英特尔正在与 Google 合作为采用英特尔实感技术的手机 Project Tango,Lum 坚信其中将蕴含着巨大的商机。

英特尔实感 SDK: 展望未来

根据 Lum 的经验,上下文对于成功实施英特尔实感技术至关重要。 Lum 认为该项技术在 3D 扫描物品,并将相关信息与日益普及的 3D 打印进行关联方面蕴含巨大潜力,并对此充满期待。

在 Lum 自己的人机技术工作方面,他当前正在最近开始的另一个英特尔实感 SDK 项目中试验其想法。该项目名为《My Pet Shadow》,在 2013 年英特尔感知计算挑战赛中夺得了第一名。 《My Pet Shadow》是一款“投影现实”原型游戏,使用 LCD 投影仪投射阴影,支持用户以不同方式与其进行交互。 这一现实与数字世界的交互融合极大地吸引了 Lum,随着他不断探索英特尔实感技术的无限可能,这为他提供了一个新的发展方向。


Lum 的英特尔® 实感™ 项目《My Pet Shadow》在 2013 年英特尔® 感知计算挑战赛中夺得第一名。

开发人员介绍

Cyrus Lum 在游戏制作、开发和管理方面具有超过 25 的经验,曾在出版和独立开发公司就职,包括位于德州奥斯汀的 Midway Studios、Inevitable Entertainment Inc.、Acclaim Entertainment 和 Crystal Dynamics 等。 他所担任的职位包括总监、联合创始人和数字制作副总裁等。 当前,Lum 是 Phunware Inc. 的顾问,以及软件开发公司 21 Pink 的副总裁。 此外,他还自 1997 年起一直是游戏开发人员大会顾问委员会 (Game Developer Conference Advisory Board) 的成员。

更多资源

Cyrus Lum 网站

MonoDevelop

Unity

英特尔® 实感® 技术英特尔® 开发人员专区

英特尔® 实感™ SDK

英特尔® 实感™ 开发人员套件

英特尔实感技术教程

有关编译器优化的更完整信息,请参阅优化通知