骑马与砍杀中文站论坛

 找回密码
 注册(Register!)

QQ登录

只需一步,快速开始

搜索
购买CDKEY 小黑盒加速器
查看: 2032|回复: 7

[功能与代码] 简单的agent飞行实现,步兵骑兵皆可

[复制链接]

16

主题

108

回帖

197

积分

见习骑士

Rank: 3

UID
3304622
第纳尔
690
精华
0
互助
26
荣誉
3
贡献
0
魅力
158
注册时间
2021-12-28
鲜花(31) 鸡蛋(0)
发表于 2023-2-7 22:13:14 | 显示全部楼层 |阅读模式
本帖最后由 杰喵喵 于 2023-11-6 21:37 编辑

简单的agent飞行实现,步兵骑兵皆可,代码简单没有修改原本战团AI,十分傻瓜
一、理论指导:
1.【未写完】打败引擎硬核-关于骑砍各系统飞行等复杂位移功能实现与互相辅助 - MOD制作技术区 - 骑马与砍杀中文站论坛 - Powered by Discuz! (mountblade.com.cn)

2.自行百度或知乎"世界坐标系"与"自身坐标系的"相关知识。
3.改代码存在很多不足,请看下面大佬说明。

二、涉及核心函数:
1.(agent_set_no_dynamics, ":agent_no", 1),#设置是否飞行,0不飞行,1飞行
2.(position_has_line_of_sight_to_position, pos51, pos52)#两个点之间是否拥有直线视线,是否存在遮挡物
3.(agent_get_look_position, pos52, ":agent_no")#获取agent当前视角坐标pos
4. (agent_get_animation,":animation",":agent_no",0),#0读取agent的下身动作 1上半身
5.(agent_ai_get_num_cached_enemies, ":num", ":agent_no"), (agent_ai_get_cached_enemy, ":enemies", ":agent_no", ":index")#参考下面代码组合使用,读取agent最近的敌人
6.agent_ai_get_move_target、agent_ai_get_look_target#获得agent移向的目标或者观察的目标
7.(agent_set_position, ":agent_no", pos51),#强制移动agent
8. (agent_get_team,":agent_team",":agent_no"),(agent_get_division, ":agent_division", ":agent_no"), (team_get_movement_order, ":movement_order", ":agent_team", ":agent_division"),#组合获得agent的队伍移动命令

三、代码思路:
1.直接通过agent的当前动作来强制位移,不涉及修改原来的骑砍AI;
2.根据实际效果,因(agent_set_no_dynamics, ":agent_no", 1),会造成穿模异常,当飞行agent接近目标agent,如果目标agent是地面需要取消飞行状态,目标agent是飞行状态则限制agent前进。
3.通过读取agent_is_in_line_of_sight来判断场景阻挡,通过判断飞行agent的周围其他agent来判断是否有其他敌方agent阻挡。

