防守单位

防守单位分为两种,近战和使用弓箭的。部署防守单位需要花费金币。

1、近战防守单位

1、创建Defender.cs,它的代码为:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Defender : MonoBehaviour
{//格子的状态public enum tileStatus{DEAD = 0,ROAD = 1,GUARD = 2}//攻击范围public float m_attackArea = 2.0f;//攻击力public int m_power = 1;//攻击时间间隔public float m_attackInterval = 2.0f;//目标敌人protected Enemy m_targetEnemy;//是否面向敌人protected bool m_isFaceEnemy;//模型Prefabprotected GameObject m_model;//动画播放器protected Animator m_ani;//静态函数创建敌人实例,限制模板类为Defender或者是Defender的派生类public static T Create<T>(Vector3 pos, Vector3 angle) where T : Defender{//创建一个空物体,名字为"defender"GameObject go = new GameObject("defender");go.transform.position = pos;go.transform.eulerAngles = angle;//添加Denfender脚本组件或者是它的派生类T t = go.AddComponent<T>();t.Init();//将自己的格子信息设置为DEAD不能在部署TileObject.instance.setDataFromPosition(t.transform.position.x, t.transform.position.z, (int)tileStatus.DEAD);return t;}//初始化protected virtual void Init(){m_attackArea = 2.0f;m_power = 2;m_attackInterval = 2.0f;//创建模型CreateModel("swordman");//执行攻击逻辑StartCoroutine(Attack());}//创建模型protected virtual void CreateModel(string modelname){//需要把模型放在Resources目录下GameObject model = Resources.Load<GameObject>(modelname);m_model = (GameObject)Instantiate(model, this.transform.position, this.transform.rotation, this.transform);m_ani = m_model.GetComponent<Animator>();}//协程,自动攻击敌人protected virtual IEnumerator Attack(){while(m_targetEnemy == null || !m_isFaceEnemy){//如果没有目标或者不是朝向敌人则不攻击yield return 0;}//播放攻击动画m_ani.CrossFade("attack", 0.1f);//等待进入攻击动画while(!m_ani.GetCurrentAnimatorStateInfo(0).IsName("attack")){yield return 0;}//获得攻击动画的长度float ani_length = m_ani.GetCurrentAnimatorStateInfo(0).length;//等待完成攻击动作yield return new WaitForSeconds(ani_length * 0.5f);if(m_targetEnemy != null){m_targetEnemy.SetDamage(m_power);}//等待播放完剩余的动画yield return new WaitForSeconds(ani_length * 0.5f);//播放待机动画m_ani.CrossFade("idle", 0.1f);//攻击的间隔yield return new WaitForSeconds(m_attackInterval);//开始下一次攻击StartCoroutine(Attack());}//自动朝向敌人public void RotateTo(){if(m_targetEnemy == null){return;}var tardir = m_targetEnemy.transform.position - this.transform.position;//旋转y轴tardir.y = 0;//获取旋转方向Vector3 rot_delta = Vector3.RotateTowards(this.transform.forward, tardir, 20.0f * Time.deltaTime, 0.0f);Quaternion targetRotation = Quaternion.LookRotation(rot_delta);//计算当前方向与目标方向的角度float angle = Vector3.Angle(tardir, transform.forward);//如果已经面向敌人if(angle < 1.0f){m_isFaceEnemy = true;}else{m_isFaceEnemy = false;}transform.rotation = targetRotation;}//查找敌人,有先攻击生命值最低的敌人public void FindEnemy(){if(m_targetEnemy != null){//如果已经有目标了,则继续攻击return;}m_targetEnemy = null;int minlife = 0;//遍历一遍所有敌人foreach(Enemy e in GameManager.instance.m_enemyList){if(e.m_life == 0){continue;}//计算与敌人的距离Vector3 pos1 = this.transform.position;Vector3 pos2 = e.transform.position;float dist = Vector2.Distance(new Vector2(pos1.x, pos1.z), new Vector2(pos2.x, pos2.z));//如果距离超过攻击范围if(dist > m_attackArea){continue;}//查找生命值最低的敌人if(minlife == 0 || minlife > e.m_life){m_targetEnemy = e;minlife = m_targetEnemy.m_life;}}}// Update is called once per framevoid Update(){FindEnemy();RotateTo();Attack();}
}

2、远程防守单位

