植物大战僵尸的制作(不定时更新)

news/2024/10/23 20:56:03/文章来源:https://www.cnblogs.com/czyhyym/p/18498270

植物大战僵尸的制作

[点击直达github](1zero0/PlantVSZombies: 学习制作植物大战僵尸并熟悉Unity)

1.创建项目

点击右上角新项目

image-20241011163848560

选择2D(built-In Render Pipeline)(红色箭头),修改自己项目的名字(蓝色箭头),选择自己想要的地址(绿色箭头)

image-20241011163920078

2.项目

将资源包(红色箭头)拖入到Assets(蓝色箭头)中并等待一段时间。

image-20241011164343956

2.1 导入素材

如下图中,Audio就是音效Images就是相关的所有图片,其中Music中包含的就是背景音乐,随后点击右下角Import

image-20241011164456596

导入后就会在这里生成一个Audio文件夹(红色箭头)和Images文件夹(蓝色箭头)

image-20241011205018263

随后点开Audio中的MusicSound文件夹,会看到导入的音频,随便选一个,然后在右边可以点击播放(红色箭头)

:如果右边没有如下图的ch 1ch 2可以点击AssetBundle上的bgm就会弹出如图所示的样子

image-20241011205138490

3.项目制作

3.1 导入背景

再Background中找到这个白天场景(红色箭头)

image-20241014153145327

Pixels Per Unit指的是图片导入到unity中的一个单位转换,60像素转换为一米。(再unity中一个格子代表一米)

image-20241014153244104

随后将场景拖入到左侧的Scene中

image-20241014155927338

随后点击左上角Scene右侧的Game(游戏视角),并选择Full HD(1920x1080)

image-20241014160454560

随后可以通过右边的X和Y进行场景的位置改动

image-20241014161727941

随后导入卡片,以便于种植,植物再Card中

image-20241014161921870

因为植物卡片需要卡片槽(用于放置植物卡片),这里先找到卡片槽,在UI中

image-20241014162207123

  1. 随后在上面Hierarchy中右键
  2. 选择UI
  3. 选择Image

image-20241014162430279

  1. (先双击Canvas聚焦)先点击Image
  2. 选择右侧Image中的Source Image,

image-20241014162742999

在弹出的窗口中选择卡片槽

image-20241014162827306

随后点击Image中的Set Native Size

image-20241014163023406

随后将卡片槽拖拽到左上角的位置

image-20241014163046787

然后通过Game来确认它的最终位置,还是通过右侧Pos X和Pox Y进行左右和上下的移动

image-20241014163122844

  1. 选择定位
  2. 选择左上角

image-20241014163345298

3.2 植物卡片

先像上面一样创建一个Image

image-20241014163553181

随后将新建的图层拉到卡片槽的位置,并找到向日葵(可种植状态)

image-20241014163748337

随后复制一个图层并选择灰色的向日葵(不可种植状态)

image-20241014164021464

随后再次复制一个图层,并选择黑色图层(冷却状态中)

image-20241014164107731

  1. 选择Color
  2. 选择透明度

image-20241014164247413

随后在Image Type中选择Simple

image-20241014164343010

随后在选择Fill Method中的Vertical(上下)(Horizontal:水平,Radial 360:圆圈型360度,其余两个同理)

image-20241014164534844

随后选择Fill Origin中将Bottom(从下往上)改为Top(从上往下)

image-20241014164705155

随后将这三张图片分到一个组中

image-20241014165032931

并将其命名为CardTemplate,并将下面的卡片分别命名为CardLight(可种植),CardGray(不可种植),CardMask(冷却中)

image-20241014165215615

随后我们要创建一个文件夹来存放这些卡片,即将CardTemplate文件拖入到我们新建的Prefabs中

image-20241014165526556

随后将卡槽和植物卡片共同组建一个父类(也可以将植物卡片放到卡槽下),并起名为CardListUI

image-20241014165716774

这里要记得将CardListUI也定位于左上角

image-20241014165820092

3.3 为植物卡片添加脚本使之达到各种状态

先创建一个新的文件夹Scripts用于存放脚本

image-20241014170034284

  1. 点击CardTemplate
  2. 点击Add Component
  3. 输入Card,回车(两次,随后等待创建好)

