Unity角色移动:如何仅在Vector3超出-1/1时执行normalized处理?
解决斜向移动速度翻倍且避免停止延迟的问题
嘿,这个问题我之前做角色移动系统的时候也踩过一模一样的坑!斜向移动时速度翻倍,是因为同时按下水平和垂直方向输入后,移动向量的模长变成了√2(大概1.414),相当于速度被无形放大了;而直接用normalized的话,哪怕你松开按键后输入开始衰减(Input.GetAxis会平滑降到0),向量会一直被拉到模长1的状态,导致角色没法跟着输入渐变减速,就出现了你说的停止延迟。
给你一个精准的解决方案:只在移动向量的模长超过1的时候才执行归一化,这样既修正了斜向速度溢出的问题,又完美保留了正常的减速手感。
修改后的代码
// 获取输入(注意你的变量名好像搞反了?forwardInput对应Horizontal,horizontalInput对应Vertical,不过不影响核心逻辑) float forwardInput = Input.GetAxis("Horizontal"); float horizontalInput = Input.GetAxis("Vertical"); // 先创建原始移动向量,不着急归一化 Vector3 movement = new Vector3(horizontalInput, 0, forwardInput); // 关键逻辑:只有当向量的平方模长超过1时才归一化(用sqrMagnitude避免开平方,性能更优) if (movement.sqrMagnitude > 1f) { movement = movement.normalized; } // 最后应用速度和时间增量,执行移动 movement *= speed * Time.deltaTime; transform.Translate(movement);
为什么这么做有效?
- 当你同时按下水平+垂直键时,原始向量的模长是√2,平方模长就是2,大于1,这时候归一化会把向量压缩到模长1,速度就和单方向移动完全一致,不会再翻倍。
- 当你松开按键,
Input.GetAxis会从1平滑降到0,这时候向量的模长会跟着慢慢从1降到0,不会触发归一化条件,角色会跟着输入的衰减平滑减速,完全不会有停止延迟的问题。
另外补充个小细节:用sqrMagnitude代替magnitude来判断,是因为计算magnitude需要开平方,属于相对耗时的操作;而sqrMagnitude直接计算向量分量的平方和,性能更优,对于判断是否超过1的场景来说,效果完全一致。
内容的提问来源于stack exchange,提问作者FloodAndBones
相关产品推荐
相关产品推荐

