UnityU3D TD游戏制作实例创建敌人加载预制件

Posted 是嘟嘟啊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UnityU3D TD游戏制作实例创建敌人加载预制件相关的知识,希望对你有一定的参考价值。

文章目录


前言

TD(炮台防守)类游戏是比较经典的游戏类型,当年在 War3 中有很多 TD 类地图,还有类似《保卫萝卜》这种 2D 炮台防守游戏也曾火爆一时。

本次实例将使用 Unity 实现此类游戏,功能包含地图创建、敌人创建、敌人导航、炮台创建与升级、炮台攻击、敌人攻击等功能。

本章实现效果

场景和敌人

场景的创建使用 MTE 插件,该插件的使用方法可以参考另两篇文章:
【Unity】Unity插件:地形编辑器MTE(Mesh Terrain Editor)
【Unity】Unity寻路系统讲解及Navigation实际应用

敌人的模型及动画可以在 Unity Assets Store 中下载。后续章节我也会讲解如何使用模型和动画来生成预制件。

导航的功能可以参考另外几篇文章:
【Unity】Unity寻路系统讲解及Navigation实际应用
【Unity】导航基本组件:Nav Mesh Agent、Off Mesh Link、Nav Mesh Obstacle
【Unity】导航 Navigation 设置:窄桥、隧道、斜坡、台阶、坠落、跳跃
【Unity】Navigation 选择性寻路:Area Mask

动画播放可以参考另一篇文章:
【Unity】U3D ARPG游戏制作实例(二)人物基本动作切换

文件目录结构


如上图所示,目录结构基本按照以下原则:

  • Data:用于存放所有的模型、材质、纹理、动画控制器,其目录结构按照防御塔、敌人、基地、地形划分,每个目录下有相应的文件夹,以第一个敌人为例,在Enemy目录下创建一个名为Enemy_0001的目录,该目录下包含3D(模型及动画文件)、AnimatorController(动画控制器)、Materials、Textures四个目录。注意,敌人的Prefab预制体不应被存放到此文件夹中,因为预制体需要放到Resources文件夹中,以便后续动态加载。
  • Plugins:存放所有插件,例如EasyTouch、MTE等。
  • Resources:该文件夹中的内容可以被动态加载,所以我们做好的Prefab预制件要放到此文件夹中。注意,不要把所有的文件都放到此文件夹中,这会影响性能。
  • Secenes:场景文件。
  • Scripts:存放脚本文件。目前脚本暂时分为 Control(控制)、Defense(防御塔)、Enemy(敌人)、Game(游戏主程序)、Level(关卡)、Nav(导航),相应的脚本放入相应的文件夹下。

场景层次结构(Hierarchy)

如上图,场景 Hierarchy 结构大致如下:

  • Directional Light:直接光源,其后两个为测试光源,请忽略。
  • Main Camera:主相机。目前只提供一个主相机,后续可能会提供地图相机。
  • Easytouch:Easytouch、InputManager、EasyTouchControlsCanvas、EventSystem等都是用于处理输入事件的,在此不做过多处理。
  • Canvas:UI界面画布。
  • EnemyGeneratePoint:敌人出生点,所有敌人都要以出生点为父节点创建出来。一个场景内可能会有多个出生点,后续在加载 Level 时统一做处理。
  • TerrainParent:地图父节点,通过预制件加载的地图就放在此节点下。
  • GameScript:游戏脚本挂载处,用于挂载游戏核心脚本。

目前文件和场景结构设定如下,后续可能会有小范围更改。

处理模型

先将模型放到场景中,给模型创建好动画控制器,具体操作方式请见:【Unity】U3D ARPG游戏制作实例(二)人物基本动作切换

给模型指定导航代理以及自定义脚本:

将模型从场景中拖拽到文件夹中:

指定GameScript脚本

给 GameScript 节点指定两个脚本,代码如下:

using TDGameDemo.Nav;
using UnityEngine;

namespace TDGameDemo.Enemy


    /// <summary>
    /// 敌人创建器
    /// </summary>
    public class EnemyGenerator : MonoBehaviour
    

        /// <summary>
        /// 生成敌人
        /// </summary>
        /// <param name="parent">父对象</param>
        /// <param name="enemy">敌人配置对象</param>
        /// <param name="target">导航目标</param>
        /// <returns></returns>
        public bool GenerateEnemy(Transform parent, string enemy, Transform target)
        
            try
            
                GameObject enemyPrefab = Resources.Load<GameObject>(enemy);
                GameObject o = Instantiate(enemyPrefab, parent, true);
                o.GetComponent<NavTest>().target = target;
            
            catch (System.Exception)
            
                return false;
                throw;
            
            return true;
        
    


using TDGameDemo.Enemy;
using UnityEngine;

