如何在运行时动态修改样条曲线下的角色移动速度
角色移动速度实时调整实现方案
一、解决Inspector运行时修改movementSpeed不生效的问题
你的当前代码里Update直接读取movementSpeed变量,理论上运行时修改Inspector数值应该实时生效。如果没生效,大概率是原有代码在Awake/Start阶段把movementSpeed硬编码成固定值(比如movementSpeed = 5f;),或者把它缓存到了其他局部变量里。
- 检查并删除Awake/Start里对
movementSpeed的固定赋值语句,改成只在Inspector里设置初始值 - 确保所有用到移动速度的地方,都是直接读取
[SerializeField] float movementSpeed;这个变量,而非缓存的副本
二、用UI滑块实现运行时动态调整速度
步骤1:创建UI滑块
在Unity编辑器中依次点击 GameObject → UI → Slider,创建滑块控件。调整滑块的Min Value(比如设为0)和Max Value(比如设为10,按需调整),并把滑块初始值设为和movementSpeed一致。
步骤2:修改脚本支持滑块控制
在你的脚本中添加UI滑块引用,并绑定值改变事件,修改后的代码如下:
using UnityEngine; using UnityEngine.UI; [SerializeField, Self] InputReader input; [SerializeField] Transform followTarget; [SerializeField] float followDistance = 2f; [SerializeField] Vector2 movementLimit = new Vector2(x:2f, y:2f); [SerializeField] float movementRange = 5f; [SerializeField] float movementSpeed; // 保留SerializeField,Inspector可编辑 [SerializeField] float smoothTime = 0.2f; [SerializeField] float maxRoll = 15f; [SerializeField] float rollSpeed = 2f; [SerializeField] Slider speedSlider; // 新增滑块引用 Vector3 velocity; float roll; void Start() { if (speedSlider != null) { // 初始化滑块值为当前移动速度 speedSlider.value = movementSpeed; // 绑定滑块值变化时的回调 speedSlider.onValueChanged.AddListener(UpdateMovementSpeed); } } // 滑块值改变时更新移动速度 void UpdateMovementSpeed(float newSpeed) { movementSpeed = newSpeed; } void Update() { // 计算目标位置:基于跟随距离和目标位置 Vector3 targetPos = followTarget.position + followTarget.forward * -followDistance; // 对玩家位置应用平滑阻尼 Vector3 smoothedPos = Vector3.SmoothDamp(transform.position, targetPos, ref velocity, smoothTime); // 计算新的局部位置 Vector3 localPos = transform.InverseTransformPoint(smoothedPos); localPos.x += input.Move.x * movementSpeed * Time.deltaTime * movementRange; localPos.y += input.Move.y * movementSpeed * Time.deltaTime * movementRange; // 限制局部位置范围 localPos.x = Mathf.Clamp(localPos.x, -movementLimit.x, movementLimit.x); localPos.y = Mathf.Clamp(localPos.y, -movementLimit.y, movementLimit.y); // 更新玩家位置 transform.position = transform.TransformPoint(localPos); // 匹配玩家和跟随目标的旋转 transform.rotation = followTarget.rotation; // 根据输入匹配玩家翻滚角度 roll = Mathf.Lerp(roll, input.Move.x * maxRoll, Time.deltaTime * rollSpeed); transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, roll); }
替代方案:不用UI滑块的动态调整
如果不需要UI,也可以用键盘快捷键实现速度调整,在Update函数中添加这段逻辑即可:
void Update() { // ... 原有代码 ... // 按+/-键调整速度 if (Input.GetKeyDown(KeyCode.Equals)) movementSpeed += 0.5f; if (Input.GetKeyDown(KeyCode.Minus)) movementSpeed = Mathf.Max(0, movementSpeed - 0.5f); }
注意事项
- 如果不想暴露
movementSpeed为public,保留[SerializeField]即可,在滑块的On Value Changed事件面板里,直接拖入脚本所在物体,选择movementSpeed变量,Unity会自动生成赋值逻辑 - 滑块的数值范围要根据游戏需求调整,避免速度过高或过低导致移动异常
内容的提问来源于stack exchange,提问作者greyBow
相关产品推荐
相关产品推荐