image-20241014170143150

随后将新建的Card脚本拖入到Scripts中

image-20241014170312428

随后双击点开Card,在内部写入代码

enum CardState
{Cooling,WaitingSun,Ready
}public class Card : MonoBehaviour
{// 冷却 可以被点击 不可用private CardState cardState = CardState.Cooling;//要控制植物卡片的状态,就要先获取三种状态public GameObject cardLight;public GameObject cardGary;public Image cardMask;private void Update(){switch (cardState){case CardState.Cooling:CoolingUpdate();break;case CardState.WaitingSun:WaitingSunUpdate();break;case CardState.Ready:ReadyUpdate();break;default:break;}}// 卡片等待动作,首先要确定卡片的时间,即冷却时间,通过计时器来实现,通过剩余时间(冷却时间-计时器时间)/一个冷却时TransitionToWaitingSun()间生成的一个比例来给FillAmount达到一个控制效果,这样就可以使得FillAmount达到一个逐步地减少。当冷却时间到了之后就会执行TransitionToWaitingSun()转换到一个等待阳光的状态,然后就会转到WaitingSunUpdate()状态void CoolingUpdate(){cdTimer += Time.deltaTime;cardMask.fillAmount = (cdTime - cdTimer) / cdTime;  // 剩余时间的比例if (cdTimer >= cdTime){TransitionToWaitingSun();}}void WaitingSunUpdate(){}void ReadyUpdate(){}void TransitionToWaitingSun(){cardState = CardState.WaitingSun;   // 先改变植物卡片的状态(冷却状态改为灰色状态)// 植物状态的启用和禁用cardLight.SetActive(false);     // 将植物卡片亮禁用cardGary.SetActive(true);       // 植物卡片灰启用cardMask.gameObject.SetActive(false);   // 将等待状态禁用}
}

保存之后回到unity,将三种状态拖入到对应的地方(如图中红色箭头)

image-20241020201148351

3.4 阳光的计数

因为植物的种植需要阳光,所以先创建一个Empty,并改名为Manager

image-20241021200905517

随后点击右侧Add Component然后添加一个Sun Manager脚本,并双击点开

image-20241021200940111

随后先将SunManager拖入到Scripts中,随后新建文件夹Manager,并将SunManager拖入其中

image-20241021201038695

随后编写SunManager的代码,

public static SunManager Instance { get; private set; }
private void Awake()	// 进行赋值
{Instance = this;
}
[SerializeField]	// 加上一个序列化的标签,以便于可以随时改变
private int sunPoint;	// 使用私有不会让值在外面随便改变
public int SunPoint		// 用来获取阳光值
{get { return sunPoint; }
}

然后回到card中,将时间私有化,以免随便被换掉并创建序列化标签便于改变。

[SerializeField]
private  float cdTime = 2;    // 冷却时间
private  float cdTimer = 0;   // 计时器,从零开始(可以从零增加到2 ,也可以从最大减少到零)

设置一个植物的需要的阳光的值

[SerializeField]
private int needSunPoint = 50;

再回到如果需要的阳光值小于已有的阳光值,则植物卡片状态变为准备状态

void WaitingSunUpdate()
{if (needSunPoint <= SunManager.Instance.SunPoint){TransitionToReady();}
}

编写转换为准备状态的代码(高亮改为启用,等待阳光状态改为禁用,等待冷却时间保持不变)

void TransitionToReady()
{cardState = CardState.Ready;  cardLight.SetActive(true);     cardGary.SetActive(false);       cardMask.gameObject.SetActive(false);
}

3.5 准备状态(等待点击状态)

因为在准备状态可能会因为种植别的植物而使得阳光不够,所以要先确定阳光是否充足,先将阳光不够时候的代码写出

void ReadyUpdate()
{if (needSunPoint > SunManager.Instance.SunPoint){TransitionToWaitingSun();}
}

接下来给高亮时候添加一个button

image-20241022195054877

随后在card中添加一个方法用来处理自身被点击的事件,

public void Onclick(){}

并回到unity中将Card Template拖入到Select Object中

image-20241022195501219

随后点击右侧No Function选择Card中的Onclick