namespace TDGameDemo.Game


    /// <summary>
    /// 游戏主程序
    /// 加载关卡、游戏的开始、暂停、通关、失败
    /// </summary>
    public class GameMain : MonoBehaviour
    
        private EnemyGenerator _enemyGenerator;
        public Transform _generatePoint;
        public Transform _target;

        void Start()
        
            _enemyGenerator = GetComponent<EnemyGenerator>();
        

        void Update()
        
            if (Input.GetKeyDown(KeyCode.A))
            
                _enemyGenerator.GenerateEnemy(_generatePoint, "Enemy/Prefab/Prefab_Enemy_10001", _target);
            
        
    


此处路径暂时写死,后续要根据配置文件读取。

将出生点和基地的节点给到 GameMain 脚本:

运行游戏

使用 A 键来生成敌人。效果如下:


更多内容请查看总目录【Unity】Unity学习笔记目录整理

遮罩和图层

预制体


1.制作预制体,将节点拖入到assets文件下;

2.加载预制体 代码加载和手动绑定

3.预制体对象实例化:cc.instantiate(预制体)

4.假如你有一个 飞机游戏 他有源源不断的×××,这时候

就可以把这个×××当成模板,然后不断复制这个预制体.


5.把要当预制体的节点 复制到 资源管理器即可

技术分享图片



6.在代码里面创建预制体

首先要获得预制体对象 可以外部加载也可以绑定组件

cc.Class({
    extends: cc.Component,
    properties: {
    item_prefab:{
    type: cc.Prefab,
    default: null,
    },
    
    },

把预制体拖动到这里
技术分享图片



    start :function() {
    //实例化预制体
    var itema = cc.instantiate(this.item_prefab);
    //加入到场景
    this.node.addChild(itema);
    },



Mask组件 遮罩


1.Mask组件是提供viewport功能的一个组件,你可以想象通过

一个窗口去看外面的世界,只能看到这个窗口大小的视区.

2.Mask的形状:矩形.圆形.图片的Alpha制来做mask;

3.一个节点加上Mask组件后,他和他的子节点如果:

在这个范围内就会显示, 不在范围的就不会显示.会被裁剪掉.


4.面板属性 

Type类型

技术分享图片

(1)RECT矩形  

矩形的高度和宽度在size里设置 技术分享图片


(2)ELLIPSE椭圆

(3)IMAGE_STENCIL图片


Inverted 反向遮罩 效果是相反的


首先使用矩形 在他下面添加一个子节点,无论子节点多大只显示这个范围.

技术分享图片

技术分享图片  技术分享图片

反向遮罩 他只裁剪 mask范围内的 

技术分享图片

圆形

技术分享图片


使用图片来做遮罩,例如一个圆形头像,就要这个圆形的遮罩图

技术分享图片

放到这里

技术分享图片

拖动修改就行

技术分享图片




cc.Layout 


1.布局组件:

  有些物体的布局,可以不用我们写死位置,可以根据内容来排版

比如垂直排版,水平排版,就不用手动去调整.

2布局组件的面板属性:

技术分享图片

Type:排布类型

VERTICAL 垂直自动排布

他又多出几个属性

Top距离上面

Bottom 底部的距离

Spacing Y 两个垂直节点 间距 

技术分享图片

技术分享图片



Resize Mode缩放模式 默认不使用

但是有的元素会超出

技术分享图片

CONTAINER 会自动对容器大小进行缩放

CHILDREN 对子节点大小缩放




GRID 先水平在垂直

技术分享图片






cc.ScrollView 


1滚动列表主要结构:

root->view(Mask裁剪超出范围的内容)-->content(Layout)负责内容排版

2 滚动列表的每个选项

root(x,h,指定大小给Layout同)

3代码里面使用cc.ScrollView

将选项做成预制体

在代码里实例化预制体,加到这个content节点下


他有两个子节点 一个是滚动条

技术分享图片


还有一个view是 mask组件的  因为我们要超过这个范围的

 让他不能显示的

技术分享图片


每一项都是放在这个content下面的

技术分享图片


item就是里面的 视图里的一个项

技术分享图片


直接在content里添加一个 Layout布局组件


首先要设置 size大小 因为layout是根据这个来调整的

技术分享图片


技术分享图片




4.在代码里使用cc.ScrollView



    //往scrollview里添加 实际上就是添加到Content里面

    //添加10个
    for(var i =0;i<10;i++){
    //实例化 预设体
    var opt_item = cc.instantiate(this.opt_item);
    opt_item.getChildByName("uname").
    getComponent(cc.Label).string="中年人";
    //把这个项添加到 content上面去
    this.scrollView.content.addChild(opt_item);
    }


技术分享图片








以上是关于UnityU3D TD游戏制作实例创建敌人加载预制件的主要内容,如果未能解决你的问题,请参考以下文章

将敌人的方向瞄准玩家游戏制作工作室 2 DnD

如何制作一个塔防小游戏

Unity:使用动画师实例化预制件

Scanvenger游戏制作笔记控制敌人的移动

查找丢失组件的预制体

太空大战游戏开发实例