是的,这是最后一个…这里是先前的代码。 我们的敌人在随机射击。 现在我们需要HUD和声音效果,对吗?
直到今天,我进入Unity的第一刻的激动就一直伴随着我。
这篇文章的内容和范围得到了真正的解决,并满足了微调的BR.Sniper — 3WaterTowerAssalt – The Game的需求 。
解释的逻辑如下:有7个脚本:GameController.cs,Singleton.cs,HUD.cs,ShootHandler.cs,EnemyController.cs,Crosshair.cs和Soldier.cs。 看到…
1- GameController对象是一般的游戏组织者; 它通常被称为并且应该是唯一的; 这就是为什么我们使用Singleton 图案;
2-我们需要一个计时器标记:当我们的游戏正在运行时,某些对象必须每秒进行计数— GameController .Count()将负责此工作;
3-某些对象必须向播放器显示时间: HUD 。 mTxtTime属性的角色;
4-我们在射击某些物体时必须管理伤害逻辑 : ShootHandler的角色; 当我们击中敌人时,这种伤害是不一样的; 有时我们打敌人的手臂,另一我们打他的头; 为了模拟这一点,代码将使用Random .Range()类设置随机伤害,并将其扩展为也使敌人随机活动。 参见ShootHandler .ShootEvent() ;
5-到目前为止,太好了! 现在,当需要表现敌人的健康时,也会发生同样的事情。 他也可能会被击中,为此逻辑我们有GameController 。 mHealth财产; 平视显示器 。 mTxtHealth将向玩家介绍他的健康状况;
6-现在游戏结束时,某些对象必须控制: GameController 。 mGameOver属性的角色; 为此,它必须在玩家的健康度达到零或游戏时间结束时引发一个事件。 GameController.GameOver()的角色; 它将标志设置为true( mGameOver )并引发GameOver() ; 该对象的另一个作用是向其他对象提供信息(请参见公共获取方法属性: IsGameOver , IsWon , Health , Time ); 消息(YOU WON / LOOSE)将以痛苦的方式呈现,最初是由HUD对象禁用和控制的, HUD对象将是GameController对象引发的gameOver事件的侦听器;
7-剩下的任务是:如何知道Unity 中动画更改的配置,这在编号#08的步骤中进行了解释; 如何插入声音效果(步骤#29); 由于事件发生在主线程中,因此如何引发事件 。 为此,我们在C#中使用委托 ( GameController中的公共事件EventHandler GameOverEvent),该委托将事件传输到其他线程。 这是C#的技术问题。 有些语言使这变得更容易,而其他语言则没有……就足够了……
我很抱歉在一篇文章中只包含了这么长的解释……我衷心希望人们会开始使用Unity并了解他们在做什么🙂
让我们从Singleton开始编写代码,还记得吗?
步骤#01 —单例是不能被实例化或复制的脚本;
转到Unify Community Wiki,复制并粘贴1) Singleton.cs代码到具有相同名称的新C#脚本中; 保存;

步骤#02 —创建一个gameObject,将其重命名为2) GameController ,创建C#脚本,将其命名为GameController.cs并键入:
使用System.Collections;
使用System.Collections.Generic;
使用UnityEngine;公共类GameController:Singleton {
//确保这永远是单例
//不能使用构造函数!
受保护的GameController(){} //使用它进行初始化
void Start(){} //每帧调用一次更新
void Update(){}}
第一件事:设置一个变量来存储玩家当前的健康状况; 在GameController上摆脱Start()和Update() :
私人int mHealth = 100;
并向GameController添加设置伤害方法:
公共无效SetDamage (int损坏)
{
mHealth-=损害;
//当玩家的健康状况小于零时,他就死了
如果(mHealth <0)
{
mHealth = 0;
}
}
要撤消当前的生命值,请将此属性包含在GameController中 :
公共卫生
{
得到{return mHealth;}
}
创建> C#脚本 ,将其命名为HUD.cs; 在此脚本中输入并添加:
使用UnityEngine.UI;
并在HUD上。 更新()
//每帧调用一次更新
无效更新 ()
{
mTxtHealth.text = GameController.Instance.Health.ToString();
}
现在我们需要一个ShootEvent()来施加伤害(通过调用GameController的SetDamage ); 但首先让我们介绍一个名为HUD的界面-Heads Up Display;
步骤#03 —让我们设置HUD —平视显示器:

转到资源管理器,将Canvas重命名为HUD , 选择 HUD.cs并将n’拖放到刚创建的objectGame上;