1、创建Projectile.cs脚本,他是用来创建弓箭。它的代码为:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Projectile : MonoBehaviour
{// Start is called before the first frame update//当打击到目标时进行的操作System.Action<Enemy> onAttack;//目标对象Transform m_target;//目标模型的边框Bounds m_targetCenter;//使用静态函数创建弓箭public static void Create(Transform target, Vector3 spawnPos, System.Action<Enemy> action){//读取弓箭模型GameObject prefab = Resources.Load<GameObject>("arrow");GameObject go = (GameObject)Instantiate(prefab, spawnPos, Quaternion.LookRotation(target.position - spawnPos));//添加弓箭脚本组件Projectile arrow = go.AddComponent<Projectile>();//获取目标arrow.m_target = target;//获取目标边框arrow.m_targetCenter = target.GetComponentInChildren<SkinnedMeshRenderer>().bounds;//获取Actionarrow.onAttack = action;//3s之后自动销毁Destroy(go, 3.0f);}// Update is called once per framevoid Update(){if(m_target != null){this.transform.LookAt(m_targetCenter.center);}//向目标前进this.transform.Translate(new Vector3(0, 0, 10 * Time.deltaTime));if(m_target != null){//简单检测是否打击到目标if(Vector3.Distance(this.transform.position,m_targetCenter.center) < 0.5f){//攻击onAttack(m_target.GetComponent<Enemy>());//销毁弓箭Destroy(this.gameObject);}}}
}

