Unity实战 RTS3D即时战略游戏开发(十二) 战斗AI的控制

来源:互联网 发布:软件开发个人简历 编辑:程序博客网 时间:2024/05/16 07:40

         大家好,我是Zander,我们接着来开发Rts3D即时战略游戏开发。这节课我们接着来讲AI的相关部分:战斗AI。

         游戏中要进行战斗,就需要让AI会攻击,首先在一定范围内如果有足够的单位则进行攻击,在AI文件夹中创建一个StrikeAi的脚本,编辑如下:

using UnityEngine;using System.Collections;public class StrikeAi : AiBehavior {public int DronesRequired = 10;  //无人机数量public float TimeDelay = 5;     //等待时间public float SquadSize = 0.5f;   //public int IncreastPerWave = 10; //每波增加单位数量public override void Execute (){var ai = AiSupport.GetSupport (this.gameObject);  //获得AIDebug.Log (ai.Player.Name + " is attacking");int wave = (int)(ai.Drones.Count * SquadSize);DronesRequired += IncreastPerWave;foreach (var p in RtsManager.Current.Players) {if (p.IsAi)continue;for (int i = 0; i < wave; i++) {var drone = ai.Drones [i];var nav = drone.GetComponent<RightClickNavigation> ();nav.SendToTarget (p.Location.position);}return;}}public override float GetWeight (){if (TimePassed < TimeDelay)   //判断是否到了下一波攻击时间return 0;TimePassed = 0;var ai = AiSupport.GetSupport (this.gameObject);if (ai.Drones.Count < DronesRequired)   //判断是否决定攻击return 0;return 1;}}

返回到Unity,为Prefabs文件下的DroneUnit 添加RightClickNavigation脚本,然后重载一下里面的 sendToTarget方法

public void SendToTarget(Vector3 pos){target = pos;SendToTarget ();}
现在就可以检测单位,并自动攻击了,不过现在还没有攻击效果,在开火攻击前,我们先来设置一下相机的初始位置,让摄像机出生时就能看到玩家,我们打开Scripts文件夹下的CameraCradle脚本,并编辑 如下:

using UnityEngine;using System.Collections;public class CameraCradle : MonoBehaviour {public float Speed = 20;public float Height = 80;   //距离地面的高度// Use this for initializationvoid Start () {foreach (var p in RtsManager.Current.Players)   //判断玩家位置,并把摄像机的位置放置玩家的上方{ if (p.IsAi)continue;var pos = p.Location.position;pos.y = Height;transform.position = pos;}}// Update is called once per framevoid Update () {transform.Translate (Input.GetAxis ("Horizontal") * Speed * Time.deltaTime,Input.GetAxis ("Vertical") * Speed * Time.deltaTime,0);}}
好了,现在摄像机就可以出生在玩家的上方了,接下来我们实现开火攻击的效果,创建一个Battle文件夹,并在下面新建一个AttackInRange脚本,如下:

using UnityEngine;using System.Collections;public class AttackInRange : MonoBehaviour {public float FindTargetDelay = 1;  // 寻找目标间隔public float AttackRange = 20;     //攻击范围public float AttackFrequency = 0.25f;  //攻击频率public float AttackDamage = 1;      //伤害值private ShowUnitInfo target;        //攻击目标的显示信息private PlayerSetupDefinition player;   //玩家的所属阵营private float findTargetCounter = 0;   //计时器  找到新目标后或者上次攻击后过了多长时间private float attackCounter = 0;     //// Use this for initializationvoid Start () {player = GetComponent<Player> ().Info;}/// <summary>/// 寻找目标/// </summary>void FindTarget(){if (target != null) {if (Vector3.Distance (transform.position, target.transform.position) > AttackRange)  //目标距离判断{return;}}foreach (var p in RtsManager.Current.Players) {if (p == player)continue;foreach (var unit in p.ActiveUnits) {if (Vector3.Distance (unit.transform.position, transform.position) < AttackRange) {target = unit.GetComponent<ShowUnitInfo> ();return;}}}target = null;}/// <summary>/// 攻击逻辑/// </summary>void Attack(){if (target == null)return;target.CurrentHealth -= AttackDamage;}// Update is called once per framevoid Update () {findTargetCounter += Time.deltaTime;if (findTargetCounter > FindTargetDelay)   //寻找目标{FindTarget ();findTargetCounter = 0;}attackCounter += Time.deltaTime;if (attackCounter > AttackFrequency)   //攻击{Attack ();attackCounter = 0;}}}
返回Unity,为DroneUnit添加此脚本,现在就可实现攻击效果,并产生伤害了,但是还没有在UI界面上体现出来。剩下的信息显示和销毁效果,咱们在下一章中再讲。

      好了,这一章就写到这,欢迎大家加入QQ群:280993838  或者关注我的公众号:



1 0
原创粉丝点击