步骤#04 —通过选择HUD添加UI文本 ,右键单击它并创建UI> Text ,将其命名为TxtHealth

步骤#05 —像这样设置TxtHealth配置:
矩形变换 :位置x = 247; 位置y = -92; 位置Z = 0
Widht = 100; 高度 = 30
文字 = 100
字体 :Arial; 样式 =粗体; 大小 = 24
资格 =左中心
颜色 =白色

步骤#06 —在Assets下创建一个文件夹,并将其命名为Images ; 将这些图像从以下位置导入到以下目录: heart.psd和time.png :
Google云端硬碟
在图像文件夹中,选择1) heart.psd图像, 2)选择Sprite ,然后单击3) 应用; 现在4)图像背景是透明的;

现在创建一个UI> Image( ImgHealth )并将heart.psd拖动到Image Source插槽;


步骤#07 —现在,我们将创建两个对象: TxtTime (UI>文本) 和ImgTime (UI> Image) ; 重复步骤4和5的相同过程; 这是HUD结果:

到目前为止,一切都很好!
步骤#08 —现在让我们处理动画; 我们将使用动画gameObject调用自定义功能: 1)选择ToonSoldier ; 2)将鼠标悬停在“场景”视图上时单击f ; 该士兵将被选中; 3)从ToonSoldier_demo>动画中单击拍摄动画; 4)点击编辑 ;

现在,在选择了assault_combat_shoot的情况下 , 1)单击事件 , 2) 添加事件 , 3) 功能= ShootEvent , 4)将鼠标悬停在适当的位置, 5)选择ToonSoldier并弹出一个窗口; 6)单击“ 应用” ,您就完成了!
现在,当此动画在此时运行时,它将触发一个名为ShootHandler 的函数 。 ShootEvent() ;

步骤#09 —返回资产>脚本文件夹, 创建一个新的C#Script,将其命名为ShootHandler.cs,通过拖动n’将其附加到ToonSoldier_demo_1 ; 在摆脱Start()和Update()之后,键入以下方法:
公共类ShootHandler :MonoBehaviour
{
公共无效ShootEvent ()
{
int doShoot = Random.Range(0,2);
如果(doShoot> 0)
{
内部伤害= Random.Range(0,6);
GameController.Instance.SetDamage(damage);
}
}
}
现在我们需要添加时间刻度,它代表一个非负整数,它指定了两个事件之间的经过时间 ;
首先,我们将扩展UI界面;
步骤#10 —操作: 1)选择HUD , 2)将TxtHealth拖放到MTextHealth属性以将其附加到脚本;

步骤#11 —转到GameController .cs并添加:
private int mTime = 30;
在下面,我们需要getter属性:
公共时间
{
得到{return mTime; }
}
步骤#12 —转到HUD .Update()并将可用时间分配给文本:
//每帧调用一次更新
无效更新 ()
{
mTxtHealth.text = GameController.Instance.Health.ToString(); mTxtTime.text = GameController.Instance.Time.ToString();
}
步骤#13 —在Unity应用上,选择HUD.cs,然后2)将n’TxtTime拖动到适当的插槽中:

步骤#14 —现在倒计时逻辑 :打开GameController.cs并输入一个新属性:
私人布尔mGameOver = false;
步骤#15 —在GameController中。 开始():
无效开始 ()
{
//每秒调用一次此方法
InvokeRepeating(“ Count”,0.0f,1.0f);
}
在下面:
//此方法将时间变量减一
无效Count ()
{
mTime--;
}
但首先检查游戏是否结束:
//此方法将时间变量减一
无效Count()
{
//如果时间结束了
如果(mTime == 0)
{
//将标志设置为true并停止计数...
mGameOver = true;
CancelInvoke(“ Count”);
}其他{
mTime-- ;
}
}
步骤#16 —仅在游戏尚未结束时设置破坏的逻辑,而在玩家死亡时设置游戏结束:
公共无效SetDamage(int损坏)
{
如果(mGameOver)
返回;
mHealth-=损害;
//当玩家的健康状况小于零时,他就死了
如果(mHealth <0)
{
mHealth = 0;
mGameOver = true ;
}
}
步骤#17 —做一个吸气剂布尔属性:
公共布尔IsGameOver
{
得到{return mGameOver;
}
}
步骤#18 —确保游戏结束时敌人不会再出现; 转到EnemyController.Update() :
无效更新(){
如果(GameController.Instance.IsGameOver)
返回;
(...)
}
保存一切。
好!
现在,当时间结束时,敌人将保持在空闲位置。
现在是结束屏幕!
步骤#19 —现在,我们需要一个痛击(PnlGameOver)来显示玩家是赢还是输。
通过右键单击Explorer UI上的HUD > painel来创建一个痛苦的人 ; 1) 居中 (居中+居中); 2) 宽度= 200,高度= 60 ; 最后是3和4) 颜色=浅暗 ;

