Unity学习----【进阶】Input System学习(一)--导入与基础的设备调用API

·来源于唐老狮的视频教学,仅作记录和感悟记录,方便日后复习或者查找


一.Input System是什么

简单来说就是比老版的Input输入系统更先进,更方便,更加容易配置的一种检测各种设备的输入控制的系统

它和老输入系统的区别在于:

  • 老输入系统:需要我们手动去管理设备输入的判断时机来处理逻辑,
  • 新输入系统:能够在代码之外就配置好各种输入判断设置,让我们可以更加专注于处理按键判断之后的逻辑。同时它也同样可以像老输入系统一样使用,可以说是完全的上位替代。

二.Input System的导入与设置

我们需要去Package Manager中搜索Input System插件并下载安装。【安装完成之后会弹出一个窗口问你是否要使用新输入系统,选Yes即可,然后它会自动重启整个项目】

可以在bulid Setting -> player Setting -> player -> otherSetting 下找到 Active Input Handling 来设置当前项目是使用老的输入系统,还是新的输入系统,还是都保留使用


三.Input System中对设备按键调用的方式

1.键盘

Keyboard.current:能够直接获取当前存在的键盘设备(如果没有键盘会是空)

1.1.获取某个按键按的状态

//空格键 当前帧 是否按下
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
    print("空格键按下");
}

//判断D键是否释放
if (Keyboard.current.dKey.wasReleasedThisFrame)
{
    print("D键抬起");
}

//判断空格是否一直处于按下状态
if (Keyboard.current.spaceKey.isPressed)
{
    print("空格按下状态");
}


//任意键按下了
if(Keyboard.current.anyKey.wasPressedThisFrame)
{
    print("任意键按下");
}

①可以直接在Keyboard.current下点出来对应的按键(只要你知道它的英文名就好了),.anyKey是指任意按键

②它们分别后按下,按住,抬起的三个简单状态

1.2.绑定按下事件

//绑定按下事件
Keyboard.current.onTextInput += (c) => {
    print("按下的按键名字是:" + c);
};

①它可以绑定的函数传入的参数是一个字符,字符是这个按键的名字【不过它只能显示一个字符】

2.鼠标

Mouse.current:能够直接获取当前存在的鼠标设备(如果没有鼠标会是空)

2.1.鼠标的按键

//鼠标左键
mouse.leftButton
//鼠标右键
mouse.rightButton
//鼠标中键
mouse.middleButton
//鼠标 向前向后键
mouse.forwardButton;
mouse.backButton;

2.2.鼠标的按下

if (Mouse.current.leftButton.wasPressedThisFrame)
{
    print("鼠标左键按下");
}

//抬起
if (Mouse.current.leftButton.wasReleasedThisFrame)
{
    print("鼠标左键抬起");
}
//长按
if (Mouse.current.rightButton.isPressed)
{
    print("鼠标右键长按");
}

①基本上和键盘上按键按下的状态差不多

2.3.鼠标的常用数据

//鼠标在当前的屏幕位置(以屏幕分辨率为边界,左下角为原点)
print(Mouse.current.position.ReadValue());

//鼠标当前帧和上一帧的位移值
print(Mouse.current.delta.ReadValue());

//鼠标滑轮滚动的值
print(Mouse.current.scroll.ReadValue());

①这里我们获取值了之后,都是通过ReadValue()这个方法再转化读取出来的。

3.其他设备

InputSystem中可获取的设备有:

常用的

  • Keyboard—键盘
  • Mouse—鼠标
  • Touchscreen—触屏
  • Gamepad—手柄

其它

  • Joystick—摇杆
  • Pen—电子笔

Sensor(传感器)

  • Gyroscope—陀螺仪
  • GravitySensor—重力传感器
  • 加速传感器
  • 光照传感器

等等...更多的可以去官网看的(好像这个链接得用魔法)

https://docs.unity3d.com/Packages/com.unity.inputsystem@1.2/manual/Sensors.html#accelerometer


四.总结

①Input System是旧输入系统的完全上位替代,可以给开发者提供更加方便的输入配置方法以更专注于输入之后的逻辑

②Input System中可以直接获取多种设备,以像旧的输入系统一样进行逻辑判断后使用。不过其实我们并不推荐这样子做

③了解这个设备的输入与按键是为了对之后如何用Input System的配置功能来配置按键有更好的理解

