Unity XR / PC Engine Documentation

JJM Seat SDK 引擎开发指南

面向 Unity 3D / XR 游戏引擎的高性能 4D 动感座椅控制套件。开箱即用,支持跨平台姿态同步与风水气热多感官特效一体化联动。

Unity C# API Android 一体机 (XR) PC Windows x64 小白 & 通感 双座椅 Namespace: SeatControl
2 款
原生支持硬件型号
3-DOF + Yaw
自由度姿态控制
4 大类
4D 环境特效 (风/水/香/热)
100%
双端统一上层代码

💺 双座椅型号特性与配置

SDK 专为两种核心物理硬件进行了动力学建模与参数固化。开发者只需在 Inspector 下拉菜单选择对应型号,底层自动完成所有行程动力学与归零适配。

重载仿真型

通感座椅 (TongGan)

SeatType.TongGan = 1

高保真专业级沉浸式动感座椅。动力输出强劲平顺,出厂即校准在水平中立位,专为飞行模拟、赛车漂移与高端影院定制。

零位归零特性水平中立位 (0.0)
行程跨度135.0 ~ 235.0 mm
大轴 / 小轴尺寸185 mm / 50 mm
旋转减速比168.0 : 1
建议初始高度0.50 (平衡位)

🚀 极简快速上手

三步将动感控制集成到您的场景中,不需要编写任何底层通信与驱动逻辑。

1

导入 Unity Package & 拖入预制体

导入 JJMSeatSDK(Android 一体机)或 JJMSeatPCSDK_Unity(PC 端)。在启动场景中放入 SeatControlManager 预制体,默认勾选 persistAcrossScenes(跨场景不销毁)。

2

Inspector 中选择座椅型号

在 SeatControlManager 的 Inspector 面板中,将 Seat Type 下拉框切换为您的座椅型号(XiaoBai 或 TongGan),并确认座椅网络 IP(出厂默认:192.168.15.202)。

3

调用 C# API 驱动姿态与特效

在任何游戏逻辑、过山车控制或摄像机跟随脚本中,直接调用 SeatControlManager.Instance.SendSeatPosture(...)。

💡

部署建议:让座椅 IP 可配置

建议在进入游戏前提供一个「座椅连接设置」界面,让现场人员选择或填写当前座椅的 IP 与端口;也可以从固定路径读取 TXT / JSON 配置文件,由部署人员外部维护。

  • 玩家 / 现场设置:开局前输入或选择座椅地址,适配不同场地与设备。
  • 外置配置:无需重新打包即可切换 IP / 端口,适合批量部署与运维。
  • 运行时切换:配置变更后调用 SetUdpEndpoint() 即时生效,不打断风、水、香、热特效。

建议在应用配置前校验 IPv4 与端口范围;切换失败时保留原目标,并在界面明确提示。

C# 基础调用示例 (Starter Script)
using UnityEngine;
using SeatControl;

public class SeatGameplayController : MonoBehaviour
{
    void Start()
    {
        // 1. 发送初始姿态:俯仰 5°、高度 50%
        SeatControlManager.Instance.SendSeatPosture(
            new Vector3(5f, 0f, 0f), // Vector3(Pitch, Yaw, Roll)
            0.5f                     // Height: 0.0 ~ 1.0
        );

        // 2. 开启中级微风环境
        SeatControlManager.Instance.SetWindSpeed(2);
    }

    void OnTriggerEnter(Collider other)
    {
        // 3. 触发冲浪/落水剧情:喷射薄雾
        if (other.CompareTag("WaterSplash"))
        {
            SeatControlManager.Instance.SetWaterMist(1); // 1=薄雾, 2=小水珠, 3=大水珠
        }
    }
}

🎛️ 交互式姿态控制台 & C# 代码生成器

拖动下方控制滑块,即时查看 3D 虚拟平台姿态。下方将实时生成对应的 Unity C# 生产环境代码,支持一键复制粘贴。

硬件型号 (Seat Type) 选择当前测试设备
俯仰角度 (Pitch / 前后倾斜) 8.0°
翻滚角度 (Roll / 左右侧倾) -4.0°
偏航角度 (Yaw / 水平旋转) 15.0°
升降高度 (Height / 机构高度) 70%
// 等待计算...

💨 4D 多感官特效体验台

快速试用风速、水雾、香薰与热风组合,即时生成 SetEffectsCombination() 调用代码。

🍃 风速控制
0 关
1 微风
2 中风
3 强风
💧 水雾喷射
0 关
1 薄雾
2 小水珠
3 大水珠
🌸 香薰释放
0 关
香型1
香型2
🔥 热风开关
关闭
开启
// 特效代码就绪

🎮 SeatControlManager 核心接口

主控单例 MonoBehaviour,封装了全部姿态与特效驱动方法。

PC 端命名空间为 JJM.SeatPCSDK,Android 端为 SeatControl;两端方法名与参数语义保持一致,平台切换只需调整 using。

