unity制作简单的植物大战僵尸

这篇具有很好参考价值的文章主要介绍了unity制作简单的植物大战僵尸。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


介绍

简单制作植物大战僵尸游戏。

协程实现各种相机动画
卡片填充方式修改为:“已填充”,实现植物恢复
事件系统实现拖拽植物
植物子弹实现对象池

unity创建urp,项目,unity


掉落阳光

unity创建urp,项目,unity

这段代码是一个Unity游戏中的太阳类(Sun),实现了天上掉落的太阳落下的功能。具体实现如下:

isSkySun:bool 类型的变量,用于标记太阳是否是天上掉落的。
TargetY:float 类型的变量,表示太阳落到的目标位置。
speed:float 类型的变量,表示太阳下落的速度。
InitSkySun 方法:用于初始化天上掉落的太阳,传入太阳的初始位置(x, y)和目标位置 TargetY。
Update 方法:在每一帧更新时,如果太阳是天上掉落的且未被点击(isSkySun 和 isClick 都为 true),则让太阳向下移动。如果太阳到达目标位置 TargetY,则销毁太阳。注意,isClick 变量在该代码中未被定义。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
//太阳 :天上掉落  太阳花掉落
/// </summary>
public class Sun : MonoBehaviour
{
    //是否是天上掉落的
    private bool isSkySun;

    //天空中的太阳下落的目标点
    private float TargetY;

    //速度
    private float speed = 1;

    private void Start()
    {
        //初始化
        sunNum = GameObject.Find("SunNum");
    }

    //初始化天上的太阳 初始化开始的位置 及TargetY
    public void InitSkySun(float x, float y, float targetY)
    {
        //设置初始位置和目标位置
        transform.position = new Vector3(x, y, 0);
        TargetY = targetY;
        isSkySun = true;
    }

    private void Update()
    {
        if (isSkySun == true)
        {
            // 天空下落的太阳   过程中 未被点击  
            if (isClick == false)
            {
                //如果太阳未被点击,则让太阳向下移动
                if (transform.position.y > TargetY)
                {
                    transform.Translate(new Vector3(0, -1, 0) * Time.deltaTime * speed);
                }
                else
                {
                    //当太阳到达目标位置时,销毁太阳
                    Destroy(gameObject, 3f);
                }
            }
        }
    }
}

InitSkySun 方法用于初始化天上掉落的太阳,传入太阳的初始位置(x, y)和目标位置 TargetY。Update 方法中,如果太阳未被点击,太阳会一直向下移动,直到到达目标位置 TargetY,然后销毁太阳。


卡片恢复透明度

unity创建urp,项目,unity

在植物卡片上叠加一个灰色卡片,设置透明度。
设置图像类型为“已填充”

unity创建urp,项目,unity


    private void Update()
    {
        //计时 更新UI
        timer += Time.deltaTime;
        UpdateProgress();
        UpdateBg();

    }

    private void UpdateProgress()
    {
        //计算相应的百分比
        float per = Mathf.Clamp(timer / coolTime, 0, 1);

        image.fillAmount = 1 - per;
    }

    private void UpdateBg()
    {
        //1.是否冷却  fillAmount=0
        //2.如果当前拥有的阳光  比消耗的阳光多  

        if (image.fillAmount == 0 && GameMgr.Instance.GetSun() >= costSun)
        {
            bg.SetActive(false);
        }
        else
        {
            bg.SetActive(true);
        }
    }

拖拽卡片到方格子上生成植物

unity创建urp,项目,unity

这段代码定义了一个名为"Card"的类,这个类继承了三个接口IBeginDragHandler、IDragHandler、IEndDragHandler。这个类是用于控制游戏中卡牌的行为的,其中包括冷却时间、花费阳光数量、要创建的植物物体、计时器、当前物体等属性。这个类还包括一些方法,如UpdateProgress()、UpdateBg()、ScreenToWorld()、LoadByName()、OnBeginDrag()、OnDrag()和OnEndDrag()等方法,用于更新UI、加载卡牌、生成物体、让物体跟随鼠标、让物体生成在点击到的格子上等。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;

