clamp
2026/4/14大约 4 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — clamp
clamp
定义
clamp() 用来把一个数值"夹"在指定的最小值和最大值之间——简单说,就是"画两条线,不许越界"。
想象一个温度调节器,最低只能调到 16 度,最高只能调到 30 度。不管你使劲往左拧到 10 度还是往右拧到 50 度,实际温度只会在 16 到 30 之间。clamp() 就是这个温度调节器:你给它一个值和两条边界线,它帮你把值"夹"在这两条线之间。
在游戏开发中,clamp() 是使用频率极高的函数。角色的生命值不能超过上限也不能低于 0、移动速度不能超过最大值、UI 进度条必须在 0~100% 之间、相机旋转角度不能超过可视范围……几乎所有涉及"数值范围限制"的场景都会用到它。
clamp() 是 clampf()(浮点数版)和 clampi()(整数版)的"通用版",会根据你传入的参数类型自动判断该用哪个。
函数签名
C#
// 浮点数版本
public static float Clamp(float value, float min, float max)
// 整数版本
public static int Clamp(int value, int min, int max)GDScript
# 自动适配 int 和 float
func clamp(value: float, min: float, max: float) -> float参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
value | float 或 int | 是 | 要限制的原始数值 |
min | float 或 int | 是 | 允许的最小值(下限) |
max | float 或 int | 是 | 允许的最大值(上限) |
返回值
float 或 int —— 被"夹"在 [min, max] 范围内的值(类型与输入一致)。具体规则:
- 如果
value小于min,返回min - 如果
value大于max,返回max - 如果
value已经在范围内,返回value本身
代码示例
C#
// ===== 基础用法:三种情况演示 =====
float a = Mathf.Clamp(5.0f, 0.0f, 10.0f);
// 运行结果: a = 5.0(在范围内,原样返回)
float b = Mathf.Clamp(-3.0f, 0.0f, 10.0f);
// 运行结果: b = 0.0(低于下限,返回下限)
float c = Mathf.Clamp(15.0f, 0.0f, 10.0f);
// 运行结果: c = 10.0(超过上限,返回上限)
// ===== 实际场景:角色生命值管理 =====
[Export] public int ExMaxHealth = 100;
private int _currentHealth = 85;
public void Heal(int amount)
{
// 回血后不能超过最大生命值
_currentHealth = Mathf.Clamp(_currentHealth + amount, 0, ExMaxHealth);
GD.Print($"治疗后血量: {_currentHealth}");
}
public void TakeDamage(int damage)
{
// 受伤后不能低于 0
_currentHealth = Mathf.Clamp(_currentHealth - damage, 0, ExMaxHealth);
GD.Print($"受伤后血量: {_currentHealth}");
}
// 调用示例:
// Heal(30) → 运行结果: 治疗后血量: 100(被上限截住)
// TakeDamage(200) → 运行结果: 受伤后血量: 0(被下限截住)
// ===== 进阶用法:相机视角限制 =====
[Export] public float ExMinPitch = -60.0f; // 最低仰角(向下看)
[Export] public float ExMaxPitch = 80.0f; // 最高仰角(向上看)
private float _pitchAngle = 0.0f;
public override void _UnhandledInput(InputEvent ev)
{
if (ev is InputEventMouseMotion motion)
{
// 鼠标上下移动控制俯仰角
_pitchAngle -= motion.Relative.Y * 0.2f;
// 把角度限制在允许范围内,防止相机翻转
_pitchAngle = Mathf.Clamp(_pitchAngle, ExMinPitch, ExMaxPitch);
GD.Print($"俯仰角: {_pitchAngle:F1} 度");
}
}
// 运行结果: 俯仰角: -60.0 度(到达下限,不再继续下降)GDScript
# ===== 基础用法:三种情况演示 =====
var a = clamp(5.0, 0.0, 10.0)
# 运行结果: a = 5.0(在范围内,原样返回)
var b = clamp(-3.0, 0.0, 10.0)
# 运行结果: b = 0.0(低于下限,返回下限)
var c = clamp(15.0, 0.0, 10.0)
# 运行结果: c = 10.0(超过上限,返回上限)
# ===== 实际场景:角色生命值管理 =====
@export var ex_max_health: int = 100
var _current_health: int = 85
func heal(amount: int) -> void:
# 回血后不能超过最大生命值
_current_health = clamp(_current_health + amount, 0, ex_max_health)
print("治疗后血量: %d" % _current_health)
func take_damage(damage: int) -> void:
# 受伤后不能低于 0
_current_health = clamp(_current_health - damage, 0, ex_max_health)
print("受伤后血量: %d" % _current_health)
# 调用示例:
# heal(30) → 运行结果: 治疗后血量: 100(被上限截住)
# take_damage(200) → 运行结果: 受伤后血量: 0(被下限截住)
# ===== 进阶用法:相机视角限制 =====
@export var ex_min_pitch: float = -60.0 # 最低仰角(向下看)
@export var ex_max_pitch: float = 80.0 # 最高仰角(向上看)
var _pitch_angle: float = 0.0
func _unhandled_input(ev: InputEvent) -> void:
if ev is InputEventMouseMotion:
# 鼠标上下移动控制俯仰角
_pitch_angle -= ev.relative.y * 0.2
# 把角度限制在允许范围内,防止相机翻转
_pitch_angle = clamp(_pitch_angle, ex_min_pitch, ex_max_pitch)
print("俯仰角: %.1f 度" % _pitch_angle)
# 运行结果: 俯仰角: -60.0 度(到达下限,不再继续下降)注意事项
clamp()是一个通用函数,在 GDScript 中可以同时处理整数和浮点数。如果需要明确类型,请使用clampf()(浮点数)或clampi()(整数)。- C# 中
Mathf.Clamp()有多个重载版本(overload),编译器会根据你传入的参数类型(int还是float)自动选择对应版本。 - 必须确保
min <= max。如果min大于max,行为是未定义的(可能返回min,也可能返回max,取决于具体实现),这是最常见的 bug 来源之一。 clamp()等价于min(maxValue, max(minValue, value))——先保证不低于下限,再保证不超过上限。clamp()是游戏开发中使用频率最高的函数之一,几乎所有涉及数值范围控制的场景都会用到它。当你发现自己在写if (x < min) x = min; if (x > max) x = max;时,直接换成clamp()就对了。
