You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Forms游戏适配Razer Kishi及跨平台游戏控制器方案咨询

Xamarin.Forms游戏控制器支持解决方案

Android平台支持Razer Kishi输入:可行,实现步骤如下

Razer Kishi属于标准HID游戏控制器,Android原生支持,可通过Xamarin.Forms的依赖服务调用Android原生API实现输入监听:

  1. 声明游戏手柄支持
    在Android项目的AndroidManifest.xml中添加特性声明(非必须,但能帮助应用商店分类):
<uses-feature android:name="android.hardware.gamepad" android:required="false" />
  1. 定义共享接口
    在Xamarin.Forms共享项目中创建统一的游戏控制器服务接口:
public interface IGameControllerService
{
    event EventHandler<GamepadInputEventArgs> GamepadInputReceived;
    void StartListening();
    void StopListening();
}

public class GamepadInputEventArgs : EventArgs
{
    public int ButtonCode { get; set; }
    public bool IsPressed { get; set; }
    public float LeftStickX { get; set; }
    public float LeftStickY { get; set; }
    public float RightStickX { get; set; }
    public float RightStickY { get; set; }
}
  1. Android平台实现接口
    创建Android平台的依赖服务实现,利用系统InputDevice和MotionEvent监听输入:
[assembly: Dependency(typeof(AndroidGameControllerService))]
namespace YourGame.Droid.Services
{
    public class AndroidGameControllerService : IGameControllerService, Java.Lang.Object, View.IOnGenericMotionListener, View.IOnKeyListener
    {
        private readonly Activity _currentActivity;
        public event EventHandler<GamepadInputEventArgs> GamepadInputReceived;

        public AndroidGameControllerService()
        {
            _currentActivity = Platform.CurrentActivity;
            _currentActivity.Window.DecorView.SetOnGenericMotionListener(this);
            _currentActivity.Window.DecorView.SetOnKeyListener(this);
        }

        public void StartListening() { }

        public void StopListening()
        {
            _currentActivity.Window.DecorView.SetOnGenericMotionListener(null);
            _currentActivity.Window.DecorView.SetOnKeyListener(null);
        }

        public bool OnGenericMotion(View v, MotionEvent e)
        {
            if ((e.Source & InputSourceType.Gamepad) != 0)
            {
                var inputArgs = new GamepadInputEventArgs
                {
                    LeftStickX = e.GetAxisValue(Axis.X),
                    LeftStickY = e.GetAxisValue(Axis.Y),
                    RightStickX = e.GetAxisValue(Axis.Z),
                    RightStickY = e.GetAxisValue(Axis.Rz)
                };
                GamepadInputReceived?.Invoke(this, inputArgs);
                return true;
            }
            return false;
        }

        public bool OnKey(View v, Keycode keyCode, KeyEvent e)
        {
            if ((e.Source & InputSourceType.Gamepad) != 0 && e.Action == KeyEventActions.Down)
            {
                var inputArgs = new GamepadInputEventArgs
                {
                    ButtonCode = (int)keyCode,
                    IsPressed = true
                };
                GamepadInputReceived?.Invoke(this, inputArgs);
                return true;
            }
            return false;
        }
    }
}
  1. 共享项目调用
    在游戏逻辑中通过依赖服务获取实例,处理输入:
var controllerService = DependencyService.Get<IGameControllerService>();
controllerService.GamepadInputReceived += (sender, args) =>
{
    // 处理A键按下
    if (args.ButtonCode == (int)Keycode.ButtonA && args.IsPressed)
    {
        // 执行游戏操作,比如跳跃
    }
    // 处理左摇杆移动
    if (Math.Abs(args.LeftStickX) > 0.1f)
    {
        // 控制角色左右移动
    }
};
controllerService.StartListening();

跨平台(Android+iOS)解决方案:存在,实现方式如下

通过依赖服务分别实现Android和iOS的原生游戏控制器监听,共享统一接口,实现跨平台输入处理:

  1. 复用共享接口
    直接使用上述的IGameControllerService和GamepadInputEventArgs接口。

  2. iOS平台实现接口
    利用iOS原生GCController框架实现输入监听:

[assembly: Dependency(typeof(iOSGameControllerService))]
namespace YourGame.iOS.Services
{
    public class iOSGameControllerService : IGameControllerService
    {
        private GCController _connectedController;
        public event EventHandler<GamepadInputEventArgs> GamepadInputReceived;

        public void StartListening()
        {
            GCController.DidConnect += OnControllerConnected;
            GCController.DidDisconnect += OnControllerDisconnected;
            GCController.StartWirelessControllerDiscovery();
        }

        public void StopListening()
        {
            GCController.DidConnect -= OnControllerConnected;
            GCController.DidDisconnect -= OnControllerDisconnected;
            if (_connectedController != null)
            {
                _connectedController.ExtendedGamepad.ValueChanged -= OnGamepadValueChanged;
                _connectedController = null;
            }
        }

        private void OnControllerConnected(object sender, GCControllerEventArgs e)
        {
            _connectedController = e.Controller;
            if (_connectedController.ExtendedGamepad != null)
            {
                _connectedController.ExtendedGamepad.ValueChanged += OnGamepadValueChanged;
            }
        }

        private void OnControllerDisconnected(object sender, GCControllerEventArgs e)
        {
            if (_connectedController == e.Controller)
            {
                _connectedController.ExtendedGamepad.ValueChanged -= OnGamepadValueChanged;
                _connectedController = null;
            }
        }

        private void OnGamepadValueChanged(GCGamepad pad, GCControllerElementChangedEventArgs e)
        {
            var inputArgs = new GamepadInputEventArgs
            {
                LeftStickX = pad.LeftThumbstick.XAxis.Value,
                LeftStickY = pad.LeftThumbstick.YAxis.Value,
                RightStickX = pad.RightThumbstick.XAxis.Value,
                RightStickY = pad.RightThumbstick.YAxis.Value
            };

            // 处理A键
            if (pad.ButtonA.Pressed)
            {
                inputArgs.ButtonCode = (int)GCInputButton.A;
                inputArgs.IsPressed = true;
                GamepadInputReceived?.Invoke(this, inputArgs);
            }
            // 其他按键(B、X、Y等)同理处理
        }
    }
}
  1. 跨平台统一调用
    共享项目中的调用逻辑与Android完全一致,无需额外修改,依赖服务会自动匹配当前平台的实现。

注意事项

  • Android端:Razer Kishi符合标准Android游戏手柄映射,直接使用Keycode.ButtonA等常量即可识别按键。
  • iOS端:Razer Kishi iOS版本为Lightning接口,无需蓝牙权限;若支持无线控制器,需在Info.plist中添加NSBluetoothAlwaysUsageDescription权限说明。

内容的提问来源于stack exchange,提问作者Tommi Gustafsson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 19:05:32