/// <summary>
///      卡片     
/// </summary>
public class Card : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    //冷却时间
    public float coolTime = 4;
    //计时器
    private float timer;

    private Image image;

    private GameObject bg;
    //花费的阳光
    public int costSun;

    //要创建的植物物体
    public GameObject plantPrefab;



    //当前的物体
    public GameObject curObj;






    private void Start()
    {
        //初始化
        costSun = 50;
        timer = 0;
        image = transform.Find("progress").GetComponent<Image>();
        bg = transform.Find("bg").gameObject;

        //string[] cardName = name.Split("_");
        //string resPath = "Prefabs/" + cardName[1];
        //Debug.Log(resPath);
        LoadByName(gameObject.name);
    }


    private void Update()
    {
        //计时 更新UI
        timer += Time.deltaTime;
        UpdateProgress();
        UpdateBg();

    }


    private void UpdateProgress()
    {
        //计算相应的百分比
        float per = Mathf.Clamp(timer / coolTime, 0, 1);

        image.fillAmount = 1 - per;
    }


    private void UpdateBg()
    {
        //1.是否冷却  fillAmount=0
        //2.如果当前拥有的阳光  比消耗的阳光多  

        if (image.fillAmount == 0 && GameMgr.Instance.GetSun() >= costSun)
        {


            bg.SetActive(false);

        }
        else
        {
            bg.SetActive(true);
        }
    }


    //屏幕坐标  转  z为0的世界坐标
    public Vector3 ScreenToWorld(Vector3 pos)
    {

        Vector3 po = Camera.main.ScreenToWorldPoint(pos);

        //确保pos 为0;
        Vector3 final = new Vector3(po.x, po.y, 0);
        return final;

    }
    根据名字 加载 物体
    //public void LoadByName(string name)
    //{
    //    // 切割字符串
    //    string[] cardName = name.Split("_");
    //    //加载预制体
    //    string resPath = "Prefabs/" + cardName[1];
    //    plantPrefab = Resources.Load<GameObject>(resPath);


    //}

    public void LoadByName(string name)
    {
        // 切割字符串
    //    string[] cardName = name.Split("_");
        string[] cardName = name.Split('_');


        if (cardName.Length > 1)
        {
            // 加载预制体
            string resPath = "Prefabs/" + cardName[1];
            plantPrefab = Resources.Load<GameObject>(resPath);
        }
        else
        {
            // 处理拆分结果不正确的情况
            Debug.LogError("Invalid name format: " + name);
        }
    }





    //生成一个物体  出现在鼠标所对应的世界处坐标
    public void OnBeginDrag(PointerEventData eventData)
    {
        //  Debug.Log(eventData.position);  
        //  eventData.position  不是  世界坐标    做转换
        // unity 坐标系   1. 世界坐标系   2.屏幕坐标系     3.视口坐标  ***

        //如果黑色背景激活
        if (bg.activeSelf)
        {
            return;
        }
        curObj = Instantiate(plantPrefab);
        curObj.transform.position = ScreenToWorld(eventData.position);


    }

    //  让物体 跟随 着鼠标
    public void OnDrag(PointerEventData eventData)
    {
        if (curObj != null)
        {
            curObj.transform.position = ScreenToWorld(eventData.position);
        }
    }
    //让物体生成在点击到的格子上
    public void OnEndDrag(PointerEventData eventData)
    {

        //计时器重置
        timer = 0;

        //UI更新  
        GameMgr.Instance.ChangSun(-costSun);

        UIMgr.Instance.ChangeUICount(GameMgr.Instance.GetSun());

        //开始正式种植
        if (curObj == null) { return; }


        Collider2D[] col = Physics2D.OverlapPointAll(ScreenToWorld(eventData.position));

        // 遍历所有的格子

        for (int i = 0; i < col.Length; i++)
        {

            //1 是格子

            //2有没有植物
            if (col[i].tag == "Land" && col[i].gameObject.transform.childCount == 0)
            {

                curObj.transform.position = col[i].transform.position;

                curObj.transform.SetParent(col[i].transform);


                //这里我们生成的是游戏物体  拖动时会调用方法
                //会出现 拖动时发射子弹的bug
                //设置isOnGround 为true


                //以豌豆为例 后续会提取Plant 类
                //Peashooter obj = curObj.GetComponent<Peashooter>();

                //if (obj != null)
                //{

                //    obj.isOnGround = true;

                //}

                Plant obj = curObj.GetComponent<Plant>();

                if (obj != null)
                {

                    obj.isOnGround = true;

                }




                curObj = null;
                return;


            }

        }
        // 如果没有合适的格子   curob还在

        if (curObj != null)
        {
            GameObject.Destroy(curObj);
            curObj = null;
        }







    }
}


