Survival Shooter Tutorial中文解析(三)

PHASE FIVE

  1. Sacen视图中选择2D模式,菜单栏选择GameObject→UI→Canvas,重命名Canvas为HUDCanvas,添加组件Canvas Group,不勾选Interactable和Blocks Raycasts;
  2. 为HUDCanvas添加空的游戏对象命名为HealthUI,通过Anchor Presets,按住Alt和Shift将它的位置和中心点设到左下角,Wdith设为75,Height设为60;
  3. 右键HealthUI→UI→Image添加图像命名为Heart,设置Width和Height为30,在Heart的Image组件中从源图片中选择Heart;
  4. 右键HealthUI→UI→Slider添加条形命名为HealthSlider,设置Position X为95、Y为0,展开HealthSlider,删掉其子对象Handle Slide Area;
  5. 在HealthSlider的Slider组件中,将Transition模式设为None,MaxValue设为100,拖动滑动条Value到100;
  6. 右键点击HUDCanvas,创建UI→Image,重命名为DamageImage,设置Rect Transform,Alt右键点击右下角的Stretch将其尺寸扩展为全屏大小,在Image组件中,Colour块中Alpha(A)设为0。

PHASE SIX

  1. 为Player添加脚本PlayerHealth,拖动Hierarchy中的HealthSlider及DamageImage到脚本中的相应位置,为脚本中的Death Clip添加音效Player Death;
  2. 为Zombunny添加脚本EnemyAttack。
脚本PlayerHealth解析
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.SceneManagement;

namespace CompleteProject
{
    public class PlayerHealth : MonoBehaviour
    {
        public int startingHealth = 100;//Player的初始血量100
        public int currentHealth; //定义Player的当前血量变量
        public Slider healthSlider; //定义引用血条参数
        public Image damageImage; //引用受伤时的图像                        
        public AudioClip deathClip;//添加角色死亡的音效
        public float flashSpeed = 5f;//设定damageImage的淡出屏幕的速度
        public Color flashColour = new Color(1f, 0f, 0f, 0.1f); //设定damageImage的颜色


        Animator anim;//引用动画组件参数
        AudioSource playerAudio;//引用音效组件参数
        PlayerMovement playerMovement;//引用脚本PlayerMovement
        PlayerShooting playerShooting;//引用脚本PlayerShooting
        bool isDead; //声明bool值判断角色是否死亡
        bool damaged;//声明bool值判断角色是否受伤


        void Awake ()
        {
            // Setting up the references.
            anim = GetComponent <Animator> ();//设置动画
            playerAudio = GetComponent <AudioSource> ();//设置音效
            playerMovement = GetComponent <PlayerMovement> ();//指定脚本PlayerMovement
            playerShooting = GetComponentInChildren <PlayerShooting> ();//指定脚本PlayerMovement

            currentHealth = startingHealth;//将角色初始生命设置为当前生命值
        }


        void Update ()
        {
            if(damaged)
            {
        
                damageImage.color = flashColour;//角色受伤时,将flashColour赋值给damageImage的color;
            }
            else
            {
                damageImage.color = Color.Lerp (damageImage.color, Color.clear, flashSpeed * Time.deltaTime);//通过Lerp,将受伤后屏幕显示的颜色渐变消除
            }
            damaged = false;//重置角色的受伤状态为否;
        }


        public void TakeDamage (int amount)
        {
            damaged = true;//改变角色受伤状态为真
            currentHealth -= amount;//当前血量减少,减少值为受到的伤害值
            healthSlider.value = currentHealth;//将当前血量赋值给血条
            playerAudio.Play ();//播放角色受伤的音效,引用的是Player的音效组件中的Player Hurt

            if(currentHealth <= 0 && !isDead)
            {
                Death ();//当Player的血量小于等于0,isDead为flase时;
            }
        }