四、代码
(一)、script部分
  1. #检查agent是是飞行单位
  2.    ("cf_agent_is_fly", [
  3.     (store_script_param, ":agent_no", 1),
  4.    
  5.     (gt,":agent_no",-1),
  6.     (agent_slot_ge,":agent_no",slot_agent_fly,1),
  7.     ]),
  8.    
  9.     #检查agent是不是飞行单位
  10.    ("cf_agent_is_no_fly", [
  11.     (store_script_param, ":agent_no", 1),
  12.    
  13.     (gt,":agent_no",-1),
  14.     (neg|agent_slot_ge,":agent_no",slot_agent_fly,1),
  15.     ]),
  16.    

  17.    
  18.    
  19. #判断agent前方是否有其他agent阻挡
  20. ("cf_agent_go_forward_be_hindered_from_other_agent",
  21. [
  22.   (store_script_param, ":agent_no", 1),
  23.   (store_script_param, ":is_run", 2),

  24.   (gt,":agent_no",-1),
  25.   (agent_is_alive,":agent_no"),
  26.   (agent_is_human,":agent_no"),
  27.   (agent_get_team,":team",":agent_no"),
  28.   (init_position,pos30),
  29.   (agent_get_position,pos30,":agent_no"),
  30.   (agent_get_horse,":horse",":agent_no"),
  31.   (assign,":radius_fixed_point",200),
  32.   (assign,":z_value_p",150),
  33.   (try_begin),
  34.     (gt,":horse",-1),
  35.     (assign,":z_value_p",300),
  36.   (try_end),
  37.   (store_mul,":z_value_n",":z_value_p",-1),

  38.   (assign,":be_hindered",0),
  39.   (try_for_agents,":other_agent",pos30,":radius_fixed_point"),
  40.       (eq,":be_hindered",0),
  41.       (neq,":other_agent",":agent_no"),
  42.       (agent_is_alive,":other_agent"),
  43.       (agent_is_human,":other_agent"),
  44.       (agent_get_team,":other_team",":other_agent"),
  45.       (teams_are_enemies,":other_team",":team"),
  46.      
  47.       (agent_get_horse,":other_agent_horse",":other_agent"),
  48.       (assign,":x_value_p",30),

  49.       (assign,":distance_value",50),
  50.       (try_begin),
  51.          (gt,":other_agent_horse",-1),
  52.          (assign,":x_value_p",100),
  53.          (assign,":distance_value",100),
  54.       (try_end),
  55.       (store_mul,":x_value_n",":x_value_p",-1),
  56.       #骑马加上马头和人的距离
  57.       (try_begin),
  58.          (gt,":horse",-1),
  59.          (val_add,":distance_value",100),
  60.       (try_end),
  61.       
  62.       (init_position,pos31),
  63.       (agent_get_position,pos31,":other_agent"),
  64.       (get_distance_between_positions,":distance",pos31,pos30),
  65.       (init_position,pos32),
  66.       (position_transform_position_to_local,pos32,pos30,pos31),
  67.       (position_get_x,":x_0",pos32),
  68.       (position_get_y,":y_0",pos32),
  69.       (position_get_z,":z_0",pos32),
  70.       (gt,":y_0",0),
  71.       (le,":distance",":distance_value"),
  72.       (is_between,":z_0",":z_value_n",":z_value_p"),
  73.       (is_between,":x_0",":x_value_n",":x_value_p"),
  74.       (assign,":be_hindered",1),
  75.   (try_end),
  76.   
  77.   (eq,":be_hindered",":is_run"),

  78.   ]
  79.   ),  
  80.   
  81.   #判断agent后退是否有其他agent阻挡
  82. ("cf_agent_go_back_be_hindered_from_other_agent",
  83. [
  84.   (store_script_param, ":agent_no", 1),
  85.   (store_script_param, ":is_run", 2),

  86.   (gt,":agent_no",-1),
  87.   (agent_is_alive,":agent_no"),
  88.   (agent_is_human,":agent_no"),
  89.   (agent_get_team,":team",":agent_no"),
  90.   (init_position,pos30),
  91.   (agent_get_position,pos30,":agent_no"),
  92.   (agent_get_horse,":horse",":agent_no"),
  93.   (assign,":radius_fixed_point",200),
  94.   (assign,":z_value_p",150),
  95.   (try_begin),
  96.     (gt,":horse",-1),
  97.     (assign,":z_value_p",300),
  98.   (try_end),
  99.   (store_mul,":z_value_n",":z_value_p",-1),

  100.   (assign,":be_hindered",0),
  101.   (try_for_agents,":other_agent",pos30,":radius_fixed_point"),
  102.       (eq,":be_hindered",0),
  103.       (neq,":other_agent",":agent_no"),
  104.       (agent_is_alive,":other_agent"),
  105.       (agent_is_human,":other_agent"),
  106.       (agent_get_team,":other_team",":other_agent"),
  107.       (teams_are_enemies,":other_team",":team"),
  108.       
  109.       (agent_get_horse,":other_agent_horse",":other_agent"),
  110.       (assign,":x_value_p",30),

  111.       (assign,":distance_value",50),
  112.       (try_begin),
  113.          (gt,":other_agent_horse",-1),
  114.          (assign,":x_value_p",100),
  115.          (assign,":distance_value",100),
  116.       (try_end),
  117.       (store_mul,":x_value_n",":x_value_p",-1),
  118.       
  119.       (try_begin),
  120.          (gt,":horse",-1),
  121.          (val_add,":distance_value",100),
  122.       (try_end),
  123.       
  124.       (init_position,pos31),
  125.       (agent_get_position,pos31,":other_agent"),
  126.       (get_distance_between_positions,":distance",pos31,pos30),
  127.       (init_position,pos32),
  128.       (position_transform_position_to_local,pos32,pos30,pos31),
  129.       (position_get_x,":x_0",pos32),
  130.       (position_get_y,":y_0",pos32),
  131.       (position_get_z,":z_0",pos32),
  132.       (lt,":y_0",0),
  133.       (le,":distance",":distance_value"),
  134.       (is_between,":z_0",":z_value_n",":z_value_p"),
  135.       (is_between,":x_0",":x_value_n",":x_value_p"),
  136.       (assign,":be_hindered",1),
  137.   (try_end),
  138.   
  139.   (eq,":be_hindered",":is_run"),

  140.   ]
  141.   ),

  142. #判断agent右边是否有其他agent阻挡
  143. ("cf_agent_go_right_be_hindered_from_other_agent",
  144. [

  145.   (store_script_param, ":agent_no", 1),
  146.   (store_script_param, ":is_run", 2),

  147.   (gt,":agent_no",-1),
  148.   (agent_is_alive,":agent_no"),
  149.   (agent_is_human,":agent_no"),
  150.   (agent_get_team,":team",":agent_no"),
  151.   (init_position,pos30),
  152.   (agent_get_position,pos30,":agent_no"),
  153.   (agent_get_horse,":horse",":agent_no"),
  154.   (assign,":radius_fixed_point",200),
  155.   (assign,":z_value_p",150),
  156.   (try_begin),
  157.     (gt,":horse",-1),
  158.     (assign,":z_value_p",300),
  159.   (try_end),
  160.   (store_mul,":z_value_n",":z_value_p",-1),

  161.   (assign,":be_hindered",0),
  162.   (try_for_agents,":other_agent",pos30,":radius_fixed_point"),
  163.       (eq,":be_hindered",0),
  164.       (neq,":other_agent",":agent_no"),
  165.       (agent_is_alive,":other_agent"),
  166.       (agent_is_human,":other_agent"),
  167.       (agent_get_team,":other_team",":other_agent"),
  168.       (teams_are_enemies,":other_team",":team"),
  169.       
  170.       (agent_get_horse,":other_agent_horse",":other_agent"),
  171.       (assign,":y_value_p",30),

  172.       (assign,":distance_value",50),
  173.       (try_begin),
  174.          (gt,":other_agent_horse",-1),
  175.          (assign,":y_value_p",100),
  176.          (assign,":distance_value",100),
  177.       (try_end),
  178.       (store_mul,":y_value_n",":y_value_p",-1),
  179.       #骑马加上马头和人的距离
  180.       (try_begin),
  181.          (gt,":horse",-1),
  182.          (val_add,":distance_value",100),
  183.       (try_end),
  184.       
  185.       (init_position,pos31),
  186.       (agent_get_position,pos31,":other_agent"),
  187.       (get_distance_between_positions,":distance",pos31,pos30),
  188.       (init_position,pos32),
  189.       (position_transform_position_to_local,pos32,pos30,pos31),
  190.       (position_get_x,":x_0",pos32),
  191.       (position_get_y,":y_0",pos32),
  192.       (position_get_z,":z_0",pos32),
  193.       (gt,":x_0",0),
  194.       (le,":distance",":distance_value"),
  195.       (is_between,":z_0",":z_value_n",":z_value_p"),
  196.       (is_between,":y_0",":y_value_n",":y_value_p"),
  197.       (assign,":be_hindered",1),
  198.   (try_end),
  199.   
  200.   (eq,":be_hindered",":is_run"),

  201.   ]
  202.   ),   
  203. #判断agent左边是否有其他agent阻挡
  204. ("cf_agent_go_left_be_hindered_from_other_agent",
  205. [
  206.   (store_script_param, ":agent_no", 1),
  207.   (store_script_param, ":is_run", 2),

  208.   (gt,":agent_no",-1),
  209.   (agent_is_alive,":agent_no"),
  210.   (agent_is_human,":agent_no"),
  211.   (agent_get_team,":team",":agent_no"),
  212.   (init_position,pos30),
  213.   (agent_get_position,pos30,":agent_no"),
  214.   (agent_get_horse,":horse",":agent_no"),
  215.   (assign,":radius_fixed_point",200),
  216.   (assign,":z_value_p",150),
  217.   (try_begin),
  218.     (gt,":horse",-1),
  219.     (assign,":z_value_p",300),
  220.   (try_end),
  221.   (store_mul,":z_value_n",":z_value_p",-1),

  222.   (assign,":be_hindered",0),
  223.   (try_for_agents,":other_agent",pos30,":radius_fixed_point"),
  224.       (eq,":be_hindered",0),
  225.       (neq,":other_agent",":agent_no"),
  226.       (agent_is_alive,":other_agent"),
  227.       (agent_is_human,":other_agent"),
  228.       (agent_get_team,":other_team",":other_agent"),
  229.       (teams_are_enemies,":other_team",":team"),
  230.       
  231.       (agent_get_horse,":other_agent_horse",":other_agent"),
  232.       (assign,":y_value_p",30),

  233.       (assign,":distance_value",50),
  234.       (try_begin),
  235.          (gt,":other_agent_horse",-1),
  236.          (assign,":y_value_p",100),
  237.          (assign,":distance_value",100),
  238.       (try_end),
  239.       (store_mul,":y_value_n",":y_value_p",-1),
  240.       #骑马加上马头和人的距离
  241.       (try_begin),
  242.          (gt,":horse",-1),
  243.          (val_add,":distance_value",100),
  244.       (try_end),
  245.       
  246.       (init_position,pos31),
  247.       (agent_get_position,pos31,":other_agent"),
  248.       (get_distance_between_positions,":distance",pos31,pos30),
  249.       (init_position,pos32),
  250.       (position_transform_position_to_local,pos32,pos30,pos31),
  251.       (position_get_x,":x_0",pos32),
  252.       (position_get_y,":y_0",pos32),
  253.       (position_get_z,":z_0",pos32),
  254.       (lt,":x_0",0),
  255.       (le,":distance",":distance_value"),
  256.       (is_between,":z_0",":z_value_n",":z_value_p"),
  257.       (is_between,":y_0",":y_value_n",":y_value_p"),
  258.       (assign,":be_hindered",1),
  259.   (try_end),
  260.   
  261.   (eq,":be_hindered",":is_run"),

  262.   ]
  263.   ),