僵尸生成器

unity创建urp,项目,unity

僵尸放在一个链表中

Awake(): 在对象被创建时调用的方法,将当前对象赋值给Instance,实现单例模式。
CreateZombine(): 创建僵尸的方法。实例化僵尸预制体,随机选择生成点,设置生成点的父对象、位置和层级。将生成的僵尸添加到存储的僵尸列表中。
AddZombine(Zombine zom): 将僵尸添加到存储的僵尸列表中。
RemoveZombine(Zombine zom): 从存储的僵尸列表中移除僵尸。
CreateStartZombie(): 创建初始僵尸的方法。循环3次,实例化僵尸预制体,随机选择生成点,设置生成点的父对象、位置和层级。将生成的僵尸添加到正在展示的僵尸列表中,将其动画的播放速度设置为0,将其isWalk标志设为false。
DestoryZombieShow(): 销毁正在展示的僵尸的方法。遍历正在展示的僵尸列表,销毁每个僵尸的游戏对象。
Start(): Unity的内置方法,在脚本启用时调用。调用CreateByTime()方法。
CreateByTime(): 按时间创建僵尸的方法。使用协程CreateSomeZombie(),在一定条件下循环生成僵尸。
CreateSomeZombie(): 使用假数据创建一些僵尸的协程方法。在一定条件下循环生成僵尸。根据刷新标志isRefresh的值,生成一定数量的僵尸,并在每次生成之间等待一定的时间间隔。
StopCreateZombie(): 停止创建僵尸的方法。停止所有的协程。
ClearZombie(): 清除所有僵尸的方法。将刷新标志isRefresh设为false,并销毁存储的所有僵尸的游戏对象。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 僵尸管理
/// </summary>
public class ZombieMgr : MonoBehaviour
{
    public static ZombieMgr Instance;

    public GameObject zombiePrefab;
    //生成点列表
    public Transform[] bornPoint;
    //存储的列表
    public List<Zombine> zombies = new List<Zombine>();

    public List<Zombine> zombineShow = new List<Zombine>();
    private int layerIndex = 0;
    //是否刷新
    public bool isRefresh = false;


    private void Awake()
    {
        Instance = this;
    }



    public void CreateZombine()
    {
        //生成物体
        GameObject go = GameObject.Instantiate(zombiePrefab);
        //随机坐标
        int index = Random.Range(0, 5);//0 1 2 3 4
        go.transform.parent = bornPoint[index];
        go.transform.localPosition = Vector3.zero;


        //设置层级
        layerIndex += 1;

        go.GetComponent<SpriteRenderer>().sortingOrder = layerIndex;
        AddZombine(go.GetComponent<Zombine>());
    }

    public void AddZombine(Zombine zom)
    {
        zombies.Add(zom);
    }

    public void RemoveZombine(Zombine zom)
    {
        zombies.Remove(zom);
    }