<think>好的,用户想在Unity中找到设置try-catch的最佳实践代码示例。首先,我需要回忆Unity中使用C#的异常处理机制。根据引用[2]中的内容,C#的try-catch-finally结构是处理异常的基础,应该先确保用户了解基本用法。 然后,用户特别提到Unity环境,可能需要考虑Unity特有的情况,比如协程中的异常处理或者主线程之外的异常捕获。例如,Unity中的某些操作可能在主线程之外抛出异常,这时候需要确保异常能被正确捕获,避免应用崩溃。 接下来,引用[1]提到可以自定义异常类来统处理异常,这可能对用户有帮助。在Unity中,可能需要对不同的模块(如资源加载、网络请求)使用特定的异常类,方便调试和处理。例如,可以创建ResourceLoadException或NetworkException。 另外,引用[4]提到Unity编辑器打包后的应用可能存在不同行为,比如语音合成的尾音问题。这提示在编写try-catch时需要注意Unity编辑器和实际运行环境的差异,可能需要额外的日志记录或调试措施。 用户可能需要代码示例,所以应该提供几个典型场景的例子。比如资源加载、协程中的使用、网络请求等。同时,要强调避免在性能关键代码中过度使用try-catch,因为引用[3]的代码示例可能涉及性能影响,需注意。 还要考虑资源清理,使用finally块来释放资源,比如关闭文件或断开网络连接,确保资源的正确释放,避免内存泄漏。例如在加载资源后无论是否异常都进行清理。 另外,异常日志的记录也很重要,尤其是在Unity中,可以使用Debug.LogError输出到控制台,方便调试。同时,可能建议用户将异常信息上传到服务器进行分析,特别是在发布版本中。 最后,需要提醒用户不要滥用try-catch,只在可能出现异常的地方使用,避免掩盖潜在的错误。例如,输入验证应先使用条件检查,而不是依赖异常处理。 总结下来,回答应包含基本结构、自定义异常、资源清理、协程处理、日志记录和性能注意事项,并提供相应代码示例,确保用户能在Unity中有效应用try-catch的最佳实践。</think>### Unity中try-catch最佳实践及示例代码 在Unity中使用C#的异常处理机制时,需要结合游戏引擎特性进行优化设计。以下为结合引用内容和Unity特性的最佳实践方案: #### 基础结构优化 ```csharp try { // Unity资源加载等高危操作 Texture2D texture = Resources.Load<Texture2D>("NonExistentImage"); Instantiate(texture); // 可能触发空引用异常 } catch (System.NullReferenceException ex) { Debug.LogError($"资源加载失败: {ex.Message}"); // 使用默认资源进行补偿处理 Texture2D defaultTex = Resources.Load<Texture2D>("DefaultImage"); } catch (UnityException ex) { Debug.LogError($"Unity特有异常: {ex.GetType()} - {ex.Message}"); } finally { Resources.UnloadUnusedAssets(); // 确保资源释放[^2] } ``` #### 二、协程异常处理模式 ```csharp IEnumerator LoadNetworkData() { using (UnityWebRequest request = UnityWebRequest.Get("https://api.example.com")) { yield return request.SendWebRequest(); try { if (request.result == UnityWebRequest.Result.Success) { // 处理网络数据 } else { throw new CustomNetworkException(request.error); } } catch (CustomNetworkException ex) { Debug.LogError($"网络请求失败: {ex.ErrorCode}"); // 显示网络错误提示UI } } } ``` #### 三、自定义异常体系(基于引用[1]优化) ```csharp public class UnityResourceException : System.Exception { public string AssetPath { get; } public UnityResourceException(string path, string message) : base($"资源加载失败: {path} | {message}") { AssetPath = path; } } // 使用示例 try { GameObject prefab = Resources.Load<GameObject>("Characters/MainHero"); if(prefab == null) throw new UnityResourceException("Characters/MainHero", "角色预制体缺失"); } catch (UnityResourceException ex) { Debug.LogError(ex.Message); // 加载备用资源或进入安全模式 } ``` #### 四、性能敏感区处理(参考引用[3]) ```csharp void Update() { // 避免在每帧执行的代码中使用try-catch // 改为前置条件检查 if (_playerController != null) { _playerController.ProcessInput(); } else { HandleMissingComponent(); } } ``` #### 五、多线程异常捕获 ```csharp async void StartComplexCalculation() { try { await Task.Run(() => { // 后台线程中的计算 if (calculationFailed) throw new CalculationException("Matrix inversion failed"); }); } catch (CalculationException ex) { // Unity主线程中处理异常 Debug.LogException(ex); _errorDisplay.Show(ex.Message); } } ``` ### 核心原则: 1. **分层捕获**:按`具体异常→UnityException→Exception`顺序捕获[^2] 2. **资源保障**:using语句finally块必须包含`Object.Destroy`/`Resources.Unload`等 3. **日志规范**:使用`Debug.LogError`记录完整调用堆栈 4. **异常转换**:将底层异常封装为业务语义明确的异常类型[^1] 5. **性能隔离**:Update/FixedUpdate等高频方法避免使用try-catch
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萘柰奈

谢谢老板喵

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值