复制代码

(二)module_mission_templates部分玩家使用Y进入飞行,接触地面自动接触
  1. init_the_key_y = (
  2.       
  3.   0,0,2,[
  4.   (key_clicked,key_y),
  5.   (get_player_agent_no, ":player_agent"),
  6.   (neg|agent_slot_ge,":player_agent",slot_agent_fly,1),#非飞行
  7.   ],
  8.        [
  9.         (set_fixed_point_multiplier, 100),
  10.         
  11.         (get_player_agent_no, ":player_agent"),
  12.         (agent_get_horse,":horse", ":player_agent"),
  13.         (agent_get_position, pos10, ":player_agent"),   
  14.       
  15.         (try_begin),
  16.             (gt,":horse",-1),
  17.             (assign,":var_0",":horse"),
  18.         (else_try),
  19.             (assign,":var_0",":player_agent"),
  20.         (try_end),        
  21.         (position_move_z,pos10,10),
  22.         (agent_set_slot,":player_agent",slot_agent_fly,1),#飞行
  23.         (agent_set_no_dynamics, ":var_0", 1),
  24.         (agent_set_position,":var_0",pos10),
  25.         (display_message,"@player fly is on"),

  26.        ]
  27. )  
  28. common_player_fly = (0.0,0,0,
  29.     [
  30.       (get_player_agent_no, ":player_agent"),
  31.       (agent_slot_ge, ":player_agent", slot_agent_fly, 1),
  32.     ],
  33.     [
  34.     (set_fixed_point_multiplier, 100),
  35.    
  36.     (get_player_agent_no, ":player_agent"),
  37.     (assign,":y_move",0),
  38.     (assign,":x_move",0),
  39.     (assign,":z_move",0),
  40.     (init_position,pos5),
  41.     #骑马的时候马与人共用速度
  42.     (agent_get_horse, ":horse", ":player_agent"),
  43.     (assign,":var_0",":player_agent"),
  44.     (try_begin),
  45.         (gt,":horse",-1),
  46.         (assign,":var_0",":horse"),
  47.     (try_end),   
  48.     (agent_get_speed,pos5,":var_0"),
  49.     (position_get_y,":y_speed",pos5),
  50.     (position_get_x,":x_speed",pos5),
  51.    
  52.     (try_begin),
  53.         (gt,":horse",-1),
  54.         (store_div,":y_move",":y_speed",fly_y_horse_move_div),
  55.         (store_div,":x_move",":x_speed",fly_x_horse_move_div),
  56.     (else_try),
  57.         (store_div,":y_move",":y_speed",fly_y_move_div),
  58.         (store_div,":x_move",":x_speed",fly_x_move_div),
  59.     (try_end),
  60.    
  61.     (init_position,pos6),
  62.     (agent_get_look_position, pos6, ":player_agent"),
  63.     (position_get_rotation_around_x, ":rotation_x_player", pos6),
  64.     (try_begin),
  65.         (key_is_down, key_v),
  66.         (assign,":z_move",z_move_up),
  67.     (else_try),
  68.         (key_is_down, key_b),
  69.         (assign,":z_move",z_move_up),
  70.         (val_mul,":z_move",-1),
  71.     (else_try),
  72.         (neq,":y_move",0),
  73.         (is_between,":rotation_x_player",1,91),#鼠标移动玩家视角向上 对着天空
  74.         (store_div,":value", ":rotation_x_player",9),
  75.         (val_add,":value",1),
  76.         (store_div,":z_move",":y_move",fly_z_move_div),
  77.         (val_mul,":z_move",":value"),
  78.    (else_try),
  79.         (neq,":y_move",0),
  80.         (is_between,":rotation_x_player",270,360),#鼠标移动玩家视角向下 对着地面
  81.         (store_sub,":value", 360,":rotation_x_player"),
  82.         (store_div,":value", ":value",9),
  83.         (val_add,":value",1),
  84.         (val_mul,":value",-1),
  85.         (store_div,":z_move",":y_move",fly_z_move_div),
  86.         (val_mul,":z_move",":value"),
  87.     (try_end),
  88.    
  89.     #其他agnt阻挡
  90.     (assign,":be_block",0),
  91.     (try_begin),
  92.         (gt,":y_move",0),
  93.         (call_script,"script_cf_agent_go_forward_be_hindered_from_other_agent",":player_agent",1),
  94.         (assign,":be_block",1),
  95.     (else_try),
  96.         (lt,":y_move",0),
  97.         (call_script,"script_cf_agent_go_back_be_hindered_from_other_agent",":player_agent",1),
  98.         (assign,":be_block",1),
  99.     (else_try),
  100.         (gt,":x_move",0),
  101.         (call_script,"script_cf_agent_go_right_be_hindered_from_other_agent",":player_agent",1),
  102.         (assign,":be_block",1),
  103.     (else_try),
  104.         (lt,":x_move",0),
  105.         (call_script,"script_cf_agent_go_left_be_hindered_from_other_agent",":player_agent",1),
  106.         (assign,":be_block",1),
  107.     (try_end),
  108.     (eq,":be_block",0),
  109.     ##
  110.    
  111.     (init_position,pos5),
  112.     (agent_get_position,pos5,":var_0"),
  113.     #限制飞行高度
  114.     (position_get_z,":pos_z",pos5),
  115.     (try_begin),
  116.         (ge,":pos_z",fly_z_height_limit),
  117.         (gt,":z_move",0),
  118.         (assign,":z_move",0),
  119.     (try_end),
  120.     ##
  121.    
  122.     #使用武器时候Z轴不移动
  123.     (try_begin),
  124.         (agent_get_attack_action, ":attack_action", ":player_agent"),
  125.         (neq, ":attack_action",0),
  126.         (assign,":z_move",0),
  127.     (try_end),
  128.     ##
  129.    
  130.     (neq|this_or_next,":y_move",0),
  131.     (neq|this_or_next,":x_move",0),
  132.     (neq,":z_move",0),
  133.     (position_move_y,pos5,":y_move"),
  134.     (position_move_x,pos5,":x_move"),
  135.     (position_move_z,pos5,":z_move"),

  136.     (try_begin),
  137.        (game_key_is_down,gk_move_right),
  138.        (position_rotate_z, pos5,-1),
  139.     (else_try),
  140.        (game_key_is_down,gk_move_left),
  141.        (position_rotate_z, pos5, 1),  
  142.     (try_end),
  143.    
  144.     #获得地图最大限制
  145.     (get_scene_boundaries, pos26, pos27),#左下角和右上角的点,方向朝上
  146.     (position_get_x, ":lower_left_corner_x", pos26),
  147.     (position_get_y, ":lower_left_corner_y", pos26),
  148.     (position_get_x, ":upper_right_corner_x", pos27),
  149.     (position_get_y, ":upper_right_corner_y", pos27),         
  150.     (val_add,":lower_left_corner_x",50),
  151.     (val_add,":lower_left_corner_y",50),
  152.     (val_sub,":upper_right_corner_x",50),
  153.     (val_sub,":upper_right_corner_y",50),
  154.    
  155.         
  156.     #设置障碍判断pos6
  157.     (init_position,pos6),
  158.     (copy_position ,pos6,pos5),
  159.     (try_begin),
  160.         (gt,":horse",-1),
  161.         (position_move_z, pos6, 300),
  162.         (position_move_y, pos6, 200),
  163.     (else_try),
  164.         (position_move_z, pos6, 150),
  165.         (position_move_y, pos6, 100),
  166.     (try_end),
  167.     #读取xy数据与对地面距离
  168.     (position_get_x,":pos_x",pos5),
  169.     (position_get_y,":pos_y",pos5),
  170.     (position_get_distance_to_ground_level,":ground_level",pos5),
  171.     (try_begin),#接触地面退出飞行
  172.         (le,":ground_level",0),      
  173.         (agent_set_slot,":player_agent",slot_agent_fly,0),#退出飞行
  174.         (agent_set_no_dynamics, ":var_0", 0),
  175.         (display_message,"@player fly is off"),
  176.     (else_try),
  177.         #防止飞出地图
  178.         (gt,":pos_x",":lower_left_corner_x"),
  179.         (lt,":pos_x",":upper_right_corner_x"),
  180.         (gt,":pos_y",":lower_left_corner_y"),
  181.         (lt,":pos_y",":upper_right_corner_y"),
  182.         #判断前方障碍点
  183.         (agent_is_in_line_of_sight,":player_agent",pos6),
  184.         (agent_set_position,":var_0",pos5),
  185.     (try_end),
  186.    
  187. ])



  188. common_agent_flying_lead_charge =  (0, 0, 0, [],
  189. [
  190.     #设置pos单位量尺为cm  
  191.     (set_fixed_point_multiplier, 100),
  192.    
  193.     (try_for_agents, ":agent_no"),
  194.        (agent_is_non_player,":agent_no"),
  195.        (agent_is_human, ":agent_no"),  ##是人
  196.        (agent_is_alive, ":agent_no"),  ##存活的
  197.        (neg|agent_is_wounded,":agent_no"),##非击晕的
  198.        (agent_get_troop_id,":troop_id",":agent_no"),
  199.        (agent_get_horse,":horse", ":agent_no"),
  200.        (agent_get_team,":agent_team",":agent_no"),
  201.        (agent_get_division, ":agent_division", ":agent_no"),
  202.        (team_get_movement_order, ":movement_order", ":agent_team", ":agent_division"),
  203.         
  204.        (assign,":agent_can_fly",0),
  205.        (try_begin),
  206.           (gt,":horse",-1),
  207.           (agent_get_item_id,":item_id",":horse"),
  208.           (eq,":item_id","itm_courser_fly"),
  209.           (assign,":agent_can_fly",1),
  210.        (else_try),
  211.           (this_or_next|eq,":troop_id","trp_nord_champion_fly"),#需要设定的单位
  212.           (eq,":troop_id","trp_swadian_sharpshooter_fly"),
  213.           (assign,":agent_can_fly",1),
  214.        (try_end),
  215.       
  216.        (eq,":agent_can_fly",1),
  217.       
  218.        ##强制设定目标
  219.        (agent_ai_get_move_target,":target_agent",":agent_no"),
  220.        (try_begin),
  221.            (lt,":target_agent",0),
  222.            (agent_ai_get_look_target,":target_agent",":agent_no"),
  223.            (try_begin),
  224.               (gt,":target_agent",-1),
  225.               (agent_is_alive,":target_agent"),
  226.            (else_try),
  227.               (agent_clear_scripted_mode, ":agent_no"),
  228.               (agent_ai_get_num_cached_enemies, ":num", ":agent_no"),
  229.               (try_for_range,":index",0,":num"),#get target_agent
  230.                  (store_random_in_range,":index",0,":num"),
  231.                  (agent_ai_get_cached_enemy, reg40,":agent_no",":index"),
  232.                  (agent_is_alive, reg40),
  233.                  (assign,":target_agent",reg40),
  234.                  (agent_set_look_target_agent,":agent_no",":target_agent"),
  235.                  (assign,":num",-1),#break
  236.               (try_end),
  237.            (try_end),
  238.         (try_end),
  239.         ##

  240.         #设定var_0
  241.         (try_begin),
  242.             (gt,":horse",-1),
  243.             (assign,":var_0",":horse"),
  244.         (else_try),
  245.             (assign,":var_0",":agent_no"),
  246.         (try_end),
  247.         ##
  248.         
  249.         (try_begin),#开始飞行
  250.             (neg|agent_slot_ge,":agent_no",slot_agent_fly,1),#非飞行
  251.             (eq, ":movement_order", mordr_charge),
  252.             (gt,":target_agent",-1),
  253.             #获得目标target_agent与agent_no的距离
  254.             (init_position,pos20),
  255.             (agent_get_position, pos20, ":agent_no"),
  256.             (init_position,pos21),
  257.             (agent_get_position, pos21, ":target_agent"),
  258.             (get_distance_between_positions,":distance_target",pos20,pos21),
  259.             
  260.             (try_begin),
  261.               (gt,":horse",-1),
  262.               (assign,":var_0",":horse"),
  263.               (position_move_z,pos20,z_move_up),
  264.               (assign,":distance_target_judgment",5000),
  265.             (else_try),
  266.               (assign,":var_0",":agent_no"),
  267.               (position_move_z,pos20,z_move_up),
  268.               (assign,":distance_target_judgment",2500),
  269.             (try_end),
  270.             #距离满足或target_agent是飞行状态则进入飞行状态
  271.             (assign,":agent_start_fly",0),
  272.             (try_begin),
  273.                 (agent_slot_ge,":target_agent",slot_agent_fly,1),#飞行
  274.                 (assign,":agent_start_fly",1),
  275.             (else_try),
  276.                 (gt,":distance_target",":distance_target_judgment"),
  277.                 (assign,":agent_start_fly",1),
  278.             (try_end),
  279.             ##
  280.             (eq,":agent_start_fly",1),
  281.             (agent_set_slot,":agent_no",slot_agent_fly,1),
  282.             (agent_set_no_dynamics, ":var_0", 1),
  283.             (agent_set_position, ":var_0", pos20),
  284.         (else_try),#起飞飞行
  285.           (agent_slot_eq,":agent_no",slot_agent_fly,1),
  286.           (init_position,pos20),
  287.           (agent_get_position, pos20, ":agent_no"),
  288.           (position_get_distance_to_ground_level,":ground_level",pos20),
  289.           (try_begin),
  290.              (le, ":ground_level",1000),
  291.              (position_move_z,pos20,z_move_up),   
  292.              (agent_set_position, ":var_0", pos20),
  293.           (else_try),
  294.              (agent_set_slot,":agent_no",slot_agent_fly,2),
  295.           (try_end),
  296.         (else_try),#正常飞行
  297.           (agent_slot_eq,":agent_no",slot_agent_fly,2),
  298.           (assign,":y_move",0),
  299.           (assign,":x_move",0),
  300.           (assign,":z_move",0),
  301.          
  302.           (init_position,pos20),
  303.           (agent_get_speed,pos20,":var_0"),
  304.           (position_get_y,":y_speed",pos20),
  305.           (position_get_x,":x_speed",pos20),
  306.           #速度
  307.           (try_begin),
  308.             (gt,":horse",-1),
  309.             (val_div,":y_speed",fly_y_horse_move_div),
  310.             (assign,":y_move",":y_speed"),
  311.             (val_div,":x_speed",fly_x_horse_move_div),
  312.             (assign,":x_move",":x_speed"),
  313.           (else_try),
  314.             (val_div,":y_speed",fly_y_move_div),
  315.             (assign,":y_move",":y_speed"),
  316.             (val_div,":x_speed",fly_x_move_div),
  317.             (assign,":x_move",":x_speed"),
  318.           (try_end),

  319.           (init_position,pos20),
  320.           (agent_get_look_position, pos20, ":agent_no"),
  321.           (position_get_rotation_around_x, ":rotation_x", pos20),

  322.           (try_begin),
  323.                 (neq,":y_move",0),
  324.                 (is_between,":rotation_x",1,91),#鼠标移动玩家视角向上 对着天空
  325.                 (store_div,":value", ":rotation_x",9),
  326.                 (val_add,":value",1),
  327.                 (store_div,":z_move",":y_move",fly_z_move_div),
  328.                 (val_mul,":z_move",":value"),
  329.           (else_try),
  330.                 (neq,":y_move",0),
  331.                 (is_between,":rotation_x",270,360),#鼠标移动玩家视角向下 对着地面
  332.                 (store_sub,":value", 360,":rotation_x"),
  333.                 (store_div,":value", ":value",9),
  334.                 (val_add,":value",1),
  335.                 (val_mul,":value",-1),
  336.                 (store_div,":z_move",":y_move",fly_z_move_div),
  337.                 (val_mul,":z_move",":value"),
  338.           (try_end),   

  339.           #其他agnt阻挡
  340.           (assign,":be_block",0),
  341.           (try_begin),
  342.               (gt,":y_move",0),
  343.               (call_script,"script_cf_agent_go_forward_be_hindered_from_other_agent",":agent_no",1),
  344.               (assign,":be_block",1),
  345.           (else_try),
  346.               (lt,":y_move",0),
  347.               (call_script,"script_cf_agent_go_back_be_hindered_from_other_agent",":agent_no",1),
  348.               (assign,":be_block",1),
  349.           (else_try),
  350.               (gt,":x_move",0),
  351.               (call_script,"script_cf_agent_go_right_be_hindered_from_other_agent",":agent_no",1),
  352.               (assign,":be_block",1),
  353.           (else_try),
  354.               (lt,":x_move",0),
  355.               (call_script,"script_cf_agent_go_left_be_hindered_from_other_agent",":agent_no",1),
  356.               (assign,":be_block",1),
  357.          (try_end),
  358.          (eq,":be_block",0),
  359.          ##

  360.          ##AI条件限制防止一直向下
  361.          (try_begin),
  362.             (gt,":y_move",0),
  363.             (lt,":z_move",0),
  364.             (gt,":target_agent",0),
  365.             (neg|agent_slot_ge,":target_agent",slot_agent_fly,1),#非飞行
  366.             (eq, ":movement_order", mordr_charge),
  367.             #获得目标target_agent与agent_no的距离
  368.             (init_position,pos21),
  369.             (agent_get_position, pos21, ":target_agent"),
  370.             (get_distance_between_positions,":distance_target",pos20,pos21),
  371.             #对应非飞行单位根据距离下降,进入一定范围后才下降
  372.             (try_begin),
  373.                 (gt,":horse",0),
  374.                 (gt,":distance_target",1500),
  375.                 (assign,":z_move",0),
  376.             (else_try),
  377.                 (gt,":distance_target",750),
  378.                 (assign,":z_move",0),
  379.             (try_end),
  380.           (try_end),
  381.           ##         

  382.           (neq|this_or_next,":y_move",0),
  383.           (neq|this_or_next,":x_move",0),
  384.           (neq,":z_move",0),
  385.         
  386.           (init_position,pos20),
  387.           (agent_get_position,pos20,":var_0"),
  388.           #限制飞行高度
  389.           (position_get_z,":pos_z",pos20),
  390.           (try_begin),
  391.             (ge,":pos_z",fly_z_height_limit),
  392.             (gt,":z_move",0),
  393.             (assign,":z_move",0),
  394.           (try_end),
  395.           ##
  396.         
  397.           #使用武器时候Z轴不移动
  398.           (try_begin),
  399.             (agent_get_attack_action, ":attack_action", ":agent_no"),
  400.             (neq, ":attack_action",0),
  401.             (assign,":z_move",0),
  402.           (try_end),
  403.           ##
  404.          
  405.           (init_position,pos19),
  406.           (copy_position ,pos19,pos20),
  407.           (position_move_y,pos20,":y_move"),
  408.           (position_move_x,pos20,":x_move"),
  409.           (position_move_z,pos20,":z_move"),  
  410.         
  411.           ##骑手马的转动 读取马的动作来作为依据
  412.           (try_begin),
  413.             (gt,":horse",-1),
  414.             (agent_get_animation,":animation",":horse",1),#必须是1读取上半身!!!!!!!!!
  415.             (try_begin),
  416.                 (eq|this_or_next,":animation","anim_horse_turn_right"),
  417.                 (eq,":animation","anim_horse_turn_right_head"),
  418.                 (position_rotate_z, pos20,-1),
  419.             (else_try),
  420.                 (eq|this_or_next,":animation","anim_horse_turn_left"),
  421.                 (eq,":animation","anim_horse_turn_left_head"),
  422.                 (position_rotate_z, pos20, 1),   
  423.             (try_end),
  424.           (try_end),
  425.           ##

  426.          #获得地图最大限制
  427.          (init_position,pos26),
  428.          (init_position,pos27),
  429.          (get_scene_boundaries, pos26, pos27),#左下角和右上角的点,方向朝上
  430.          (position_get_x, ":lower_left_corner_x", pos26),
  431.          (position_get_y, ":lower_left_corner_y", pos26),
  432.          (position_get_x, ":upper_right_corner_x", pos27),
  433.          (position_get_y, ":upper_right_corner_y", pos27),         
  434.          (val_add,":lower_left_corner_x",50),
  435.          (val_add,":lower_left_corner_y",50),
  436.          (val_sub,":upper_right_corner_x",50),
  437.          (val_sub,":upper_right_corner_y",50),
  438.    
  439.          #设置障碍判断pos21
  440.          (init_position,pos21),
  441.          (copy_position ,pos21,pos20),
  442.          (try_begin),
  443.             (gt,":horse",-1),
  444.             (position_move_z, pos21, 300),
  445.             (position_move_y, pos21, 200),
  446.          (else_try),
  447.             (position_move_z, pos21, 150),
  448.             (position_move_y, pos21, 100),
  449.          (try_end),
  450.         
  451.          #读取xy数据与对地面距离
  452.          (position_get_x,":pos_x",pos20),
  453.          (position_get_y,":pos_y",pos20),
  454.          (position_get_distance_to_ground_level,":ground_level",pos20),
  455.          (try_begin),#接触地面退出飞行
  456.             (le,":ground_level",0),      
  457.             (agent_set_slot,":agent_no",slot_agent_fly,0),#退出飞行
  458.             (agent_set_no_dynamics, ":var_0", 0),
  459.          (else_try),#判断前方障碍点
  460.             (neg|agent_is_in_line_of_sight,":agent_no",pos21),
  461.             (position_move_z,pos19,10),
  462.             (agent_set_position,":var_0",pos19),   
  463.          (else_try),
  464.             #防止飞出地图
  465.             (gt,":pos_x",":lower_left_corner_x"),
  466.             (lt,":pos_x",":upper_right_corner_x"),
  467.             (gt,":pos_y",":lower_left_corner_y"),
  468.             (lt,":pos_y",":upper_right_corner_y"),
  469.             (agent_set_position,":var_0",pos20),        
  470.          (try_end),
  471.       (try_end),   
  472.     (try_end),
  473. ]
  474. )
