【Untiy&项目分享&项目讲解】UnitZ的敌人生成系统 1 敌人孵化器

来源:互联网 发布:mac的ps和windows 编辑:程序博客网 时间:2024/04/27 12:15

在网络上面找到的一个完整的Unity项目,类似未转变者Unturn


本文章就来讲解下,UnitZ的敌人生成系统

打开UnitZ的项目,发现敌人生成的区域使用的是Enemy Spawner(Spawn产卵)



(图1 大图)



(图2 大图)

-------------------------------------------------------------------------------------------

void Start ()//用于初始化

{
        indexSpawn = Random.Range (0, Objectman.Length);//获得一个 数组对象 中的 随机对象
        timetemp = Time.time;//Time.time:从游戏开始后开始计时,表示截止目前共运行的游戏时间。
    }

-------------------------------------------------------------------------------------------

   void ObjectExistCheck ()
    {
        // checking a number of all objects. that's was spawn with this spawner  一个数字 用于  检查 生成了孵化对象的 所有对象

        ObjectsNumber = 0;// 如果 生成 了 敌人 ,这个ObjectsNumber就自己加1。ObjectsNumber是生成了敌人的数量
        foreach (var obj in spawnList) {
            if (obj != null)
                ObjectsNumber++;
        }
    }

-------------------------------------------------------------------------------------------

资料3

void OnDrawGizmos ()//画一个立方体,用于判断这个 孵化器 的范围
    {
        #if UNITY_EDITOR
        Gizmos.color = Color.red;//红线
        Gizmos.DrawSphere (transform.position, 2);//描述:用在transform.position绘制一个大小为2绘制一个球体.
        Gizmos.DrawWireCube (transform.position, this.transform.localScale);//    描述:用transform.position和this.transform.localScale绘制一个线框立方体.
        Handles.Label(transform.position, "Enemy Spawner");//在transform.position位置 绘制一个"Enemy Spawner"的文本
        #endif
    }

-------------------------------------------------------------------------------------------

 //检测地面,在 射线的位置 向下 发射一个射线,判断该点 的位置
    Vector3 DetectGround (Vector3 position)

    {
        RaycastHit hit;
        if (Physics.Raycast (position, -Vector3.up, out hit, 1000.0f)) {
            return hit.point;//如果 物理射线 向下 发射长度为 1000.0f的射线 存在,就返回 地面 的位置。否则就返回 当前该点的位置
        }
        return position;
    }

向下发射一个长度为1000.0f的射线,是肯定会有一个返回对象的

如果出现bug,就返回当前人物的位置

-------------------------------------------------------------------------------------------