    public void CreateStartZombie()
    {
        for (int i = 0; i < 3; i++)
        {
            GameObject go = GameObject.Instantiate(zombiePrefab);
            //随机坐标
            int index = Random.Range(0, 5);//0 1 2 3 4
            go.transform.parent = bornPoint[index];
            go.transform.localPosition = Vector3.zero;

            Zombine zombine = go.GetComponent<Zombine>();
            zombineShow.Add(zombine);
            go.GetComponent<Animator>().speed = 0;

            zombine.isWalk = false;
        }
    }





    public void DestoryZombieShow()
    {

        for (int i = 0; i < zombineShow.Count; i++)
        {
            GameObject.Destroy(zombineShow[i].gameObject);
        }
    }

    public void Start()
    {
        CreateByTime();
    }
    public void CreateByTime()
    {
        StartCoroutine(CreateSomeZombie());
    }

    //使用假数据
    private IEnumerator CreateSomeZombie()
    {
        while (layerIndex < 12)
        {
            //是否在刷
            if (isRefresh == true)
            {
                int delay = Random.Range(2, 5);
                yield return new WaitForSeconds(delay);

                int randomNum = Random.Range(1, 4);
                for (int i = 0; i < randomNum; i++)
                {
                    CreateZombine();
                }
            }
            yield return new WaitForSeconds(5);
        }
        yield return new WaitForSeconds(5);
        StartCoroutine(CreateSomeZombie());
    }

    public void StopCreateZombie()
    {
        StopAllCoroutines();
    }


    public void ClearZombie()
    {
        isRefresh = false;
        for (int i = 0; i < zombies.Count; i++)
        {
            GameObject.Destroy(zombies[i].gameObject);

        }
        //zombies.Clear();
    }






}

子弹对象池

unity创建urp,项目,unity

在Awake()函数中,将该脚本实例化为单例对象。

在Start()函数中,创建对象池,即实例化一定数量的子弹对象,将它们添加到对象池中,并将其设为未激活状态。

在GetPoolObject()函数中,从对象池中获取一个子弹对象,如果对象池中存在未被激活的子弹对象,则直接返回该对象,并将其设为激活状态;如果对象池中不存在未被激活的子弹对象,则创建一个新的子弹对象,将其添加到对象池中,并将其设为激活状态,最后返回该对象。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 子弹对象池  仅作为简单讲解  不涉及其他复杂操作   单例
/// </summary>
public class BulletPool : MonoBehaviour
{

    public static BulletPool Instance;


    //子弹预制体
    public GameObject bulletPrefab;
    //对象池容量
    public int amount = 10;
    // 物品列表
    private List<GameObject> pool = new List<GameObject>();


    private void Awake()
    {
        Instance = this;
    }


    private void Start()
    {   //创建对象池的物体
        for (int i = 0; i < amount; i++)
        {
            GameObject go = Instantiate(bulletPrefab);
            //让物体失活
            go.SetActive(false);
            //添加到对象池
            pool.Add(go);

        }
    }

    //从对象池获取物体
    public GameObject GetPoolObject()
    {
        for (int i = 0; i < pool.Count; i++)
        {
            //找出未被激活的物体  将其激活  并返回
            if (!pool[i].activeInHierarchy)
            {
                pool[i].SetActive(true);
                return pool[i];
            }
        }
        //如果没有满足条件的物体  创建物体  添加到池中   激活 并返回
        GameObject go = GameObject.Instantiate(bulletPrefab);
        pool.Add(go);


        go.SetActive(true);
        return go;
    }
}

源码


https://wwez.lanzoul.com/iSCMm0yyk99c文章来源地址https://www.toymoban.com/news/detail-743359.html