        void Death ()
        {
            isDead = true;//Player判定为死亡
            playerShooting.DisableEffects ();//调用playerShooting脚本中的DisableEffects方法关闭射击特效
            anim.SetTrigger ("Die");//通过触发器播放Player的死亡动画
            playerAudio.clip = deathClip;//音效组件引用脚本中的音效deathClip,Player Hurt的音效会停止播放
            playerAudio.Play ();//播放音效组件中的deathClip音效

            playerMovement.enabled = false;//关闭脚本PlayerMovemonet
            playerShooting.enabled = false;//关闭脚本PlayerShooting
        }

        public void RestartLevel ()
        {
            SceneManager.LoadScene (0);//重载当前的场景
        }
    }
}
脚本EnemyAttack解析
using UnityEngine;
using System.Collections;

namespace CompleteProject
{
    public class EnemyAttack : MonoBehaviour
    {
        public float timeBetweenAttacks = 0.5f;//攻击的间隔时间
        public int attackDamage = 10; //攻击的伤害值

        Animator anim; //声明引用动画的参数
        GameObject player; //声明引用游戏对象的参数
        PlayerHealth playerHealth;//声明引用脚本PlayerHealth的参数
        EnemyHealth enemyHealth; //声明引用脚本EnemyHealth的参数
        bool playerInRange;//定义角色是否在被攻击范围的布尔值
        float timer;//定义下次攻击的计时器  

        void Awake ()
        {
            // Setting up the references.
            player = GameObject.FindGameObjectWithTag ("Player");//通过标签设置引用的游戏对象为Player
            playerHealth = player.GetComponent <PlayerHealth> ();//引用脚本PlayerHealth
            enemyHealth = GetComponent<EnemyHealth>();//引用脚本EnemyHealth
            anim = GetComponent <Animator> ();//引用游戏动画组件
        }

        void OnTriggerEnter (Collider other)
        {
            if(other.gameObject == player) //如果进入碰撞范围的是Player
            {
               playerInRange = true;//那么Player在攻击范围内
            }
        }


        void OnTriggerExit (Collider other)
        {

            if(other.gameObject == player)//如果退出碰撞范围的是Player
            {
                playerInRange = false;//Player不在攻击范围内了
            }
        }


        void Update ()
        {
            // Add the time since Update was last called to the timer.
            timer += Time.deltaTime;//每执行一次Update,timer计时器增加一次deltaTime

            // If the timer exceeds the time between attacks, the player is in range and this enemy is alive...
            if(timer >= timeBetweenAttacks && playerInRange && enemyHealth.currentHealth > 0)//如果计时器超过了攻击间隔时间 且 玩家在被攻击范围内 且 怪物当前生命大于0
            {
                Attack ();//怪物进行一次攻击
            }

            if(playerHealth.currentHealth <= 0)//如果Player的生命值小于或等于0
            {
                anim.SetTrigger ("PlayerDead");//Player的动画触发器“PlayerDead”启动,播放该动画
            }
        }

        void Attack ()
        {
            timer = 0f;//每次执行攻击方法时,重置计时器
            if(playerHealth.currentHealth > 0)//如果Player的生命值大于0
            {
                playerHealth.TakeDamage (attackDamage);//怪物对Player造成伤害
            }
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,460评论 25 707
  • 学习Unity3D有一段时间了,庞大的U3D系统可能只学了一些皮毛。最近做东西时又要为怪物制作血条,但一时间...
    Wei_Boom阅读 42,971评论 10 26
  • 在宾馆短暂休息后。我们想要找个地方吃晚饭。可是问题来了。吃什么呢?我们从某团上找了几个比较喜欢的东西。然后准备去吃...
    MJ_巨蟹阅读 206评论 0 0
  • 乌牙。是我近期用的网名,QQ、微信都用它。朋友问怎么改我备注,我不假思索的说:就叫乌牙。名字只是一个代号,但这个符...
    乌牙阅读 1,659评论 0 0