吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 25845|回复: 49
上一主题 下一主题
收起左侧

[C&C++ 原创] [代码中的数学]CSGO自瞄原理

  [复制链接]
跳转到指定楼层
楼主
Keing 发表于 2018-11-12 17:48 回帖奖励
本帖最后由 Keing 于 2019-1-20 15:31 编辑

说到FPS游戏的自瞄,大家都会想到读玩家的坐标,然后将坐标转化为屏幕坐标,再移动鼠标,其实这个有很大的缺陷,而且过程也比较麻烦,分辨率一换又要出问题
还有一种自瞄方法,现在CSGO大多数自瞄都是这样一个原理,获得敌人和自己的坐标,通过坐标来计算角度,通过写角度来实现自瞄
目前通用的计算角度函数是这样的
[C++] 纯文本查看 复制代码
void CalcAngle( float *src, float *dst, float *angles )
{
    double delta[3] = { (src[0]-dst[0]), (src[1]-dst[1]), (src[2]-dst[2]) };
    double hyp = sqrt(delta[0]*delta[0] + delta[1]*delta[1]);
    angles[0] = (float) (asinf(delta[2]/hyp) * (180/3.1415926));
    angles[1] = (float) (atanf(delta[1]/delta[0]) * (180/3.1415926));
    angles[2] = 0.0f;
    if(delta[0] >= 0.0) { angles[1] += 180.0f; }
}


不过我今天要讲的是另一种算法,但是也相差不多

图上是两个玩家在三维上的位置,分别是A(-4,-2,1),B(4,2,1)
如果B是我们自己,而A是敌人,我们可以通过计算向量BA来得到两个玩家之间的距离,向量BA=A-B=(8,4,1),计算出向量BA后我们可以把我们自己也就是B当成原点坐标重新建立一个三维坐标系,如下图:

而敌人的坐标就是我们求出来的向量了
给大家简单介绍一个关于三维的概念:
· pitch是围绕X轴旋转,也叫做俯仰角
· yaw是围绕Y轴旋转,也叫做偏航角
以人物角色看,yaw是左右偏动,而picth是上下偏动,,在游戏中角度都是固定的一个方向,偏航和我们学习的二维坐标一样的,0°,90°,180°,270°,,而俯仰正Z轴是-90°,负Z轴是90°,俯仰可能和我们平时认知有点不一样,,不过不重要,我们继续
红色和X轴夹角我们称之为yaw,可以通过arctan(y/x)来计算出,而图中 yaw = arctan(4/8) ≈ 26°
蓝色和红色夹角我们称之为pitch,可以通过arcsin(z/红色),而 红色 = sqrt(x2 + y2) 所以 pitch = srcsin(2/(sqrt(82+42))) ≈ 6.37°
刚刚说过Z轴正半轴是-90°,而我们算出来是6.37°,很明显,如果俯仰以6.37°来写,那么我们的视角会朝下移动,所以我们要给俯仰度数取反 pitch = arcsin(z/红色) * -1
大家可能以为到这儿就结束了,其实不然,还有另外一种情况,我们继续往下看

如果最初我们是以A为我们玩家本身,B是敌人,那么我们要求的向量就是向量AB了,而向量AB = B - A = (-8,-4,1)
这样我们就可以以A为原点,敌人B的位置就是向量AB取成点的坐标,同样的道理我们计算出  红线 和 X 轴负半轴的夹角为 -26°,刚刚说到偏航是X轴开始为0°,如果我们直接写入-36°,那么玩家视觉必定转向的是第四象限而不是第三象限,所以我们就需要在算法里面多加一条判断 (敌人-我) 的X是否小于等于0 ,如果满足 yaw = yaw + 180°
我们刚刚算的在第一象限的时候 X > 0 并未满足小于等于0 所以yaw是26° ,不需要加180°,写入角度26°也会转向26°位置
而第三象限的时候 X < 0 满足了小于等于0 所以 yaw = -26 °+ 180° = 154°,大家可以想象一下 154°是否为第三象限玩家所在位置度数


OK,现在大功告成,我们只需要获得自己头部位置和敌人头部位置,然后通过以上计算得出yaw和pitch,在通过写内存来达到自瞄头部,,我把简单过程写出来,具体函数我就不写了哈
角度计算函数:
[C++] 纯文本查看 复制代码
vec3 aimbot::calcAngles(vec3 us,vec3 them)
{
        vec3 dists;
        dists =them - us;
        float hyp = dists.magnitude();
        vec3 result;
        result.x = (asinf(dists.z / hyp)*57.295779513082f) ;
        result.y = (atanf(dists.y / dists.x)*57.295779513082f);
        result.z = 0;
        if (dists.x <= 0)
        {
                result.y += 180;
        }
        result.x = -result.x;
        return result;
}

