【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 1917|回复: 0

7-6 Enemy AI 敌人的人工智能

[复制链接]
发表于 2013-10-17 13:15:10 | 显示全部楼层 |阅读模式
这个类主要处理机器人巡逻兵的人工智能,在游戏中如何处理自己的行为。
机器人在游戏中3个状态:巡逻,追玩家和向玩家开枪射击
处于第一种状态的机器人自动寻路的路径是保存在数组中的若干个点,每走到一个点稍作停留会向下一个点继续自动寻路。
机器人在追逐玩家的时候如果玩家从视野中消失,那么它会停留5秒钟,还是没发现玩家的话,就解除警报回去继续巡逻。
第三种状态是向玩家开枪,修改了动画参数以后自己关闭掉寻路系统,等待shooting类处理。
C#脚本
  1. using UnityEngine;
  2. using System.Collections;

  3. public class EnemyAI : MonoBehaviour
  4. {
  5.         public float patrolSpeed = 2f;                          // 巡逻的速度.
  6.         public float chaseSpeed = 5f;                           // 追踪玩家的速度.
  7.         public float chaseWaitTime = 5f;                        // 追踪玩家丢失目标后等待时间.
  8.         public float patrolWaitTime = 1f;                       // 巡逻到一个节点后停留时间.
  9.         public Transform[] patrolWayPoints;                     // 记录巡逻路径节点的数组.
  10.         
  11.         
  12.         private EnemySight enemySight;                          // Reference to the EnemySight script.
  13.         private NavMeshAgent nav;                               // Reference to the nav mesh agent.
  14.         private Transform player;                               // Reference to the player's transform.
  15.         private PlayerHealth playerHealth;                      // Reference to the PlayerHealth script.
  16.         private LastPlayerSighting lastPlayerSighting;          // Reference to the last global sighting of the player.
  17.         private float chaseTimer;                               // 记录追踪过程中的计时器.
  18.         private float patrolTimer;                              // 记录巡逻过程中的计时器.
  19.         private int wayPointIndex;                              // 数组下标变量
  20.         
  21.         
  22.         void Awake ()
  23.         {
  24.                 // 初始化变量.
  25.                 enemySight = GetComponent<EnemySight>();
  26.                 nav = GetComponent<NavMeshAgent>();
  27.                 player = GameObject.FindGameObjectWithTag(Tags.player).transform;
  28.                 playerHealth = player.GetComponent<PlayerHealth>();
  29.                 lastPlayerSighting = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<LastPlayerSighting>();
  30.         }
  31.         
  32.         
  33.         void Update ()
  34.         {
  35.                 // 如果玩家被巡逻机器人发现并且还活着..
  36.                 if(enemySight.playerInSight && playerHealth.health > 0f)
  37.                         // ... 机器人开枪.
  38.                         Shooting();
  39.                
  40.                 // 如果玩家已经被(可能是机器人也可能是摄像机等)发现,并且玩家活着...
  41.                 else if(enemySight.personalLastSighting != lastPlayerSighting.resetPosition && playerHealth.health > 0f)
  42.                         // ... 机器人开始追玩家.
  43.                         Chasing();
  44.                
  45.                 // 其他情况...
  46.                 else
  47.                         // ... 机器人自己寻路.
  48.                         Patrolling();
  49.         }
  50.         
  51.         
  52.         void Shooting ()
  53.         {
  54.                 // 开火的时候,机器人自动寻路停止.
  55.                 nav.Stop();
  56.         }
  57.         
  58.         
  59.         void Chasing ()
  60.         {
  61.                 // 创建一个变量记录机器人到最后一个发现角色位置的向量.
  62.                 Vector3 sightingDeltaPos = enemySight.personalLastSighting - transform.position;
  63.                
  64.                 // 如果长度大于2,(开方操作非常消耗资源,如果仅仅是比较大小,用sqrMagnitude长度的平方的话速度比较快)...
  65.                 if(sightingDeltaPos.sqrMagnitude > 4f)
  66.                         // ..那么设定自动寻路的目的地为最后一个发现玩家的位置.
  67.                         nav.destination = enemySight.personalLastSighting;
  68.                
  69.                 // 设置自动寻路的速度.
  70.                 nav.speed = chaseSpeed;
  71.                
  72.                 // 如果靠近了自动寻路的目的地...
  73.                 if(nav.remainingDistance < nav.stoppingDistance)
  74.                 {
  75.                         // ... 开始计时
  76.                         chaseTimer += Time.deltaTime;
  77.                         
  78.                         // 计时器超过了等待时间..
  79.                         if(chaseTimer >= chaseWaitTime)
  80.                         {
  81.                                 // ... 设置警报解除,取消掉最后发现玩家地点,计时器置零.
  82.                                 lastPlayerSighting.position = lastPlayerSighting.resetPosition;
  83.                                 enemySight.personalLastSighting = lastPlayerSighting.resetPosition;
  84.                                 chaseTimer = 0f;
  85.                         }
  86.                 }
  87.                 else
  88.                         // 如果还没到最终目的地,计时器保持0.
  89.                         chaseTimer = 0f;
  90.         }
  91.         
  92.         
  93.         void Patrolling ()
  94.         {
  95.                 // 设置巡逻速度.
  96.                 nav.speed = patrolSpeed;
  97.                
  98.                 // 如果靠近了目的地...
  99.                 if(nav.destination == lastPlayerSighting.resetPosition || nav.remainingDistance < nav.stoppingDistance)
  100.                 {
  101.                         // ... 计时器开始计时
  102.                         patrolTimer += Time.deltaTime;
  103.                         
  104.                         // 计时器超时...
  105.                         if(patrolTimer >= patrolWaitTime)
  106.                         {
  107.                                 // ... 修改自动巡逻的位置点下标
  108.                                 if(wayPointIndex == patrolWayPoints.Length - 1)
  109.                                         wayPointIndex = 0;
  110.                                 else
  111.                                         wayPointIndex++;
  112.                                 
  113.                                 // 计时器重置.
  114.                                 patrolTimer = 0;
  115.                         }
  116.                 }
  117.                 else
  118.                         // 如果没有靠近目的地,计时器保持0.
  119.                         patrolTimer = 0;
  120.                
  121.                 // 设置当前的目的地.
  122.                 nav.destination = patrolWayPoints[wayPointIndex].position;
  123.         }
  124. }
