重要通知:与此问题相关的信息已被弃用,仅供历史参考。尽管在发布答案时问题已得到解决,但正在讨论的开发范例不再支持或接受其预期用途。
原问题如下:
我正在开发一个用于游戏发布的 WebView2 容器应用程序,并且有一些问题阻碍了开发过程。然而,该组件没有被正确读取,因此它的功能根本不起作用。举个例子:我有一个应该在 Javascript 端读取的字段,该字段旨在当容器应用程序未完全激活时阻止游戏输入(例如,如果在 Xbox 控制台上打开指南菜单)。不幸的是,由于 WinRT 组件未正确读取,该字段在 Javascript 端显示为未定义,导致用户的输入在所有情况下都被阻止。其他功能(包括从用户的 Xbox 帐户读取游戏保存)也存在同样的问题,这表明 WebView2 拾取 WinRT 组件存在重大问题。
这是我的示例案例的字段定义:
public static bool GameBarActive { get { return gameBarActive; } }
激活检测通过关联的窗口事件进行处理:
private static void Window_Activated(CoreWindow sender, WindowActivatedEventArgs args)
{
if (args.WindowActivationState == CoreWindowActivationState.Deactivated)
{
gameBarActive = true;
}
else
{
gameBarActive = false;
}
}
这里应该发生的是,当 gameBarActive 为 false 时,GameBarActive(公共只读版本)应该从 WinRT 组件返回内部可写版本的值。将 WinRT 组件连接到 WebView2 容器的 C# 代码将其放置在名为 Xbox 的顶级 Javascript 命名空间中,其中包含一个名为 API 的类,该类将 WinRT 组件公开给游戏。然而,由于 WinRT 组件没有在 Javascript 端被拾取,因此检测的行为就好像它总是正确的(实际上没有定义可言)。
以 RPG Maker MV 的控制器输入检测为例,输入块的功能应该如下:
if (Xbox.API.GameBarActive == false) {
var lastState = this._gamepadStates[gamepad.index] || [];
var newState = [];
var buttons = gamepad.buttons;
var axes = gamepad.axes;
var threshold = 0.5;
newState[12] = false;
newState[13] = false;
newState[14] = false;
newState[15] = false;
for (var i = 0; i < buttons.length; i++) {
newState[i] = buttons[i].pressed;
}
if (axes[1] < -threshold) {
newState[12] = true; // up
} else if (axes[1] > threshold) {
newState[13] = true; // down
}
if (axes[0] < -threshold) {
newState[14] = true; // left
} else if (axes[0] > threshold) {
newState[15] = true; // right
}
for (var j = 0; j < newState.length; j++) {
if (newState[j] !== lastState[j]) {
var buttonName = this.gamepadMapper[j];
if (buttonName) {
this._currentState[buttonName] = newState[j];
}
}
}
this._gamepadStates[gamepad.index] = newState;
}
任何有关正在发生的事情(或我可以尝试的其他任何事情)的见解将不胜感激。
大笨蛋。事实证明,我也有一些功能在应该公开的时候被设置为私有,这最终导致了更大的问题。最重要的是,在将处理方法从布尔值更改为字符串响应后,我忘记更改 Javascript 端匹配函数调用的名称。还有一个问题,无论大小写,都使用相同的拼写,这是我通过切换到函数调用来代替之前的字段值发现的,以及代码设计中的一个主要缺陷,即连续触发该方法,从而C# 方面的一些令人困惑的事情。
更新后的公共函数如下:
public static string getGameBarState()
{
return gameBarState;
}
更新后的检测如下:
private static void Window_Activated(CoreWindow sender, WindowActivatedEventArgs args)
{
if (args.WindowActivationState == CoreWindowActivationState.Deactivated)
{
gameBarState = "Active";
}
else
{
gameBarState = "Inactive";
}
}
内部字段如下:
static string gameBarState = "Inactive";
更新后的Javascript如下:
var lastState = this._gamepadStates[gamepad.index] || [];
var newState = [];
var buttons = gamepad.buttons;
var axes = gamepad.axes;
var threshold = 0.5;
newState[12] = false;
newState[13] = false;
newState[14] = false;
newState[15] = false;
for (var i = 0; i < buttons.length; i++) {
newState[i] = buttons[i].pressed;
}
if (axes[1] < -threshold) {
newState[12] = true; // up
} else if (axes[1] > threshold) {
newState[13] = true; // down
}
if (axes[0] < -threshold) {
newState[14] = true; // left
} else if (axes[0] > threshold) {
newState[15] = true; // right
}
for (var j = 0; j < newState.length; j++) {
if (newState[j] !== lastState[j]) {
console.log('Status of the Xbox Guide is as follows')
console.log(Xbox.API.getGameBarState());
if (Xbox.API.getGameBarState() != "Active") {
var buttonName = this.gamepadMapper[j];
if (buttonName) {
this._currentState[buttonName] = newState[j];
}
}
else {
return;
}
}
}
this._gamepadStates[gamepad.index] = newState;
虽然我仍在通过激活检测来验证 C# 端的事情(不知何故决定搞砸),但我想我已经弄清楚了。