2、创建Archer.cs,它是用来创建弓箭防守单位。它的代码为:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Archer : Defender
{protected override void Init(){m_attackArea = 5.0f;m_power = 1;m_attackInterval = 1.0f;CreateModel("archer");StartCoroutine(Attack());}//攻击逻辑protected override IEnumerator Attack(){while(m_targetEnemy == null || !m_isFaceEnemy){//如果没有目标则一直等待yield return 0;}//播放攻击动画m_ani.CrossFade("attack", 0.1f);//等待进入攻击动画while(!m_ani.GetCurrentAnimatorStateInfo(0).IsName("attack")){yield return 0;}//获取攻击动画的长度float ani_length = m_ani.GetCurrentAnimatorStateInfo(0).length;//等待完成攻击动作yield return new WaitForSeconds(ani_length * 0.5f);//如果有目标敌人,则向目标敌人发射弓箭if(m_targetEnemy){Vector3 pos = this.m_model.transform.Find("atkpoint").position;//创建弓箭Projectile.Create(m_targetEnemy.transform, pos, (Enemy e) =>{e.SetDamage(m_power);m_targetEnemy = null;});}//等待攻击动作播放结束yield return new WaitForSeconds(ani_length * 0.5f);//播放待机动画m_ani.CrossFade("idle", 0.1f);//等待攻击间隔yield return new WaitForSeconds(m_attackInterval);//进行下一次攻击StartCoroutine(Attack());}}

3、部署防守单位

1、修改GameManager.cs代码中的onButtonCreateDefenderUp函数,修改后的代码为:

void onButtonCreateDefendUp(BaseEventData data)
{//创建射线Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hitInfo;//判断碰撞if(Physics.Raycast(ray, out hitInfo, 1000, m_groundLayer)){//如果选中的是一个可以部署防守单位的格子if(TileObject.instance.getDataFromPosition(hitInfo.point.x,hitInfo.point.z) == (int)Defender.tileStatus.GUARD){//计算碰撞点的位置Vector3 hitpos = new Vector3(hitInfo.point.x, 0, hitInfo.point.z);//获得Grid Object座位位置Vector3 gridpos = TileObject.instance.transform.position;//获得格子大小float tilesize = TileObject.instance.m_tileSize;//计算出所点的格子的中心点的坐标hitpos.x = gridpos.x + (int)((hitpos.x - gridpos.x) / tilesize) * tilesize + tilesize * 0.5f;hitpos.z = gridpos.z + (int)((hitpos.z - gridpos.z) / tilesize) * tilesize + tilesize * 0.5f;//获得选择的GameObjectGameObject go = data.selectedObject;if(go.name.Contains("1")){//减10金币创建防守单位if(SetGold(-10)){Defender.Create<Defender>(hitpos, new Vector3(0, 180, 0));}}else if(go.name.Contains("2")){//减15金币创建防守单位if (SetGold(-15)){Defender.Create<Archer>(hitpos, new Vector3(0, 180, 0));}}}}m_isSelectedButton = false;
}

4、运行效果

Unity塔防游戏学习(六)相关推荐

  1. Unity塔防游戏的制作与实现

    一.游戏场景的搭建 首先,我们需要创建一个新的Unity场景,并将场景设置为2D模式.然后,我们需要导入一些必要的素材,如地图.塔.怪物.子弹等.我们可以从Unity Asset Store中下载这些 ...

  2. unity塔防游戏开发之基于标点法来简易实现敌人路线移动

    unity塔防游戏开发之基于标点法来简易实现敌人路线移动 首先创建一个物体,把它设置为静态物体,给他创建一系列子物体,将这些子物体放在各个路线的转角处,这样就实现标点的目的,然后将这些路标的位置都设置 ...

  3. unity塔防游戏,可以正常运行

    unity塔防游戏 游戏截图如下:(下载链接在文末) 点我下载资源 https://download.csdn.net/download/weixin_43474701/64828307

  4. unity塔防游戏怪物转向_Unity官方新手游戏项目推荐合集

    Unity官方新手游戏项目推荐合集 今天给同学们介绍一些Unity官方发布过的一些游戏项目,这些项目都简化了游戏开发的入门学习过程,可以快速地制作出游戏,适合新手入门体验,下面就带同学们看一看: Un ...

  5. unity塔防游戏怪物转向_怪兽塔防手游下载-怪兽塔防官方版v1.0下载

    怪兽塔防官方版是一款画风Q萌的塔防手游,怪兽塔防里有很多可爱的怪物,保护你身后的城堡,不断到来的敌人会对你造成极大的威胁,你可以通过在固定的位置放置武器进行防御,这将考验你对紧急情况的反应和应对能力, ...

  6. unity塔防游戏怪物转向_怪兽塔防手机版下载-怪兽塔防游戏下载v1.4 安卓版

    怪兽塔防,融入大量呆萌怪物玩法的经典塔防手游,游戏中玩家需要不断应对来袭的敌人,游戏中玩家需要在关卡中放置武器进行防御,游戏十分考验玩家的反应力与应变能力,游戏玩法挑战性十足,感兴趣的玩家可以下载体验 ...

  7. unity塔防游戏怪物转向_玩一玩这款塔防游戏?

    关注上方蓝字获得更多内容 今日分享塔防游戏 塔防游戏,曾经也是风靡一时,非常受人喜欢的. 今天小皮分享的这款和保卫萝卜可以说是异曲同工,还是不错的. 该游戏拥有精美的画面,并且在形象设计上也制作的相当 ...

  8. unity塔防游戏怪物转向_英雄塔防物语游戏下载-英雄塔防物语官方版 v2.3.8最新版...

    英雄塔防物语手游欢迎大家来下载,英雄塔防物语是一款二次元塔防放置手游,这款游戏为大家带来全新的角色,玩家可以收集卡牌进行组合对战,玩法十分丰富,还有丰富的剧情等你来解锁哦. [游戏简介] 英雄塔防物语 ...

  9. unity塔防游戏怪物转向_野生防御塔游戏下载-野生防御塔游戏安卓版 v1.0

    野生防御塔是一款塔防策略类型的游戏,经典好玩的塔防策略玩法等你来,在这开启一场刺激的塔防吧.你需要依靠塔防建筑抵挡怪物的攻击,同时也需要面对对手的偷袭.依靠击杀怪物获得的金币可以购买一些道具升级你的塔 ...

  10. unity塔防游戏怪物转向_一款塔防+第一人称射击的混合类游戏

    ​HELLO-大家好,这里是小白的每日一游推荐时间.世上的游戏千千万,有许多好玩的游戏由于缺乏宣传,所以不被广大玩家所熟知.在这里小白每天会为大家推荐一款评价很高但是不太出名的游戏- <幽闭圣地 ...

最新文章

  1. 没听说过这些,就不要说你懂并发了,three。
  2. 【API知识】ElementUI一些问题的解决方案
  3. linux下perl命令行参数,Perl One-Liners | Perl命令行学习1 -e参数
  4. 临时笔记, 有意思的东西
  5. mongodb的基本操作数据更新
  6. Vue 项目更新,浏览器不需强制刷新就可更新版本! 防止缓存
  7. 寻星时卫星数字电视接收机的信号检测功能
  8. 计算机网络管理员下午试题答案,(完整版)计算机网络管理员考试试题库和答案(13页)-原创力文档...
  9. 计算机如何在文段中插入符号,插入项目符号与编号(Word 2013基础)——想象力电脑应用...
  10. SLAM Cartographer(1)框架与安装
  11. 加油,我看好你 本题由擂主Wfox提供 -flag{bc57380e-9f8d-4b1e-8432-794b54b5625f}
  12. 2021年第十二届蓝桥杯大赛软件赛决赛C/C++大学A组 个人部分题解
  13. Warshall算法代码实现
  14. rpm、yum、编译安装轻松解决centos7程序包安装
  15. Android 4.0模拟器弹出---“谷歌拼音输入法”已停止运行的解决方法
  16. 我的前半生之十四,谈论富婆是一种高级趣味
  17. 计算机与数学交融的教学设计,信息技术与小学数学学科的整合 小学数学教案...
  18. bzoj 3398: [Usaco2009 Feb]Bullcow 牡牛和牝牛
  19. 面向对象三大特性-多态
  20. 在Win10平台上搭建AI训练(英伟达GPU加速)环境

热门文章

  1. 使用xlang开发隐形水印制作工具
  2. 国外哪个服务器最稳定,合适的国外服务器有什么选择技巧
  3. linux 查看IP地址
  4. 数据结构银行排队系统c语言,数据结构银行排队系统实验报告
  5. 分布式存储Ceph之PG状态详解
  6. CSP - 201403-1 - 相反数 (C++)
  7. html5在线播放flac,分享5个无损音乐网站
  8. 联想Thinkpad E430搜不到无线网络
  9. 机器学习系列文章【转自我的新浪博客】
  10. Ubuntu启用root权限