复制代码

(三)常量部分
  1. z_move_up = 10
  2. fly_y_move_div = 10
  3. fly_x_move_div = 10
  4. fly_z_move_div = 4
  5. fly_y_horse_move_div = 40
  6. fly_x_horse_move_div = 30
  7. fly_z_horse_move_div = 4
  8. fly_z_height_limit = 5000
  9. #agent是否处于飞行状态
  10. slot_agent_fly  = 100
复制代码

(四)、效果
视频展示:
骑马与砍杀战团飞砍,是兄弟就来飞砍_哔哩哔哩bilibili_骑马与砍杀_演示
骑马与砍杀战团飞砍,是兄弟就来飞砍_哔哩哔哩bilibili_骑马与砍杀_演示




图3.jpg

空战

空战

野战

野战

评分

参与人数 1第纳尔 +20 互助 +1 魅力 +20 收起 理由
Aomine Daiki + 20 + 1 + 20 文章不错,继续努力!

查看全部评分

212

主题

1033

回帖

1049

积分

子爵[版主]

Rank: 7Rank: 7Rank: 7

UID
2893127
第纳尔
14847
精华
0
互助
93
荣誉
21
贡献
325
魅力
1382
注册时间
2017-11-5
鲜花(431) 鸡蛋(0)
发表于 2023-2-8 12:31:55 | 显示全部楼层
本帖最后由 vegetto 于 2023-2-8 14:48 编辑