会在后面来解释 一大串坐标XYZ

    void Update()//这个函数是主要运行的函数
    {
        OnActive = false;//初始化使得,孵化器 孵化状态 为否
        if (PlayerEnter)
        {
            // check if player is enter this area当玩家进入该区域
            GameObject[] playersaround = GameObject.FindGameObjectsWithTag(PlayerTag);//找到所有标签为“敌人”的物体,把其放入 对象数字 playeraround中
            for (int p = 0; p < playersaround.Length; p++)
            {//判断 敌人标签 的对象数组 中的每个对象
                if (Vector3.Distance(this.transform.position, playersaround[p].transform.position) < this.transform.localScale.x)
                {
                    OnActive = true;
                    //【资料5】当 这个孵化器的位置 与 敌人标签 的对象数组 的 每个对象 的位置  的距离  
                    //小于 这个孵化器的 【资料6】相对于父级物体变换的缩放。 X。使其 孵化器 状态 为真
                }//结束IF
            }//结束循环FOR
        }//结束IF
        else
        {
            OnActive = true;//否则 也为真
        }//结束ELSE

        bool offlineMode = (!Network.isServer && !Network.isClient);//一个布尔变量 判断是否 在线。离线状态模式offlineMode

        if (!OnActive)//如果玩家没有进入 则 跳出update函数
            return;

        ObjectExistCheck();//检查敌人数量
        if (Objectman[indexSpawn] == null)//如果没有生成敌人,则跳出 update函数
            return;

        // spawn if ObjectsNumber is less than Max object.如果 孵化器 已经生成的敌人数量,小于 最大的物体
        if (ObjectsNumber < MaxObject && Time.time > timetemp + TimeSpawn)
        {//如果生成敌人数量 小于 最大生成敌人数量  且  系统运行时间 大于 这两个控制变量【用于在系统运行开始一段时间内不启动这个判断语句】

            timetemp = Time.time;//使得timetemp 的值 为 当前 系统运行时间
            GameObject obj = null;//生成一个 物体 变量使其为空。
            //生成 一个三维的 对象spawnPoint 调用检测地面的函数,把 后面一大串的坐标XYZ
            Vector3 spawnPoint = DetectGround(transform.position + new Vector3(Random.Range(-(int)(this.transform.localScale.x / 2.0f), (int)(this.transform.localScale.x / 2.0f)), 0, Random.Range((int)(-this.transform.localScale.z / 2.0f), (int)(this.transform.localScale.z / 2.0f))));//生成一个3维坐标 spawnPoint ,用来判断
            //后面一大串的坐标XYZ 意味着 从 这个孵化器的 坐标开始 计算 一个在孵化器范围内的随机的坐标
            //new Vector3(Random.Range(-(int)(this.transform.localScale.x / 2.0f), (int)(this.transform.localScale.x / 2.0f)), 0, Random.Range((int)(-this.transform.localScale.z / 2.0f), (int)(this.transform.localScale.z / 2.0f)))
            if (!offlineMode)//判断 如果在线
            {
                if (Network.isServer)//如果连接到 服务器
                {//spawnPoint在孵化器范围内随机 的一个坐标
                    obj = (GameObject)Network.Instantiate(Objectman[indexSpawn], spawnPoint, Quaternion.identity, 0);//就 使用联网的敌人数组 在spawnPoint,方位为Quaternion.identity 生成敌人
                }//结束IF
            }//结束IF
            else
            {
                obj = (GameObject)GameObject.Instantiate(Objectman[indexSpawn], spawnPoint, Quaternion.identity); //否则也生成物体,使用的是当前单机的敌人数组
            }//结束ELSE
            if (obj)//如果obj物体 = 敌人 存在
                spawnList.Add(obj);//就在spawnList物体数组中添加其中
            indexSpawn = Random.Range(0, Objectman.Length);//indexSpawn 为 已经生成的敌人 的随机数

        }//结束IF
    }//结束UPDATE

(大图3大图4)

为了区分,把这一长串的数据用回车来划分。

随机函数的使用参考 资料7

new Vector3(//随机函数返回一个坐标,组成了 一个新的 3维坐标

Random.Range(

-(int)(this.transform.localScale.x / 2.0f),(int)(this.transform.localScale.x / 2.0f)

), //获得一个随机的坐标X,范围 在浅红色深红色的范围内

0,

Random.Range(

(int)(-this.transform.localScale.z / 2.0f),(int)(this.transform.localScale.z / 2.0f)

)//获得一个随机的坐标Z,范围 在浅蓝色深蓝色 的范围内

)

(图5)

在该项目中,孵化器的大小为如下图所示区域,Scale。因为在相对坐标系中,当该孵化器 成为 某一物体 的子物体的 时候,

要获得当前坐标(因为孵化器成为某物体的子类,对相对父类的Scale坐标进行操作),即为this.transform.localScale

(图6)

-------------------------------------------------------------------------------------------

(图7)

资源分享:

1.UnitZ.unitypackage  57.7MB

资料参考

2.Unity3D中的工具类-Time类

3.Unity3D脚本18:可视化辅助设置类 Gizmos

4.Handles.Label 标签

5.Vector3.Distance 距离

6.Transform.localScale 自身缩放

7.Unity3D中随机函数的应用

0 0