[Unity2D入门教程]简单制作仿植物大战僵尸游戏之⑤制作更多的敌人Attacker以及防御者Defender

制作更多的Defender:

  之前我们创建了一个向日葵和一个仙人掌,今天我们多创建两个

  首先是一个老头Gnome,我们让它的功能和仙人掌一样,所以我会尽量快点讲完,

 需要给它三个脚本Defender,Shooter,Health

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

public class Defender : MonoBehaviour
{
    [SerializeField] int starCost = 100;

    public int GetStarCost()
    {
        return starCost;
    }
    public void AddStars(int amount)
    {
        FindObjectOfType<StarsDisplay>().AddStars(amount);
    }
}

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

public class Shooter : MonoBehaviour
{
    [SerializeField] GameObject projectTile;
    [SerializeField] GameObject gun;
    AttackSpawner myLaneSpawner;
    Animator animator;
    private void Start()
    {
        animator = GetComponent<Animator>();
        SetLaneSpawner();
    }
    private void Update()
    {
        if(IsAttackerInLand())
        {
            animator.SetBool("isAttacking", true);
        }
        else
        {
            animator.SetBool("isAttacking", false);
        }
    }
    private void SetLaneSpawner()
    {
        AttackSpawner[] spawners = FindObjectsOfType<AttackSpawner>();
        //找到这行路的所有敌人
        foreach(var spawner in spawners)
        {
            //判断是不是在我们这一行
            bool IsCloseEnough = (Mathf.Abs( spawner.transform.position.y - transform.position.y ) <= Mathf.Epsilon);
            if (IsCloseEnough)
            {
                myLaneSpawner = spawner; //找到我这条路的生成敌人
            }
        }
    }
    private bool IsAttackerInLand()
    {
        //如果我这条路上的敌人数量小于等于0return false
        if(myLaneSpawner.transform.childCount <= 0)
        {
            return false;
        }
        else
        {
            return true;
        }
    }

    public void Fire()
    {
        Instantiate(projectTile, gun.transform.position, transform.rotation); //生成子弹
    }
}

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

public class Health : MonoBehaviour
{
    [SerializeField] float health = 100f;
    [SerializeField] GameObject deathVFX;
    public void DealDamage(float damage)
    {
        health -= damage;
        if(health <= 0)
        {
            TriggerDeathVFX();
            Destroy(gameObject);
        }
    }
    //生成爆炸特效
    private void TriggerDeathVFX()
    {
        if (!deathVFX) return;
        GameObject deathVFXObject = Instantiate(deathVFX, transform.position, transform.rotation);
        Destroy(deathVFXObject, 1f); //1秒后销毁生成的爆炸特效
    }
}

然后给它碰撞框和动画并把参数都填上去后我们给它一个空对象Body创建组件Sprite Renderer。通过改变它的Sprite来制造动画。

斧头的Prefab如下

动画就让他旋转365°

 

 

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

public class Projectile : MonoBehaviour
{
    [SerializeField] float speed = 1f;
    [SerializeField] float damage = 50f;
    void Update()
    {
        transform.Translate(Vector2.right * speed * Time.deltaTime);
        
    }
    private void OnTriggerEnter2D(Collider2D other)
    {
        var health = other.GetComponent<Health>();
        var attacker = other.GetComponent<Attacker>();

        if(attacker && health)
        {
            health.DealDamage(damage);
            Destroy(gameObject);
        }
        
    }
}

然后我们来创建一个墓碑GraveStone,相当于高坚果,它的血量非常厚可以挡住很久

除了前面的脚本还要给他一个独特的脚本,但只是给之后我们创建的敌人识别的

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

public class GraveStone : MonoBehaviour
{
    private void OnTriggerStay2D(Collider2D other)
    {
        Attacker attacker = other.GetComponent<Attacker>();
        if (attacker)
        {

        }
    }
}

给它做个动画就稍微改变一下它的Scale值

 

最后,别忘了把他们放到我们之前创建的Quad中

 

 

创建敌人:

  在创建新的敌人之前,我们需要让敌人都实现能吃植物的动画,因此我们创建一个鳄鱼的吃植物动画Lizard Attack把对应的素材拖进ANimation

 

我们选择添加动画事件,当执行那一帧的时候植物掉血。

 

吃植物时候速度为0 

这个是一口多少血

 

 

 创建一个Lizard给它

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

public class Lizard : MonoBehaviour
{
    private void OnTriggerEnter2D(Collider2D other)
    {
        GameObject otherGameObject = other.gameObject;

        if (otherGameObject.GetComponent<Defender>())
        {
            GetComponent<Attacker>().Attack(otherGameObject);
        }
    }
}

Attacker脚本更新后如下:

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

public class Attacker : MonoBehaviour
{
    GameObject currentTarget;
    [Range(0, 5)]
    float currentSpeed = 1f;

    private void Awake()
    {
        FindObjectOfType<LevelController>().AttackerSpawn();
    }
    private void OnDestroy()
    {
        LevelController level = FindObjectOfType<LevelController>();
        if (level != null)
        {
            level.AttackerKilled();
        }
    }
    void Update()
    {
        transform.Translate(Vector2.left * currentSpeed * Time.deltaTime);
        UpdateAnimationState();
    }

    private void UpdateAnimationState()
    {
        if (!currentTarget)
        {
            GetComponent<Animator>().SetBool("isAttacking", false); 
        }
    }

    public void SetMovementSpeed(float speed)
    {
        currentSpeed = speed;
    }
    public void Attack(GameObject target)
    {
        GetComponent<Animator>().SetBool("isAttacking", true); //播放吃植物动画
        currentTarget = target;//锁定植物
    }
    public void StrikeCurrentTarget(float damage)
    {
        if (!currentTarget) return;
        Health health = currentTarget.GetComponent<Health>();
        if (health)
        {
            health.DealDamage(damage);//扣植物的血
        }
    }

}

在完成了鳄鱼后,我们要创建一个特别的狐狸敌人:

同样先给他设置好动画

 

 

 

 

 给它添加好脚本后添加参数再创建一个名字叫fox的脚本

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

public class Fox : MonoBehaviour
{
    private void OnTriggerEnter2D(Collider2D other)
    {
        GameObject otherGameObject = other.gameObject;

        if (otherGameObject.GetComponent<GraveStone>()) //当遇到gravestone时他会跳过去
        {
            GetComponent<Animator>().SetTrigger("JumpTrigger");
        }

        else if (otherGameObject.GetComponent<Defender>()) //而其它的他会吃掉
        {
            GetComponent<Attacker>().Attack(otherGameObject);
        }
    }
}

 同样我们也要为他创建动画事件

 

 

 


游戏效果:

可见跑的跑跳的跳,鳄鱼直接开吃,最下排的生成敌人给老头两斧头扔死了

猜你喜欢

转载自blog.csdn.net/dangoxiba/article/details/124184789
今日推荐