1.整体位移的立体范围除了要考虑竖向限制ground level z的地面高度以外,还要考虑横向平面尺度boundary,也就是整个场景的实际范围。很多时候场景被空气墙挡住了,所以很多人不注意场景之外,即使有地形的地方是没有地形碰撞的。超出boundary的场景范围ground level不存在或者说是无穷大,这时候人向场景地形范围外飞且需要判断降落的时候,如果采用set z to ground level的方式会很快瞬到与太阳光照贴图肩并肩、天空球之外的外太空上并且落在一个隐形面板上。这时候就别想自由落体下来了。

2.ai和玩家在启闭no dynamic状态时需要区别处理会有一些不一样的bug。因为这个操作很冷门,所以官方并没有把它处理的很好。无论是开启和关闭,引擎内部在是否高空需要自由落体和降落地面的判断还是会一直运行,然后高空突然关闭no dynamic时概率性一瞬间冲突使系统误认为已经落地,产生非dynamic影响的滞空bug。这时候无论你再怎么dynamic启闭都回归不了自由落体,特别的有时靠近地面将落地的时候会永久的卡死在地面一点,相当于零高度滞空,这时候不附加判断的话只能等下次如果不影响重启飞行的情况下重启位移,经典案例就是贴吧有的人把攻城车的踏板给抽掉那在踏板上的人就可能不会掉下来。所以要优化位移模式(比如尽量避免用一个非瞬间性的条件持续设置dynamic为某值,这种在取值需要瞬间变化的时候极容易系统冲突产生如上bug等等处理不细说。)和异常位移情况自检判断。玩家其实也会出现这种情况但比较少,因为这个bug也和动作是否允许位移的特性冲突有关,玩家比AI能做的动作和行为更多,所以说不太容易受这种bug影响,可以开关闭自如,只考虑位移。总体上人数越多、高度越高、关闭前的位移幅度较小或者偏上升趋势时、以及关闭前的动作切换这些情况共同决定了这种滞空bug容易出现的程度。