image-20241022195602677

随后回到代码中,因为在点击前我们可能会遇到阳光不够的情况,所以先做一个判断,如果阳光不够则直接返回,不做任何处理

public void Onclick(){if (needSunPoint > SunManager.Instance.SunPoint) return;}

再写一个转换为冷却时间的方法即Cooling方法

 void TransitionCooling(){cardState = CardState.Cooling;cdTimer = 0;cardLight.SetActive(false);cardGary.SetActive(true);cardMask.gameObject.SetActive(true);}

随后将此方法放入到点击事件中

public void Onclick()
{if (needSunPoint > SunManager.Instance.SunPoint) return;// TODO:消耗阳光值,并进行种植TransitionCooling();}

随后回到unity中并将CardTemplate复制两个,并将其分别改名为CardSunFlower和CardPeaShooter

image-20241022200714884

随后选择CardLight,点击右侧的Source Image选择peashooter的图片,CardGary同理,CardMask不做改动

image-20241022200847143

3.6 开发阳光值的消耗和更新

在CardListUI中创建一个Text-TextMeshPro(之后改名为SunPointText)

image-20241022203642114

随后选中Text(TMP)并将其拖到适合位置并改变大小

image-20241022203729089

随后点击Text(TMP)改变其中字体大小并悬着上下左右居中

image-20241022203613698

将里面的内容改为300

image-20241022203808511

改变字体颜色为黑色,并改变字体

image-20241022203937359

呈现如下效果

image-20241022204009868

随后在SunManager代码中增加public TextMeshProUGUI sunPointText;代码,并在unity中进行手动拖拽将SunPointText拖进去

image-20241022204555821

随后在SunManager代码块中增加更新阳光的代码

public void UpdateSunPointText()
{sunPointText.text = sunPoint.ToString();
}

随后在上面编写一个阳光开始的代码,并将UpdateSunPointText()放入其中

private void Start()
{UpdateSunPointText();
}

编写一个阳光减少并更新数值的代码

public void SubSun(int point) 
{sunPoint -= point;UpdateSunPointText();
}

随后进入Cards中,在点击(Onclick)方法中增加方法

public void Onclick()
{if (needSunPoint > SunManager.Instance.SunPoint) return;// TODO:消耗阳光值,并进行种植SunManager.Instance.SubSun(needSunPoint);TransitionCooling();}

3.7 创建第一个植物-向日葵

首先双击背景

image-20241023170506955

随后将中间的摄像头变小一点

image-20241023170539770

随后点开Images中的Plants,再点开SunFLower,就可以看到两种状态的向日葵图层

image-20241023172933819

选中所有的高亮向日葵并拖拽到左边Sense中

image-20241023173309494

先创建一个新的文件夹Animations,并修改文件名为Sunflower_Idle

image-20241023173423047

随后选中新出现的两个文件并放入到Animations中

image-20241023173544900

随后点击上面的Sunflower进行大小修改,这里大小合适,不做修改

image-20241023173721026

随后点击运行,这就就能看到向日葵的动态图

image-20241023173806797

注意:如果这里的向日葵会一闪一闪的,可以点击上面的Sunflower后在右侧的Additional Settings中将Order in Layer的0修改为1

image-20241023173853042

在Scripts中创建一个Plant(用于控制全部植物)的脚本

image-20241023175046763

将它拖入到Sunflower中

image-20241023175134741

3.8 关于植物不同状态的处理

在新建脚本Plant中创建枚举PlantState,里面只有两种状态Disable和Enable

enum PlantState
{Disable,Enable
}

在下面编写一个更新方法

private void Update()
{switch (plantState){case PlantState.Disable:DisableUpdate();break;case PlantState.Enable:EnableUpdate();break;default:break;}
}

并编写Disable方法和Enable方法

void DisableUpdate()
{}
void EnableUpdate()
{}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/820847.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AJAX发送请求

AJAX发送请求 ◼ AJAX 是异步的JavaScript 和 XML(Asynchronous JavaScript And XML)它可以使用JSON,XML,HTML 和text 文本等格式发送和接收数据; ◼ 如何来完成AJAX请求呢?第一步:创建网络请求的AJAX对象(使用XMLHttpRequest)第二步:监听XMLHttpRequest对象状…

实验二 类和对象_基础编程1

实验任务一:#pragma once#include <string>// 类T: 声明 class T { // 对象属性、方法 public:T(int x = 0, int y = 0); // 普通构造函数T(const T &t); // 复制构造函数T(T &&t); // 移动构造函数~T(); // 析构函数void adjust(int ra…

第二章学习笔记

第2章 模型评估与选择 2.1 经验误差与过拟合 错误率(error rate):分类错误的样本数占样本总数的比例称为错误率。 精度(accuracy):精度 = 1 - 错误率。 如果在m个样本中有a个样本分类错误,那么错误率,精度 = 1 - E。 学习器的实际预测输出与样本的真实输出之间的差异称为误…

food

厨具使用 高压锅使用详细参考和评论区:https://www.bilibili.com/video/BV1wr4y1n7Ej/?spm_id_from=333.337.search-card.all.click&vd_source=5e8f069711510b3788382a0a03ff38e5本文来自博客园,作者:我爱读论文,转载请注明原文链接:https://www.cnblogs.com/life131…

超千款鸿蒙原生游戏上架,华为游戏中心成就非凡游戏体验

10月22日,原生鸿蒙之夜暨华为全场景新品发布会在深圳举行,华为正式为用户带来全新的原生鸿蒙操作系统(HarmonyOS NEXT),这是HarmonyOS诞生以来最大的更新。发布会公布了当前HarmonyOS NEXT整体应用生态的进展,其中鸿蒙游戏领域令人瞩目。以《王者荣耀》、《和平精英》、《…

# 20222402 2024-2025-1 《网络与系统攻防技术》实验二实验报告

1.实验内容 本周学习内容 ①Shellcode技术 ②后门概念:后门就是不经过正常认证流程而访问系统的通道。 ③后门案例:XcodeGhost等。 ④后门技术:狭义后门:特指潜伏于操作系统中专门做后门的一个程序,“坏人”可以连接这个程序,远程执行各种指令。 管控功能实现技术 自启动…

基于毕奥-萨伐尔定律的交流电机的4极旋转磁场matlab模拟与仿真

1.课题概述 基于毕奥-萨伐尔定律的交流电机的4极旋转磁场,对比不同定子半径,对比2级旋转磁场。2.系统仿真结果 3.核心程序与模型 版本:MATLAB2022a% 合并位置和电流P = [xa xa_ xbxb_ xc xc_];I = [IaIa_ IbIb_ IcIc_];index = 1; % 初始化索引% 在矩形区域内循环计算磁场f…

Python量子生成对抗网络QGAN神经网络药物发现、多方法乳腺癌药物筛选应用

全文链接:https://tecdat.cn/?p=37975 原文出处:拓端数据部落公众号 分析师:Chenhao Wu在当今的医学领域,乳腺癌作为一种严重威胁女性健康的疾病,其治疗一直是科研工作者们关注的焦点。乳腺癌的发展与雌激素受体密切相关,其中 ERα 被视为治疗乳腺癌的重要靶标。能够拮抗…

java操作word

word基础 docx和doc的区别doc是微软特有的一种文件格式,其本质是一个二进制的文件 docx是基于XML的开放文档格式,是Office Open Xml的一部分。docx组成部分一个完整的docx文档由4部分构成。即 _rels、docProps、word和 [Content_Types].xmlword文件夹定义了文档的内容和格式等…

【Azure Developer】使用JavaScript通过SDK进行monitor-query的client认证报错问题

const logsQueryClient = new LogsQueryClient(credential , {endpoint: "https://api.loganalytics.azure.cn/v1" ,audience: "https://api.loganalytics.azure.cn",});问题描述 使用JavaScript通过SDK进行monitor-query的client初始化时候,需要进行认…

图论优化

图论优化 三元环计数 首先给所有边定向,从度数小的点指向度数大的点,如果度数一样,则从编号小的指向编号大的,最终形成一张DAG。 枚举\(u\)以及\(u\)指向的点\(v\)以及\(v\)指向的点\(w\),如果\(u\)也指向\(w\)则成三元环。 如果要一开始是有向图计数则最后判断一下\(u,v,…