static property

Instance

public static SeatControlManager Instance { get; }

全局单例访问点。在场景中首次调用会自动查找已挂载的管理器实例。

method 核心主力接口

SendSeatPosture()

public void SendSeatPosture(Vector3 rotation, float height)

驱动座椅到达指定欧拉角姿态与升降高度。建议在游戏主循环(如 FixedUpdate)中以 30Hz ~ 60Hz 频率调用。

参数类型建议范围说明
rotation.xfloat-15.0 ~ 15.0Pitch (俯仰):正值前倾(俯冲/下坡),负值后仰(抬升/上坡)
rotation.yfloat0.0 ~ 360.0Yaw (偏航):水平旋转角度(度)
rotation.zfloat-15.0 ~ 15.0Roll (横滚):正值向右倾斜,负值向左倾斜
heightfloat0.0 ~ 1.0Height (升降高度):0.0 为最低点,0.5 为平衡位,1.0 为最高点
method

ResetPosture()

public void ResetPosture()

将座椅姿态迅速回位至中立位(rotation = Vector3.zero, height = 0.5)。常用于关卡结束、玩家重开或退出场景前。

method 运行时切换

SetUdpEndpoint()

public bool SetUdpEndpoint(string udpIp, int udpPort)

轻量切换当前座椅的姿态 UDP 目标。只更新目标 IP / 端口,不会重建风、水、香、热特效连接;本地固定源端口 8410 保持不变。适合在开局设置页或运行中切换不同座椅。

参数类型说明
udpIpstring新的 IPv4 地址,例如 192.168.15.251
udpPortint控制器监听端口,通常 7408,范围 1–65535

返回:成功返回 true;IP / 端口非法或 SDK 未初始化返回 false,并保留原目标。切换时会丢弃旧目标尚未发送的积压报文。

适用场景:多台座椅共用同一套风 / 水 / 香 / 热硬件时使用。如果新座椅的特效控制器 IP / 端口也不同,请调用 SetEffectsEndpoints(),只切换两路特效,不重建姿态连接。

C# 运行时切换座椅,不打断特效
// 切换到另一台座椅;风/水/香/热连接保持不动
bool ok = SeatControlManager.Instance.SetUdpEndpoint(
    "192.168.15.251", 7408);

if (!ok)
    Debug.LogWarning("目标切换失败,继续使用原座椅");

注意:直接修改 SeatConfig.udpIp 或 Inspector 字段只会改变配置数据,不会立即改变当前连接;必须调用本接口或 ApplyConnectionSettings()。

平台对应:PC DLL SeatSDK_SetUdpEndpoint(const char*, int);PC Unity JJM.SeatPCSDK.SeatControlManager.Instance.SetUdpEndpoint(...);Android Java SeatController.setUdpEndpoint(String, int);Unity Android SeatControl.SeatControlManager.Instance.SetUdpEndpoint(...)。

method 4D 特效 原子切换

SetEffectsEndpoints()

public bool SetEffectsEndpoints(string relayIp, int relayPort, string speedIp, int speedPort)

原子切换继电器与风速控制器的 IP / 端口。两路新连接都成功后才替换旧连接;任一路失败时保留旧连接,不会出现半切换。只修改特效端点,不重建姿态 UDP,本地固定源端口 8410 不变。

参数类型说明
relayIpstring继电器 IPv4,例如 192.168.15.7
relayPortint继电器 Modbus TCP 端口,通常 8234
speedIpstring风速控制器 IPv4,例如 192.168.15.8
speedPortint风速控制器端口,通常 8234

返回:两路都连接成功并完成切换返回 true;特效未启用、参数非法、任一路连接失败返回 false,旧连接继续可用。

内部固定:继电器从站地址 1、风速从站地址 1、风速寄存器 3 由 SDK 固定,不提供配置项,也不出现在 Inspector、UE 节点或本接口参数中。

安全行为:切换前会尽力关闭旧设备特效;新设备默认保持关闭,不会自动恢复风速/水雾/香薰/热风状态。该接口是配置操作,应在设置页调用,不要每帧调用。

容错:如果开局时特效 IP 填错、初始化失败,SDK 会保留特效控制器;修正地址后仍可调用本接口恢复连接,无需重建姿态 UDP。

C# 切换两路特效,失败保留旧连接
// 只切特效;姿态 UDP 与本地 8410 保持不变
bool ok = SeatControlManager.Instance.SetEffectsEndpoints(
    "192.168.15.7", 8234,
    "192.168.15.8", 8234);

if (!ok)
    Debug.LogWarning("特效切换失败,继续使用旧连接");

平台对应:PC DLL SeatSDK_SetEffectsEndpoints(const char*, int, const char*, int);PC Unity JJM.SeatPCSDK.SeatControlManager.Instance.SetEffectsEndpoints(...);Android Java SeatController.setEffectsEndpoints(String, int, String, int);Unity Android SeatControl.SeatControlManager.Instance.SetEffectsEndpoints(...)。