大家可能会问为什么会有*57.295779513082f,这个是 180/3.1415926得到的,因为C++里asinf和atanf得出的弧度值,需要*(180/PI) 来转化为度数


[C++] 纯文本查看 复制代码
void aimbot()
{
        Player localPlayer = utils.getLocalPlayer();
        Player closetPlayer = aim.getCloset();
        closetPlayer.getInfo();
        if (getClassid(closetPlayer.base) != 35)
                return;
        vec3 v2;
        v2 = getBonePos(localPlayer.base);
        vec3 v1;
        v1 = getBonePos(closetPlayer.base);
        vec3 aimat = aim.calcAngles(v2, v1);
        int pViewAngle = vam.Read<int>(bEngine + clientState);
        vam.Write<float>((pViewAngle + ViewAngles), aimat.x);
        vam.Write<float>((pViewAngle + ViewAngles + 0x4), aimat.y);
}


aimat.x接受的是pitch,aimait.y接受的是yaw;其他的函数我就不发出来了哈,这里主要是介绍csgo自瞄中的数学,其他的大家可以自己去学习
if (getClassid(closetPlayer.base) != 35) 这句是判断玩家实体是否为玩家

vec3:
[C++] 纯文本查看 复制代码
class vec3
{
public:
        float x;
        float y;
        float z;
        vec3() :x(0), y(0), z(0){}
        vec3(float x,float y,float z):x(x),y(y),z(z){}
        vec3 operator + (vec3 v)
        {
                vec3 vr;
                vr.x = this->x + v.x;
                vr.y = this->y + v.y;
                vr.z = this->z + v.z;
                return vr;
        }
        vec3 operator - (vec3 v)
        {
                vec3 vr;
                vr.x = this->x - v.x;
                vr.y = this->y - v.y;
                vr.z = this->z - v.z;
                return vr;
        }
        float magnitude()
        {
                return sqrt((x * x) + (y * y) + (z * z));
        }
}


大家有什么不理解的可以在下面发粗来我给你们解答-.-+,只限本教程的哈

免费评分

参与人数 12吾爱币 +14 热心值 +11 收起 理由
寻常巷陌” + 1 用心讨论,共获提升!
JuDei + 1 + 1 用心讨论,共获提升!
南冥的小鲲 + 1 + 1 用心讨论,共获提升!
Kaiter_Plus + 1 + 1 楼主厉害,教程很是详细。
lwick + 1 + 1 用心讨论,共获提升!
nacht + 1 + 1 我很赞同!
堕落死亡 + 1 + 1 谢谢@Thanks!
孤梦。 + 1 + 1 谢谢@Thanks!
wxyzlibo + 1 谢谢@Thanks!
笙若 + 1 谢谢@Thanks!
wushaominkk + 5 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
我在京东开天猫 + 1 + 1 666

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
阿政0506 发表于 2019-5-20 17:07
老哥有没有兴趣一起研究csgo,现在我在5E B5都有在玩,平滑自瞄还有点小缺陷,比较简陋。x_r 和y_r是最计算出来自瞄到敌人头的鼠标数值,x_r - 计算之前鼠标X的值 = 鼠标从准心移动到敌人的值     ,最后写x_r -  鼠标从准心移动到敌人的值. 老哥怎么改进或者说有没有思路是不是有问题?
沙发
wgg666 发表于 2018-11-12 18:02 来自手机
3#
 楼主| Keing 发表于 2018-11-12 18:12 |楼主
wgg666 发表于 2018-11-12 18:02
请问能教我求生之路怎么写自瞄外挂嘛

游戏外挂最好是从基础开始,你可以先去看看那些比较基础的
4#
xiaoyi279 发表于 2018-11-12 18:21 来自手机
太厉害了
5#
xiaoyi279 发表于 2018-11-12 18:31 来自手机
楼主,这个画坐标系的软件叫什么啊?
6#
 楼主| Keing 发表于 2018-11-12 18:39 |楼主
xiaoyi279 发表于 2018-11-12 18:31
楼主,这个画坐标系的软件叫什么啊?

Sketchpad,不过这个是收费的,我也没买,我是试用20分钟慢慢画的。。。。。
7#
mengcfunk 发表于 2018-11-12 19:17
自瞄可还行,学到了学到了!6666666666666666666666666666!
8#
为注册等了十年 发表于 2018-11-12 22:08 来自手机
大佬就是大佬
9#
 楼主| Keing 发表于 2018-11-12 22:14 |楼主

其实就简单的三角函数问题。。。。仔细看一下很容易理解的
10#
寒江雪2018 发表于 2018-11-12 22:18 来自手机
外挂还有这么复杂的数学原理,受教了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 13:11

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表