Unity中如何钳制指向鼠标的LineRenderer距离并同步功率条UI

实现方法
核心思路是统一力度计算逻辑:对鼠标拖拽的原始距离做上限钳制,用同一份计算结果同时驱动LineRenderer绘制、击球力度计算、功率条UI更新,从根源避免三者数值不同步;钳制操作仅修改长度不改变归一化后的方向向量,不会影响瞄准指向。
第一步 新增配置字段
先在脚本类中添加可配置参数和缓存变量,方便在Inspector面板实时调整参数:
[Header("瞄准与力度设置")] public float maxAimLength = 3.5f; // LineRenderer最大绘制长度,对应满力度击球 public UnityEngine.UI.Slider powerBar; // 左下角功率条UI组件 private float currentShotPower; // 缓存当前钳制后的击球力度 private Vector3 currentShotDir; // 缓存当前瞄准方向
第二步 修改画线逻辑
在绘制线段时先做水平面坐标对齐、方向归一化、距离钳制,再同步更新线渲染器和功率条:
private void DrawLine(Vector3 worldPoint) { // 对齐到球所在水平面,消除Y轴坐标差带来的距离计算误差 Vector3 horizontalHitPoint = new Vector3(worldPoint.x, transform.position.y, worldPoint.z); // 计算归一化瞄准方向,保证指向永远和鼠标拖拽方向一致 Vector3 aimDir = (horizontalHitPoint - transform.position).normalized; // 计算原始拖拽距离 float rawDragDistance = Vector3.Distance(transform.position, horizontalHitPoint); // 钳制距离到设定的上限,超过最大值时按最大长度计算 float clampedDistance = Mathf.Clamp(rawDragDistance, 0f, maxAimLength); // 计算线渲染器的实际终点 Vector3 lineEndPos = transform.position + aimDir * clampedDistance; // 更新LineRenderer Vector3[] positions = { transform.position, lineEndPos }; lineRenderer.SetPositions(positions); lineRenderer.enabled = true; // 同步更新功率条,0-1的比例值直接适配Slider的value范围 if (powerBar != null) { powerBar.value = clampedDistance / maxAimLength; } // 缓存计算结果,供击球逻辑直接使用 currentShotDir = aimDir; currentShotPower = clampedDistance; }
第三步 修改击球逻辑
直接使用缓存的方向和力度值,避免重复计算导致数值不一致:
private void Shoot() { isAiming = false; lineRenderer.enabled = false; // 重置功率条 if (powerBar != null) { powerBar.value = 0f; } // 施加击球力 rb.AddForce(currentShotDir * currentShotPower * shotPower); }
调整说明
- 调用Shoot方法时不需要再传入worldPoint参数,所有瞄准阶段的计算结果已经提前缓存
- 如果功率条是用Image做的填充式进度条,把Slider赋值的逻辑替换为
fillImage.fillAmount = clampedDistance / maxAimLength即可 - maxAimLength参数可以在运行时直接在Inspector调整,直到线长上限、最大击球力度符合设计预期
- 全程使用归一化方向向量计算,距离钳制不会改变瞄准指向
内容的提问来源于stack exchange,提问作者jshel
相关产品推荐
相关产品推荐