3.in sight这种适合地平面运动关系碰撞判断手段,不太适合立体空间移动模式,因为像高楼林立的场景,六向位移会和障碍物的不规则表面比如有凹凸形状的孔洞和凹槽,一旦贴合没有高强度的碰撞检测就很容易穿膜,lookpos只能防御来自于视线吻合的位移方向的障碍物判断,如果产生了其他方向与视线或者碰撞检测方向角度相差较大的位移,单个in sight或是其他单方向的检测手段并不足以来支持限制改变位移的碰撞需求。所以针对不同的对象碰撞检测往往会使用很多复合,且光光处理好飞行的人与各种prop类型的障碍物完美避免穿入(穿模部分可以不强求,但不能穿入且回不来)就需要消耗大量的性能。


不过,一个最偷懒的方式就是就像汽车一样设置较大的自动刹车距离,避免出现需要贴合障碍物摩蹭的情况。位移碰撞事件不要拆分多个触发器和太高或太低触发间隔,就像汽车刹车一样,有制动距离,因为运动的主动控制延迟因素影响很大,比如你以50的速度时检测碰撞停止或许从视觉暂留看立即停住了,但是以500的速度本以为按照触发写的本意可以在碰撞前紧贴着停下,但是实际上检测到碰撞的瞬间又持续触发多前进了一两百距离,因为本身各个碰撞检测手段有一点极短的反馈时间,微观上同一个触发时刻检测到的碰撞略滞后于此时的位移坐标。而人体在空中面对建筑物就像蚂蚁一样,可以忽略自身碰撞轮廓的各向尺寸,灵活的点对固定的物的碰撞自然要求比较高,而船体庞然大物但相对于自身体型的速度不快,碰撞检测强度就低一些但是对自身碰撞轮廓的范围又要有所判定。所以体型特征、速度越高,需要贴障碍不穿的碰撞检测强度越大。