到了这里,关于unity制作简单的植物大战僵尸的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 植物大战僵尸各种僵尸攻略

    此文章为“植物大战僵尸”专栏中的009刊(2023年9月第八刊),欢迎订阅。版权所有。 注意: 1.本博客适用于pvz无名版; 2.pvz指植物大战僵尸(Plants VS Zonbies); 3.本文以耗费低做标准,方法不唯一; 4.本期讲述较弱的僵尸。 1.路障舞王 路障舞王死后会有伴舞僵尸,打起来很轻

    2024年02月09日
    浏览(27)
  • Python实现植物大战僵尸

    大二暑期python项目,使用pygame编写,仅实现了冒险模式一关及我是僵尸,均使用原版贴图和音效,并尽量完整复刻了动画效果 资源链接:https://download.csdn.net/download/qq_39033469/87373063 冒险模式: 经典关卡,合理运用阳光种植植物抵挡僵尸,消灭所有僵尸后获胜 目前共有7种植物

    2023年04月25日
    浏览(71)
  • 针对“扫雷“和“植物大战僵尸“游戏,分析,扫描,阳光值,植物,金币,僵尸的分析逆向

    《软件逆向分析》 2022年9月 [一、实验工具介绍 3](#一实验工具介绍) [二、针对\\\"扫雷\\\"游戏 3](#二针对扫雷游戏) [2.1分析\\\"初级\\\"、\\\"中级\\\"和\\\"高级\\\"的棋盘内存地址范围 3](#分析初级中级和高级的棋盘内存地址范围) [2.2找出\\\"雷数\\\"、\\\"笑脸\\\"和\\\"计时器\\\"的内存地址 9](#找出雷数笑脸和计时

    2024年02月07日
    浏览(31)
  • 【植物大战僵尸融合机器学习】+源码

    今天给大家推荐一个Gtihub开源项目:PythonPlantsVsZombies,翻译成中就是植物大战僵尸。 《植物大战僵尸》是一款极富策略性的小游戏。可怕的僵尸即将入侵,每种僵尸都有不同的特点,例如铁桶僵尸拥有极强的抗击打能力,矿工僵尸可以挖地道绕过种植在土壤表面的植物等。玩

    2024年04月17日
    浏览(61)
  • Java版【植物大战僵尸+源码】

    今天给大家推荐一个Gtihub开源项目:PythonPlantsVsZombies,翻译成中就是植物大战僵尸。 《植物大战僵尸》是一款极富策略性的小游戏。可怕的僵尸即将入侵,每种僵尸都有不同的特点,例如铁桶僵尸拥有极强的抗击打能力,矿工僵尸可以挖地道绕过种植在土壤表面的植物等。玩

    2024年04月12日
    浏览(30)
  • Python面向对象植物大战僵尸

     

    2024年02月12日
    浏览(31)
  • C语言手写-植物大战僵尸

    植物大战僵尸,是一个非常经典的小游戏,初学者从零开始,开发一个自己的植物大战僵尸,还是非常值得期待的!可以作为自己的课设,也可以用来快速提升自己的项目开发能力。 说明:因为完整动图提交后提示违规,所以这里仅截图示意。如果需要演示视频,在评论中回

    2023年04月27日
    浏览(80)
  • 前端小游戏——植物大战僵尸

    给大家分享一个植物大战僵尸网页游戏源代码,感兴趣的小伙伴可收藏学习 (完整源码在文末) 先来一睹“芳容” 《植物大战僵尸》 是一款极富策略性的小游戏。可怕的僵尸即将入侵,每种僵尸都有不同的特点,例如铁桶僵尸拥有极强的抗击打能力,矿工僵尸可以挖地道绕

    2024年02月03日
    浏览(31)
  • python植物大战僵尸源码教学

    大家好,给大家分享一下一个有趣的事情,很多人还不知道这一点。下面详细解释一下。现在让我们来看看! 大家好,我是梦执,对梦执着。希望能和大家共同进步! 下面给大家带来python实现植物大战僵尸的的源码分享,只含有冒险模式python 安装后怎么用。 截图+动态演示

    2024年02月22日
    浏览(37)
  • 用 Python 实现植物大战僵尸代码!

    plant_frozen_time_list[0] 是太阳花的冷却时间。 植物卡片类 每个植物卡片是一个单独的Card类,用来显示这个植物。 checkMouseClick函数:判断鼠标是否点击到这个卡片; canClick:判断这个卡片是否能种植(有没有足够的点数,是否还在冷却时间内); update 函数:通过设置图片的透

    2024年04月23日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包