步骤#20 —现在,右键单击“ painel”并添加一个Text并将其命名为TxtGameOver ; 并配置它: 1)将其 居中 ; 2) 宽度 = 200, 高度 = 70; 和3) 文字 =您赢了; 4) 字体和大小 = Arial,25; 和5) 对齐 =两个中心; 6) 颜色 =白色

现在取消选择痛苦(将通过脚本启用):

步骤#21 —为了在HUD.cs中访问此UI对象, 请添加2个成员变量(单击saveAll ); 将其拖到适当的插槽中;
公共类HUD :MonoBehaviour {public Text mTxtHealth;
公共文本mTxtTime; 公共RectTransform mPnlGameOver;
公共文本mTxtGameOver; (...) }

步骤#22 —转到GameController .cs并键入以下getter属性:
公共布尔IsWon
{
得到{
//如果玩家的生命值为零,那么他就死了。
如果(健康<= 0)
返回false;
//除此以外..
返回true;
}
}
步骤#23 —现在,游戏结束时,我将触发一个事件(一个EventHandler和一个C#委托),并添加一个导致该事件的方法并将其绑定到另一个类中; 转到GameController.cs并键入( 使用System键入;在顶部):
公共事件EventHandler OnGameOver;
步骤#24 —在GameController.cs内添加导致该事件的方法,并将其绑定到另一个类中:
//导致此事件并绑定到另一个类的方法
私人void OnGameOver()
{
如果(GameOverEvent!= null)
GameOverEvent(this,EventArgs.Empty);
}
步骤#25 —每当mGameOver设置为true时,调用此方法;
公共类GameController :Singleton {
无效Count()
{
(...)
mGameOver = true;
CancelInvoke(“ Count”);
OnGameOver();
} public void SetDamage (int损坏)
{
(...)
mGameOver = true;
CancelInvoke(“ Count”);
OnGameOver();
(...)
}
}
步骤#26 —在HUD.cs中,将委托绑定到Start()中;
//使用它进行初始化
无效开始(){
GameController.Instance.GameOverEvent + = OnGameOverEvent;
}
步骤#27 — 注意 :输入+ =时会弹出一个窗口; 单击选项卡以完成代码;
私人无效OnGameOverEvent(对象发送者,System.EventArgs e)
{
mPnlGameOver.gameObject.SetActive(true);
mTxtGameOver.text = GameController.Instance.IsWon吗? “ YOU WON”:“ YOU LOOSE”;
}
步骤#28 —切换到Crosshair.cs并在那里绑定事件; (单击saveAll)
//使用它进行初始化
无效的开始() {
//隐藏光标
Cursor.visible = false;
GameController.Instance.GameOverEvent + = OnGameOverEvent;
} private void OnGameOverEvent (对象发送者,System.EventArgs e)
{
this.gameObject.SetActive(false);
}
步骤#29 —现在听起来吧! 转到资产商店, 1)下载按钮, 2)按帖子筛选, 3)选择发布 启示录枪演示, 4)单击两次导入, 5)将创建一个目录;

声音地球游戏音频—天启后枪
步骤#30 —选择1)HUD。 十字准线 gameObject 2)单击“添加组件”, 3)选择“ 音频 源” ,然后将AutoGun_1p_01声音拖放到AudioClip插槽中,并4)取消选择“唤醒时播放” ;

在代码中,此设置与声音效果相关(请查看下面的代码):
宣告:
私有AudioSource mAudioSrc;
开始():
mAudioSrc = GetComponent ();
Update():
mAudioSrc.Play();
步骤#31 —转到ShootHandler.cs并将这些方法添加到ToonSoldier对象,以便我们可以听到敌人的步枪; 添加音频源 ,分配一个音频剪辑 ; 要应用到其他士兵,只需单击检查器上的“应用”按钮。

— — — — — — — — —
现在所有代码。 我现在将提供完整的代码 :
步骤#32 —这是GameController :






您可以立即制作一个游戏,但美工让它看起来不错!
换你了!
从我的Github中查看完整的代码。 谢谢!
下载3WaterGame_Unity完成!
#0#1#2#3#4#5#6#7#8#9#10
参考和学分
用Unity制作游戏(1–10):Jayanam的基础知识