method 4D 特效

SetWindSpeed()

public void SetWindSpeed(int level)

调节迎面风速等级。参数:0=关闭,1=微风,2=中风,3=强风。

method 4D 特效

SetWaterMist()

public void SetWaterMist(int type)

调节水雾喷射效果。参数:0=关闭,1=薄雾,2=小水珠,3=大水珠。

method 4D 特效

SetScent()

public void SetScent(int type)

切换气味香薰。参数:0=关闭,1=香型1(如森林/草地),2=香型2(如海洋/花香)。

method 4D 特效

SetHeater()

public void SetHeater(bool isOn)

开启或关闭热风。开启后,当前风会被加热成热风。参数:true 为开启热风,false 为关闭热风。

💡

最佳热风效果建议

建议在需要热风感受前 提前 10–20 秒 开启热风,让风道与加热元件充分预热,再配合风速档位使用,热风效果更明显。

热风依附于当前风:风速为 0 时没有气流,应先开启风速,或同时调用 SetEffectsCombination()。

method 高效批量

SetEffectsCombination()

public void SetEffectsCombination(int wind, int mist, int scent, bool heater)

一次性原子调用设置所有环境特效,避免多次分散网络通讯。其中 heater 是热风开关;建议提前 10–20 秒打开,再配合风速档位。

method

TurnOffAllEffects()

public void TurnOffAllEffects()

一键停用所有风、水、气、热特效,游戏暂停或退出时推荐调用。

📦 数据配置结构

直接在 Unity Inspector 中可视化配置的序列化参数类。

Serializable

SeatConfig (全局配置)

字段类型默认值说明
seatTypeSeatTypeXiaoBai座椅型号枚举:XiaoBai = 0, TongGan = 1
udpIpstring"192.168.15.202"座椅姿态控制器 IP 地址
udpPortint7408UDP 通信端口
movementParamsMovementParams默认实例运动角度上限与灵敏度缩放配置
effectsConfigEffectsConfignull4D 特效硬件网关配置(为 null 时自动禁用特效)
Serializable

EffectsConfig (特效配置)

只允许配置两路特效的 IP / 端口。继电器从站地址、风速从站地址和风速寄存器由 SDK 固定为 1 / 1 / 3,不向开发者开放。

字段类型默认值说明
relayIpstring""继电器 IPv4(水雾、香薰、热风)
relayPortint8234继电器 Modbus TCP 端口
speedIpstring""风速控制器 IPv4(Modbus RTU over TCP)
speedPortint8234风速控制器端口
Serializable

MovementParams (运动参数)

字段类型默认值说明
pitchScalefloat0.7俯仰缩放系数(用于衰减或放大倾角感受)
rollScalefloat0.7横滚缩放系数
upDownScalefloat0.3升降缩放系数
seatPitchMaxAnglefloat15.0°俯仰最大安全角度限制
seatRollMaxAnglefloat15.0°横滚最大安全角度限制

🛠️ 引擎实战代码配方

实际商业项目中常见的姿态跟随与过山车物理映射方案。

C# 配方 1:VR 头显视角平滑跟随 (Camera Follower)
using UnityEngine;
using SeatControl;

public class VRCameraSeatFollower : MonoBehaviour
{
    [SerializeField] private Transform targetCamera;
    [SerializeField] private float maxPitch = 12f;
    [SerializeField] private float maxRoll = 10f;

    void FixedUpdate()
    {
        if (targetCamera == null) return;

        // 获取相机欧拉角并归一化至 -180 ~ 180
        var euler = targetCamera.localEulerAngles;
        float pitch = Mathf.DeltaAngle(0f, euler.x);
        float roll = Mathf.DeltaAngle(0f, euler.z);
        float yaw = euler.y;

        // 限幅保护
        pitch = Mathf.Clamp(pitch, -maxPitch, maxPitch);
        roll = Mathf.Clamp(roll, -maxRoll, maxRoll);

        // 发送至座椅 (以平衡高度 0.5 运行)
        SeatControlManager.Instance.SendSeatPosture(
            new Vector3(pitch, yaw, roll),
            0.5f
        );
    }
}

🖼️ 运行时调试面板 (SeatControlUI)

SDK 内置开箱即用的 Canvas 调试 HUD,直接挂载即可在游戏内测试所有接口。

将 SeatControlUI 挂载到场景中任意 Canvas 下,它将提供完整的可视化滑块与状态反馈:

UI 控件类型作用
pitchSliderSlider (-15 ~ +15)调试俯仰角姿态
rollSliderSlider (-15 ~ +15)调试侧倾角姿态
yawSliderSlider (0 ~ 360)调试水平偏航角
heightSliderSlider (0 ~ 1)调试整体升降高度
windDropdownDropdown (0-3)实时选择风速等级
resetButtonButton一键复位回零