复制代码
JS脚本
  1. #pragma strict
  2. public var patrolSpeed : float = 2f;                        // The nav mesh agent's speed when patrolling.
  3. public var chaseSpeed : float = 5f;                         // The nav mesh agent's speed when chasing.
  4. public var chaseWaitTime : float = 5f;                      // The amount of time to wait when the last sighting is reached.
  5. public var patrolWaitTime : float = 1f;                     // The amount of time to wait when the patrol way point is reached.
  6. public var patrolWayPoints : Transform[];                   // An array of transforms for the patrol route.

  7. private var enemySight : EnemySight;                        // Reference to the EnemySight script.
  8. private var nav : NavMeshAgent;                             // Reference to the nav mesh agent.
  9. private var player : Transform;                             // Reference to the player's transform.
  10. private var playerHealth : PlayerHealth;                    // Reference to the PlayerHealth script.
  11. private var lastPlayerSighting : LastPlayerSighting;        // Reference to the last global sighting of the player.
  12. private var chaseTimer : float;                             // A timer for the chaseWaitTime.
  13. private var patrolTimer : float;                            // A timer for the patrolWaitTime.
  14. private var wayPointIndex : int;                            // A counter for the way point array.

  15. function Awake ()
  16. {
  17.     // Setting up the references.
  18.     enemySight = GetComponent(EnemySight);
  19.     nav = GetComponent(NavMeshAgent);
  20.     player = GameObject.FindGameObjectWithTag(Tags.player).transform;
  21.     playerHealth = player.GetComponent(PlayerHealth);
  22.     lastPlayerSighting = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent(LastPlayerSighting);
  23. }

  24. function Update ()
  25. {
  26.     // If the player is in sight and is alive...
  27.     if(enemySight.playerInSight && playerHealth.health > 0f)
  28.         // ... shoot.
  29.         Shooting();
  30.    
  31.     // If the player has been sighted and isn't dead...
  32.     else if(enemySight.personalLastSighting != lastPlayerSighting.resetPosition && playerHealth.health > 0f)
  33.         // ... chase.
  34.         Chasing();
  35.    
  36.     // Otherwise...
  37.     else
  38.         // ... patrol.
  39.         Patrolling();
  40. }

  41. function Shooting ()
  42. {
  43.     // Stop the enemy where it is.
  44.     nav.Stop();
  45. }

  46. function Chasing ()
  47. {
  48.     // Create a vector from the enemy to the last sighting of the player.
  49.     var sightingDeltaPos : Vector3 = enemySight.personalLastSighting - transform.position;
  50.    
  51.     // If the the last personal sighting of the player is not close...
  52.     if(sightingDeltaPos.sqrMagnitude > 4f)
  53.         // ... set the destination for the NavMeshAgent to the last personal sighting of the player.
  54.         nav.destination = enemySight.personalLastSighting;
  55.    
  56.     // Set the appropriate speed for the NavMeshAgent.
  57.     nav.speed = chaseSpeed;
  58.    
  59.     // If near the last personal sighting...
  60.     if(nav.remainingDistance < nav.stoppingDistance)
  61.     {
  62.         // ... increment the timer.
  63.         chaseTimer += Time.deltaTime;
  64.         
  65.         // If the timer exceeds the wait time...
  66.         if(chaseTimer >= chaseWaitTime)
  67.         {
  68.             // ... reset last global sighting, the last personal sighting and the timer.
  69.             lastPlayerSighting.position = lastPlayerSighting.resetPosition;
  70.             enemySight.personalLastSighting = lastPlayerSighting.resetPosition;
  71.             chaseTimer = 0f;
  72.         }
  73.     }
  74.     else
  75.         // If not near the last sighting personal sighting of the player, reset the timer.
  76.         chaseTimer = 0f;
  77. }

  78. function Patrolling ()
  79. {
  80.     // Set an appropriate speed for the NavMeshAgent.
  81.     nav.speed = patrolSpeed;
  82.    
  83.     // If near the next waypoint or there is no destination...
  84.     if(nav.destination == lastPlayerSighting.resetPosition || nav.remainingDistance < nav.stoppingDistance)
  85.     {
  86.         // ... increment the timer.
  87.         patrolTimer += Time.deltaTime;
  88.         
  89.         // If the timer exceeds the wait time...
  90.         if(patrolTimer >= patrolWaitTime)
  91.         {
  92.             // ... increment the wayPointIndex.
  93.             if(wayPointIndex == patrolWayPoints.Length - 1)
  94.                 wayPointIndex = 0;
  95.             else
  96.                 wayPointIndex++;
  97.             
  98.             // Reset the timer.
  99.             patrolTimer = 0;
  100.         }
  101.     }
  102.     else
  103.         // If not near a destination, reset the timer.
  104.         patrolTimer = 0;
  105.    
  106.     // Set the destination to the patrolWayPoint.
  107.     nav.destination = patrolWayPoints[wayPointIndex].position;
  108. }
复制代码

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2024-4-28 11:34

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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