You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

游戏开发中渐进式属性目标值设置的通用实现方案咨询

渐进式属性调整的泛型封装方案

核心思路

用泛型类封装当前值、目标值、调整增量,内置统一的Update()方法处理渐进趋近逻辑,同时通过自定义插值委托适配不同数据类型(如数值、向量等),避免为每个字段重复编写冗余代码。

实现泛型类 InterpolatingProperty<T>

public class InterpolatingProperty<T>
{
    // 当前属性值
    public T Current { get; private set; }
    // 目标属性值
    public T Target { get; private set; }
    
    // 插值逻辑委托:负责处理当前值向目标值的单次调整
    private readonly Func<T, T, T, T> _interpolator;
    // 每次调整的增量/步长
    private readonly T _increment;

    // 构造函数:传入初始值、增量、插值逻辑
    public InterpolatingProperty(T initialValue, T increment, Func<T, T, T, T> interpolator)
    {
        Current = initialValue;
        Target = initialValue;
        _increment = increment;
        _interpolator = interpolator;
    }

    // 设置新的目标值
    public void SetTarget(T target)
    {
        Target = target;
    }

    // 执行一次渐进调整
    public void Update()
    {
        Current = _interpolator(Current, Target, _increment);
    }

    // 直接将当前值同步到目标值(跳过渐进过程)
    public void SnapToTarget()
    {
        Current = Target;
    }
}

为不同类型编写插值逻辑

针对游戏中常见的数值、向量类型,编写对应的插值处理逻辑:

数值类型(以double为例)

// 处理double类型:每次向目标移动固定增量,到达目标后停止
public static double DoubleInterpolator(double current, double target, double increment)
{
    if (current < target)
    {
        return Math.Min(current + increment, target);
    }
    else if (current > target)
    {
        return Math.Max(current - increment, target);
    }
    return current;
}

二维向量类型(自定义Vector2示例)

public struct Vector2
{
    public double X { get; set; }
    public double Y { get; set; }

    public Vector2(double x, double y)
    {
        X = x;
        Y = y;
    }
}

// 处理Vector2类型:每个分量独立按增量趋近目标
public static Vector2 Vector2Interpolator(Vector2 current, Vector2 target, Vector2 increment)
{
    return new Vector2(
        DoubleInterpolator(current.X, target.X, increment.X),
        DoubleInterpolator(current.Y, target.Y, increment.Y)
    );
}

在Camera类中使用泛型属性

public class Camera
{
    // 封装缩放级别
    private readonly InterpolatingProperty<double> _zoomLevel;
    // 封装相机世界位置
    private readonly InterpolatingProperty<Vector2> _worldPosition;

    public Camera()
    {
        // 初始化缩放:初始值1.0,每次调整增量0.1
        _zoomLevel = new InterpolatingProperty<double>(1.0, 0.1, DoubleInterpolator);
        // 初始化位置:初始(0,0),X/Y方向每次增量0.5
        _worldPosition = new InterpolatingProperty<Vector2>(
            new Vector2(0, 0), 
            new Vector2(0.5, 0.5), 
            Vector2Interpolator
        );
    }

    // 对外暴露设置缩放目标的方法
    public void SetZoomTarget(double target)
    {
        _zoomLevel.SetTarget(target);
    }

    // 对外暴露设置位置目标的方法
    public void SetPositionTarget(Vector2 target)
    {
        _worldPosition.SetTarget(target);
    }

    // 统一更新所有渐进式属性
    public void Update()
    {
        _zoomLevel.Update();
        _worldPosition.Update();
    }

    // 对外提供当前缩放值的只读访问
    public double CurrentZoom => _zoomLevel.Current;
    // 对外提供当前位置的只读访问
    public Vector2 CurrentPosition => _worldPosition.Current;
}

扩展优化建议

  • 如果需要基于时间的平滑插值(如Lerp),可以替换插值逻辑为:
    public static double LerpInterpolator(double current, double target, double deltaTime)
    {
        // 0.1为平滑系数,值越大趋近速度越快
        return current + (target - current) * 0.1 * deltaTime;
    }
    
  • 可给InterpolatingProperty<T>添加IsAtTarget属性,判断当前值是否已到达目标,避免无效更新。

内容的提问来源于stack exchange,提问作者Rich. T.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 00:18:23