《速度限制原理》生死狙击物理引擎C#反编译代码解析【7yPh00N】

protected internal virtual void LimitVelocityMaxSpeed()
        {
            if (GetPlayerMove().GetImpulseTime() > 0 || GetPlayerMove().GetImpulseTime2() > 0 || !GetPlayerMove().GetIsLimitMaxSpeed())
            {
                return;
            }

            float num = _velocity[2];
            _velocity[2] = 0f;
            if (GetPlayerMove().GetPlayerStateType(33554432))
            {
                if (VectorUtils.VectorLength(_velocity) > (float)speed * 1.8f)
                {
                    VectorUtils.VectorNormalize(_velocity);
                    VectorUtils.VectorScale(_velocity, (float)speed * 1.8f, _velocity);
                }
            }
            else if (GetPlayerMove().GetDuckState() != 0 && GetPlayerMove().GetDuckState() != 1 && VectorUtils.VectorLength(_velocity) > (float)speed * 1.25f)
            {
                VectorUtils.VectorNormalize(_velocity);
                VectorUtils.VectorScale(_velocity, (float)speed * 1.25f, _velocity);
            }

            _velocity[2] = num;
        }

C#反编译代码(限速函数)

• 具体原理分析[上述代码解析]

这段代码是一个名为 LimitVelocityMaxSpeed 的函数,用于限制玩家角色的速度不超过某个阈值。以下是对这个函数的详细解释:

1.首先,函数使用条件判断来判定是否需要限制速度。以下是判定的条件:

①.GetPlayerMove().GetImpulseTime() > 0 || GetPlayerMove().GetImpulseTime2() > 0etImpulseTime2() > 0:判断脉冲时间是否大于0;(人物受到冲量影响)

②.GetPlayerMove().GetIsLimitMaxSpeed():判断是否允许限制最大速度。(例如:极限跳跃模式自带的不限速选项被开启)

2.如果上述条件1中的任何一个成立,函数会提前返回,不执行速度限制。

3.若上述条件1不满足,将保存速度向量的第三个分量为 num。然后,将速度向量的第三个分量 _velocity[2] 设置为0。这通常用于在垂直方向上限制速度。

4.接下来,函数根据不同的条件分支来进一步处理速度的水平分量:

①.如果 GetPlayerMove().GetPlayerStateType(33554432) 返回 true,表示玩家处于某种特殊状态,且速度的模大于速度乘以1.8(即速度的1.8倍),则将速度向量标准化(使其长度为1)然后缩放为速度的1.8倍。(玩家进行喷泉跳或受其他特殊物理打击时的限速方式,例如:660*1.8=1188)

②.如果 GetPlayerMove().GetDuckState() != 0 && GetPlayerMove().GetDuckState() != 1 成立,也就是玩家不处于 完全蹲下[Ducked] / 正在蹲下[Ducking] 的状态(详细蹲下状态定义方式见下方代码),并且速度的模大于速度乘以1.25(即速度的1.25倍),则将速度向量标准化然后缩放为速度的1.25倍。(这是最常规的限速方式,例如:660*1.25=825)

using System;

namespace Assets.Sources.Constant
{
	// Token: 0x020006F2 RID: 1778
	public class DuckState
	{
		// Token: 0x040016C9 RID: 5833
		public const int Ducked = 0; //角色完全蹲下状态

		// Token: 0x040016CA RID: 5834
		public const int Ducking = 1; //角色正在蹲下状态

		// Token: 0x040016CB RID: 5835
		public const int DuckJump = 2; //角色蹲下+跳跃状态

		// Token: 0x040016CC RID: 5836 
		public const int Unduck = 3; //角色站立状态

		// Token: 0x040016CD RID: 5837
		public const int DuckJumpLand = 4; //可能表示角色从跳跃中着陆并保持蹲下状态

		// Token: 0x040016CE RID: 5838
		public const int DuckJumpFinish = 5; //可能表示角色从跳跃中着陆并结束蹲下状态
	}
}

在上述条件4.②中,若玩家处于 完全蹲下[Ducked] / 正在蹲下[Ducking] 的状态(下文简称Dd01状态),则不限制人物移动速度。

例如:

Ⅰ.在部分上坡/管道进行蹲连跳时,人物会持续处于Dd01状态以达到不限速效果。(Dd01状态在理想情况下可从上坡/管道前的一小段平地持续至上坡/管道后的一小段平地);

Ⅱ.从高处坠落至下坡的瞬间按住蹲键起跳,人物会受到斜坡施加的外力影响瞬间增速,在Dd01状态下短暂突破限速后立即恢复限速。(Dd01状态持续时间 = 破速持续时间 = 0.1s);

Ⅲ.理论上玩家在进行蹲连跳时,若在Dd01状态内也就是起跳后的0.1s内将速度加至规定限速范围以上,同样可以实现破速效果。(Dd01状态结束后也就是起跳0.1s后恢复限速)。

↑ 例Ⅰ ↑       ↓ 例Ⅲ ↓

5.最后,将速度向量的第三个分量 _velocity[2] 恢复为刚保存的值 num。

• 结论

1.在部分上坡/管道进行蹲连跳或受到冲量影响时人物可持续突破限速;

2.从高处坠落至下坡的瞬间按住蹲键起跳可在接触斜坡起跳后的0.1秒内短暂大幅突破限速;

3.在平地蹲连跳起跳后的0.1秒内可短暂小幅突破限速;

4.常规限速值的计算公式:限速值 = 基础移速 * 1.25 [ 例如:660 * 1.25 = 825 ]

5.非常规限速值 (玩家进行喷泉跳或受其他特殊物理打击时) 的计算公式:限速值 = 基础移速 * 1.8 [ 例如:660 * 1.8 = 1188 ]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值