JJM Seat SDK 引擎开发指南
面向 Unity 3D / XR 游戏引擎的高性能 4D 动感座椅控制套件。开箱即用,支持跨平台姿态同步与风水气热多感官特效一体化联动。
💺 双座椅型号特性与配置
SDK 专为两种核心物理硬件进行了动力学建模与参数固化。开发者只需在 Inspector 下拉菜单选择对应型号,底层自动完成所有行程动力学与归零适配。
小白座椅 (XiaoBai)
针对便携式、紧凑型体验台研发。冲程比大,响应极快,非常适合家庭体验、轻量商业展台及短平快互动娱乐。
通感座椅 (TongGan)
高保真专业级沉浸式动感座椅。动力输出强劲平顺,出厂即校准在水平中立位,专为飞行模拟、赛车漂移与高端影院定制。
🚀 极简快速上手
三步将动感控制集成到您的场景中,不需要编写任何底层通信与驱动逻辑。
导入 Unity Package & 拖入预制体
导入 JJMSeatSDK(Android 一体机)或 JJMSeatPCSDK_Unity(PC 端)。在启动场景中放入 SeatControlManager 预制体,默认勾选 persistAcrossScenes(跨场景不销毁)。
Inspector 中选择座椅型号
在 SeatControlManager 的 Inspector 面板中,将 Seat Type 下拉框切换为您的座椅型号(XiaoBai 或 TongGan),并确认座椅网络 IP(出厂默认:192.168.15.202)。
调用 C# API 驱动姿态与特效
在任何游戏逻辑、过山车控制或摄像机跟随脚本中,直接调用 SeatControlManager.Instance.SendSeatPosture(...)。
部署建议:让座椅 IP 可配置
建议在进入游戏前提供一个「座椅连接设置」界面,让现场人员选择或填写当前座椅的 IP 与端口;也可以从固定路径读取 TXT / JSON 配置文件,由部署人员外部维护。
- 玩家 / 现场设置:开局前输入或选择座椅地址,适配不同场地与设备。
- 外置配置:无需重新打包即可切换 IP / 端口,适合批量部署与运维。
- 运行时切换:配置变更后调用
SetUdpEndpoint()即时生效,不打断风、水、香、热特效。
建议在应用配置前校验 IPv4 与端口范围;切换失败时保留原目标,并在界面明确提示。
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# 生产环境代码,支持一键复制粘贴。
// 等待计算...
💨 4D 多感官特效体验台
快速试用风速、水雾、香薰与热风组合,即时生成 SetEffectsCombination() 调用代码。
// 特效代码就绪
🎮 SeatControlManager 核心接口
主控单例 MonoBehaviour,封装了全部姿态与特效驱动方法。
PC 端命名空间为 JJM.SeatPCSDK,Android 端为 SeatControl;两端方法名与参数语义保持一致,平台切换只需调整 using。
Instance
全局单例访问点。在场景中首次调用会自动查找已挂载的管理器实例。
SendSeatPosture()
驱动座椅到达指定欧拉角姿态与升降高度。建议在游戏主循环(如 FixedUpdate)中以 30Hz ~ 60Hz 频率调用。
| 参数 | 类型 | 建议范围 | 说明 |
|---|---|---|---|
rotation.x | float | -15.0 ~ 15.0 | Pitch (俯仰):正值前倾(俯冲/下坡),负值后仰(抬升/上坡) |
rotation.y | float | 0.0 ~ 360.0 | Yaw (偏航):水平旋转角度(度) |
rotation.z | float | -15.0 ~ 15.0 | Roll (横滚):正值向右倾斜,负值向左倾斜 |
height | float | 0.0 ~ 1.0 | Height (升降高度):0.0 为最低点,0.5 为平衡位,1.0 为最高点 |
ResetPosture()
将座椅姿态迅速回位至中立位(rotation = Vector3.zero, height = 0.5)。常用于关卡结束、玩家重开或退出场景前。
SetUdpEndpoint()
轻量切换当前座椅的姿态 UDP 目标。只更新目标 IP / 端口,不会重建风、水、香、热特效连接;本地固定源端口 8410 保持不变。适合在开局设置页或运行中切换不同座椅。
| 参数 | 类型 | 说明 |
|---|---|---|
udpIp | string | 新的 IPv4 地址,例如 192.168.15.251 |
udpPort | int | 控制器监听端口,通常 7408,范围 1–65535 |
返回:成功返回 true;IP / 端口非法或 SDK 未初始化返回 false,并保留原目标。切换时会丢弃旧目标尚未发送的积压报文。
适用场景:多台座椅共用同一套风 / 水 / 香 / 热硬件时使用。如果新座椅的特效控制器 IP / 端口也不同,请调用 SetEffectsEndpoints(),只切换两路特效,不重建姿态连接。
// 切换到另一台座椅;风/水/香/热连接保持不动
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(...)。
SetEffectsEndpoints()
原子切换继电器与风速控制器的 IP / 端口。两路新连接都成功后才替换旧连接;任一路失败时保留旧连接,不会出现半切换。只修改特效端点,不重建姿态 UDP,本地固定源端口 8410 不变。
| 参数 | 类型 | 说明 |
|---|---|---|
relayIp | string | 继电器 IPv4,例如 192.168.15.7 |
relayPort | int | 继电器 Modbus TCP 端口,通常 8234 |
speedIp | string | 风速控制器 IPv4,例如 192.168.15.8 |
speedPort | int | 风速控制器端口,通常 8234 |
返回:两路都连接成功并完成切换返回 true;特效未启用、参数非法、任一路连接失败返回 false,旧连接继续可用。
内部固定:继电器从站地址 1、风速从站地址 1、风速寄存器 3 由 SDK 固定,不提供配置项,也不出现在 Inspector、UE 节点或本接口参数中。
安全行为:切换前会尽力关闭旧设备特效;新设备默认保持关闭,不会自动恢复风速/水雾/香薰/热风状态。该接口是配置操作,应在设置页调用,不要每帧调用。
容错:如果开局时特效 IP 填错、初始化失败,SDK 会保留特效控制器;修正地址后仍可调用本接口恢复连接,无需重建姿态 UDP。
// 只切特效;姿态 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(...)。
SetWindSpeed()
调节迎面风速等级。参数:0=关闭,1=微风,2=中风,3=强风。
SetWaterMist()
调节水雾喷射效果。参数:0=关闭,1=薄雾,2=小水珠,3=大水珠。
SetScent()
切换气味香薰。参数:0=关闭,1=香型1(如森林/草地),2=香型2(如海洋/花香)。
SetHeater()
开启或关闭热风。开启后,当前风会被加热成热风。参数:true 为开启热风,false 为关闭热风。
最佳热风效果建议
建议在需要热风感受前 提前 10–20 秒 开启热风,让风道与加热元件充分预热,再配合风速档位使用,热风效果更明显。
热风依附于当前风:风速为 0 时没有气流,应先开启风速,或同时调用 SetEffectsCombination()。
SetEffectsCombination()
一次性原子调用设置所有环境特效,避免多次分散网络通讯。其中 heater 是热风开关;建议提前 10–20 秒打开,再配合风速档位。
TurnOffAllEffects()
一键停用所有风、水、气、热特效,游戏暂停或退出时推荐调用。
📦 数据配置结构
直接在 Unity Inspector 中可视化配置的序列化参数类。
SeatConfig (全局配置)
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
seatType | SeatType | XiaoBai | 座椅型号枚举:XiaoBai = 0, TongGan = 1 |
udpIp | string | "192.168.15.202" | 座椅姿态控制器 IP 地址 |
udpPort | int | 7408 | UDP 通信端口 |
movementParams | MovementParams | 默认实例 | 运动角度上限与灵敏度缩放配置 |
effectsConfig | EffectsConfig | null | 4D 特效硬件网关配置(为 null 时自动禁用特效) |
EffectsConfig (特效配置)
只允许配置两路特效的 IP / 端口。继电器从站地址、风速从站地址和风速寄存器由 SDK 固定为 1 / 1 / 3,不向开发者开放。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
relayIp | string | "" | 继电器 IPv4(水雾、香薰、热风) |
relayPort | int | 8234 | 继电器 Modbus TCP 端口 |
speedIp | string | "" | 风速控制器 IPv4(Modbus RTU over TCP) |
speedPort | int | 8234 | 风速控制器端口 |
MovementParams (运动参数)
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
pitchScale | float | 0.7 | 俯仰缩放系数(用于衰减或放大倾角感受) |
rollScale | float | 0.7 | 横滚缩放系数 |
upDownScale | float | 0.3 | 升降缩放系数 |
seatPitchMaxAngle | float | 15.0° | 俯仰最大安全角度限制 |
seatRollMaxAngle | float | 15.0° | 横滚最大安全角度限制 |
🛠️ 引擎实战代码配方
实际商业项目中常见的姿态跟随与过山车物理映射方案。
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 控件 | 类型 | 作用 |
|---|---|---|
pitchSlider | Slider (-15 ~ +15) | 调试俯仰角姿态 |
rollSlider | Slider (-15 ~ +15) | 调试侧倾角姿态 |
yawSlider | Slider (0 ~ 360) | 调试水平偏航角 |
heightSlider | Slider (0 ~ 1) | 调试整体升降高度 |
windDropdown | Dropdown (0-3) | 实时选择风速等级 |
resetButton | Button | 一键复位回零 |