本帖最后由 战争傀儡阿格兰 于 2024-1-24 19:35 编辑
代码环境1.171
【战团】阿格兰魔球修改器——合集 https://bbs.mountblade.com.cn/thread-2097734-1-1.html
参考资料:
1.高虎。大佬用了一套高深的代码。。。完全没有领悟,只好自己重新设计
2.R大的领军者。script_prsnt_line_with_angle。本来以为在3D能用,结果测试了下完全不对。。但是给我积累了经验:3D空间下,坐标系xyz相减,是有bug的。需要2D对准的朋友可以直接去看他的代码。
代码实际效果:pos1对准pos2,输出reg0 = 两点直线距离
注:
1.无需pos2的位置、方向、运动速度、加速度
2.等同"agent_set_look_target_position ,再读取头部骨骼pos"
3.瞬间对准,不带动画。用物体animate到pos即可转向(该过程可能很鬼畜)
4.单次对准,如果需要长期对准,需要触发器刷新
5.如需偏移(对不准),微调x和z的旋转
6.直接position_move_y即可沿着对准的方向移动(对于pos而言,坐标系已经变了)
7.使用后直接addmisle,就能实现pos1向pos2射一箭的效果
8.y的旋转不影响前进方向,是类似“歪头”的那种旋转,可以模拟带膛线旋转的子弹等
9.应用场景举例:相机聚焦 addmisle 飞行物 战场ai(配合触发器逼着agent面向某地,或者朝着某目标开火) 场景动画
代码使用方式:用于各式触发器,改改也能在魔球里用
#coding:utf-8
#agland
#script_pos_aim_at_pos:
# Input: arg1 = pos_1, arg2 = pos_2,
# Output: reg0 = distance_between_pos
# Input:pos1对准pos2,等同"agent_set_look_target_position ,再读取头部骨骼pos",
# Output: 两点投影距离
("pos_aim_at_pos",
[
#(set_fixed_point_multiplier,1000),
#(assign, ":pos_1", pos31),
#(assign, ":pos_2", pos11),
(store_script_param, ":pos_1", 1),
(store_script_param, ":pos_2", 2),
#还原 方法一
(position_get_x, ":old_x_1", ":pos_1"),
(position_get_y, ":old_y_1", ":pos_1"),
(position_get_z, ":old_z_1", ":pos_1"),
(init_position,":pos_1"),
(position_set_x, ":pos_1", ":old_x_1"),
(position_set_y, ":pos_1", ":old_y_1"),
(position_set_z, ":pos_1", ":old_z_1"),
#还原 方法二 该方法可以保留几个角度
# (position_get_rotation_around_x,":return_x",":pos_1"),
# (val_mul,":return_x",-1),
# (position_rotate_x,":pos_1",":return_x"),
# (position_get_rotation_around_z,":return_z",":pos_1"),
# (val_mul,":return_z",-1),
# (position_rotate_z,":pos_1",":return_z"),
# (position_get_rotation_around_y,":return_y",":pos_1"),
# (val_mul,":return_y",-1),
# (position_rotate_y,":pos_1",":return_y"),
#看是否重合
(get_distance_between_positions,":dist",":pos_1",":pos_2"),
#水平方向 瞄准
(position_get_x, ":x_1", ":pos_1"),
(position_get_y, ":y_1", ":pos_1"),
(position_get_x, ":x_2", ":pos_2"),
(position_get_y, ":y_2", ":pos_2"),
(store_sub, ":off_x", ":x_2", ":x_1"),
(store_sub, ":off_y", ":y_2", ":y_1"),
(try_begin),
(gt, ":dist", 0),
#atan 把tan换算成角度 不能用tan,sin,cos,因为没有小数点
(store_atan2, ":angle_z", ":off_y", ":off_x"),
(try_end),
#将起始点放在x轴上而不是y轴上
(position_rotate_z,":pos_1",-90),
#水平瞄准
(position_rotate_z_floating,":pos_1", ":angle_z"),
#垂直方向 瞄准
#两点高度差 代码多元化
(get_sq_distance_between_position_heights,":height_sq",":pos_2",":pos_1"),
(get_sq_distance_between_positions,":distance_sq",":pos_2",":pos_1"),
(store_sqrt,":height", ":height_sq"),
#朝上朝下
(try_begin),
(position_get_z, ":z_1", ":pos_1"),
(position_get_z, ":z_2", ":pos_2"),
(gt,":z_1",":z_2"),
(val_mul,":height",-1),
(try_end),
#两点直线距离
(val_sub,":distance_sq",":height_sq"),
(store_sqrt,":dist", ":distance_sq"),
#atan 把tan换算成角度 不能用tan,sin,cos,因为没有小数点
(try_begin),
(gt, ":dist", 0),
(store_atan2, ":angle_x",":height", ":dist"),
(try_end),
#垂直瞄准
(position_rotate_x_floating,":pos_1", ":angle_x"),
#两点直线距离
(assign, reg0, ":dist"),
#test
# (assign, reg1, ":angle_z"),
# (assign, reg2, ":angle_x"),
# (display_message, "str_may_reg1_reg2"),
# (mission_cam_set_mode,1,0,0),
# (mission_cam_set_position, ":pos_1"),
# (mission_cam_animate_to_position, ":pos_2",3000, 0)
#test
]
),
——————————————以下旧版————————————————
经验交流:
1.3D空间下,坐标系xyz相减,会导致各种乱七八糟的bug,根本算不出正确的值,要么这个值是根据点自身的坐标系来算的?
2.get_distance_between_positions是两点投影距离(即俯视角度看的距离)。太坑了,明明是3D空间,两点成线,居然不给我两点直线距离?
3.get_angle_between_positions是两点投影角度(即俯视角度看的角度)。太坑了,明明是3D空间,两点成线,不给我线与世界的角度?
4.只有atan2能用,不能用atan,asin,acos,因为没有小数点,只能atan1,atan2这种,不能atan1.12这种
#coding:utf-8
#agland
#script_pos_aim_at_pos:
# Input: arg1 = pos_1, arg2 = pos_2,
# Output: reg0 = distance_between_pos
# Input:pos1对准pos2,等同"agent_set_look_target_position ,再读取头部骨骼pos",
# Output: 两点直线距离
("pos_aim_at_pos",
[
#(set_fixed_point_multiplier,1000),
#(assign, ":pos_1", pos31),
#(assign, ":pos_2", pos11),
(store_script_param, ":pos_1", 1),
(store_script_param, ":pos_2", 2),
#还原 方法一
(position_get_x, ":old_x_1", ":pos_1"),
(position_get_y, ":old_y_1", ":pos_1"),
(position_get_z, ":old_z_1", ":pos_1"),
(init_position,":pos_1"),
(position_set_x, ":pos_1", ":old_x_1"),
(position_set_y, ":pos_1", ":old_y_1"),
(position_set_z, ":pos_1", ":old_z_1"),
#还原 方法二 该方法可以保留几个角度
# (position_get_rotation_around_x,":return_x",":pos_1"),
# (val_mul,":return_x",-1),
# (position_rotate_x,":pos_1",":return_x"),
# (position_get_rotation_around_z,":return_z",":pos_1"),
# (val_mul,":return_z",-1),
# (position_rotate_z,":pos_1",":return_z"),
# (position_get_rotation_around_y,":return_y",":pos_1"),
# (val_mul,":return_y",-1),
# (position_rotate_y,":pos_1",":return_y"),
#两点距离 投影距离 不是空间距离
(get_distance_between_positions,":dist",":pos_1",":pos_2"),
#水平方向 瞄准
(position_get_x, ":x_1", ":pos_1"),
(position_get_y, ":y_1", ":pos_1"),
(position_get_x, ":x_2", ":pos_2"),
(position_get_y, ":y_2", ":pos_2"),
(store_sub, ":off_x", ":x_2", ":x_1"),
(store_sub, ":off_y", ":y_2", ":y_1"),
(try_begin),
(gt, ":dist", 0),
#atan 把tan换算成角度 不能用tan,sin,cos,因为没有小数点
(store_atan2, ":angle_z", ":off_y", ":off_x"),
#fixed_point
(val_div, ":angle_z", 100),
(try_end),
#将起始点放在x轴上而不是y轴上
(position_rotate_z,":pos_1",-90),
#水平瞄准
(position_rotate_z,":pos_1", ":angle_z"),
#垂直方向 瞄准
#两点高度差 代码多元化
(get_sq_distance_between_position_heights,":height",":pos_2",":pos_1"),
(store_sqrt,":height", ":height"),
#朝上朝下
(try_begin),
(position_get_z, ":z_1", ":pos_1"),
(position_get_z, ":z_2", ":pos_2"),
(gt,":z_1",":z_2"),
(val_mul,":height",-1),
(try_end),
#atan 把tan换算成角度 不能用tan,sin,cos,因为没有小数点
(try_begin),
(gt, ":dist", 0),
(store_atan2, ":angle_x",":height", ":dist"),
(try_end),
#fixed_point
(val_div, ":angle_x", 100),
#垂直瞄准
(position_rotate_x,":pos_1", ":angle_x"),
#两点直线距离
(val_mul,":dist",":dist"),
#(get_sq_distance_between_positions,
(store_add, ":pure_dist", ":height",":dist"),
(store_sqrt, ":pure_dist", ":pure_dist"),
(assign, reg0, ":pure_dist"),
#test
# (assign, reg1, ":angle_z"),
# (assign, reg2, ":angle_x"),
# (display_message, "str_may_reg1_reg2"),
# (mission_cam_set_mode,1,0,0),
# (mission_cam_set_position, ":pos_1"),
# (mission_cam_animate_to_position, ":pos_2",3000, 0)
#test
]
),
#agland
旧版内容
如题,可以理解为现代导弹精确制导功能。抛砖引玉,仅仅是思路,希望有人开发出更简单的方法。非新手教程。
以导弹为例,要实现3d空间里导弹头代码瞄准目标遇到了问题。原因是sce_pro场景物体的移动需要pos,而pos带有方向,导致直接anim或者set到这个位置,物体方向是目标当前方向。
船只等物体不会出现瞄准对不准的原因是,目标pos是复制自己当前pos,再进行变换。因此目标pos已经带有当前物体的方向。
箭矢的瞄准,是引擎自带的,没法研究。。
我想到的第一个解是把场景物体做成球形,即不受方向影响,只要命中目标即可。
第二个解是邪路:在场景物品上摆一个agent,用agent_set_look_target_position = 1744 ,对准需要瞄准的目标,再获取该agent头骨或者眼骨的pos,该pos带有瞄准好了的方向,再移动这个pos的y即可实现场景物品持续瞄准目标,即使目标在移动之类的。
第三个解就是不停地根据距离算tan,算角度,只要校准x和z两个方向即可,x方向可以用get_angle_between_positions = 705 (y方向是控制场景物品自身旋转,例如导弹旋转着打向目标)
快来个玉,弄个简单的方法解放我把
来自: Android客户端 |