4,no dynamic为1状态受到连续攻击,特别是远程攻击的时候,容易概率性把动画锁死在受到攻击动画的固定帧上,然后后续进行一些动作的时候,比如说攻击也会一直固定在一个动作姿势上无法系统自发的切换其他动作。所以也要进行异常动作自检。不过这种情况高度越低越容易出现。

5.对于骨骼动作判断位移,注意虽然正常情况nodynamic开启为1后升空还是可以按照地面的wasd采用步行动画等等,但是在某些情况下比如飞行状态启动前的动作以及受击恢复和主动跳跃时,下半身动作会被锁死在jump的loop动作阶段,除非自由落地解除或强制动作,然而默认的步行动作优先级不足以强制覆盖跳跃。所以出现这种情况位移就只有movez了,或许你可以说是抛砖引玉以后引用飞行动作,但加自定义其他动作位移ai行为就也不是由系统动画动作行为来控制了,所以不推荐基础动作行为指导位移,玩家靠按键,ai靠视角目标和逻辑(也就是各种行为变量slot化,在目标相对有指引的情况下,根据想要达成的目标概率化和变量slot化行为并构造触发时间和持续的时间,再根据受限条件改变各行为slot量取值,就像编写主动带cd技能一样处理,把前后左右上下的不同方向飞行等等行为当成不同的主动技能然后进行条件组合)。



比如你的左右walk步行动作的位移控制对于玩家来说是可以用,但是对于ai其实并没有多少用处。像游戏的左右位移,一部分类ad按键一样面向朝前但是左右脚交叉横向步行,但是也可以是w前进和视角转弯配合{像一些格斗游戏比如黑神话就是ad键直接整个身体向wasd对应方向转过去,骑砍是要保证镜头往面向,不同游戏不同处理),对于在高空的ai来说,ai想要去左边的地方更倾向于采用前进动作配合原地视角转弯的行为,就算有左右脚步行持续时间也较小,产生的位移忽略不计,就像骑砍原地防御挥剑也可以原地转弯一样,面朝前的左右位移行为一般游戏只用于游走打量或闪开攻击,真正到跑到目标去打人,晃动身子W前进才是最常见的行为。


6.玩家和ai最好分开写,因为且不说玩家和ai能够主动做的行为数量有很大差别,其次如果玩家和ai的飞行都以高标准处理比如碰撞的问题,性能耗不住,如果都以低标准bug处理会很多。打个比方,ai如果只针对要打人和其他单一明确的目标事件,基本不会像玩家一样瞎走,而玩家说不定突发奇想主动往墙上蹭蹭洞里钻钻,然后我第一点说的地图边界外飞飞,干些无关战斗等正常玩法的事。如果ai我们遇到碰撞可以老远检测让其转弯,那对于玩家如果不让玩家蹭墙钻洞,老远限制运动还以为有空气墙呢。所以对于ai的软限制到玩家身上就要改多上几道硬性限制。因此,玩家和ai的行为事件最好拆开分析,哪怕是其他事件通用,位移和碰撞还有主动动作技能事件这些最好拆开,一个用高端一个用低配。











鲜花鸡蛋

杰喵喵  在2023-2-8 21:56  送朵鲜花  并说:我非常同意你的观点,送朵鲜花鼓励一下

16

主题

108

回帖

197

积分

见习骑士

Rank: 3

UID
3304622
第纳尔
690
精华
0
互助
26
荣誉
3
贡献
0
魅力
158
注册时间
2021-12-28
鲜花(31) 鸡蛋(0)
 楼主| 发表于 2023-2-8 21:57:27 | 显示全部楼层
vegetto 发表于 2023-2-8 12:31
1.整体位移的立体范围除了要考虑竖向限制ground level z的地面高度以外,还要考虑横向平面尺度boundary,也 ...

感谢大佬指点,骑砍MOD制作深似海,受教了

31

主题

210

回帖

187

积分

见习骑士

Rank: 3

UID
2462463
第纳尔
1587
精华
0
互助
23
荣誉
0
贡献
0
魅力
83
注册时间
2015-3-3
鲜花(58) 鸡蛋(0)
发表于 2023-2-10 09:35:35 | 显示全部楼层
皇牌空战——代号M&B

0

主题

59

回帖

18

积分

随仆

Rank: 1

UID
3346943
第纳尔
519
精华
0
互助
0
荣誉
0
贡献
0
魅力
0
注册时间
2022-4-8
鲜花(2) 鸡蛋(0)
发表于 2023-2-12 14:16:01 来自手机 | 显示全部楼层
支持支持,搂主加油来自: Android客户端

10

主题

75

回帖

26

积分

随仆

Rank: 1

UID
2804669
第纳尔
182
精华
0
互助
0
荣誉
0
贡献
0
魅力
0
注册时间
2017-2-6
鲜花(6) 鸡蛋(0)
发表于 2023-2-12 19:51:13 来自手机 | 显示全部楼层
写这么多LZ辛苦了,学代码基础是啥,不知道要学会PY的哪些才能看懂LZ的代码,我也想飞啊,记得以前有个飞龙MOD做的很粗糙但是可以拿来YY的,代码不会郁闷

16

主题

108

回帖

197

积分

见习骑士

Rank: 3

UID
3304622
第纳尔
690
精华
0
互助
26
荣誉
3
贡献
0
魅力
158
注册时间
2021-12-28
鲜花(31) 鸡蛋(0)
 楼主| 发表于 2023-2-15 20:10:38 | 显示全部楼层
Asterl 发表于 2023-2-12 19:51
写这么多LZ辛苦了,学代码基础是啥,不知道要学会PY的哪些才能看懂LZ的代码,我也想飞啊,记得以前有个飞龙 ...

B站很多学习编程视频,多写。

10

主题

75

回帖

26

积分

随仆

Rank: 1

UID
2804669
第纳尔
182
精华
0
互助
0
荣誉
0
贡献
0
魅力
0
注册时间
2017-2-6
鲜花(6) 鸡蛋(0)
发表于 2023-2-17 21:54:33 来自手机 | 显示全部楼层
杰喵喵 发表于 2023-2-15 20:10
B站很多学习编程视频,多写。

好的,谢谢推荐,我去试试,不知道我除了会新建种族外还能学会啥…
您需要登录后才可以回帖 登录 | 注册(Register!)

本版积分规则

Archiver|手机版|小黑屋|骑马与砍杀中文站

GMT+8, 2024-12-28 19:29 , Processed in 0.219731 second(s), 31 queries , Gzip On, MemCached On.

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

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