[Unity2D入门教程]简单制作仿植物大战僵尸游戏之③完善Defender植物和Attacker的相关细节(脚本,碰撞体)

 在创建完它们的Animation之后我们还要为他们特定的行径编写脚本,(比如Lizard鳄鱼需要向前移动),向日葵Trophy需要生产阳光,仙人掌Cactus需要向前发射子弹

我们先从向日葵Trophy开始写起,这里我们在Canvas底下创建一个Text

这层灰蒙蒙的是我创建的一个空对象Buttons下的子对象3D Object叫Quad并给它一个material

搞好这些之后我们给刚刚创建的Text一个脚本就叫Stars Display(别忘了挂载)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
public class StarsDisplay : MonoBehaviour
{
    [SerializeField] int stars = 100;
    Text starText;
    void Start()
    {
        starText = GetComponent<Text>();
    }
    //更新当前的星星(在变化以后)
    private void UpdateDisplay()
    {
        starText.text = stars.ToString();
    }
    //判断是否有足够的行星
    public bool HaveEnoughStars(int amount)
    {
        return stars >= amount ? true : false;
    }
    //增加星星
    public void AddStars(int amount)
    {
        stars += amount;
        UpdateDisplay();
    }
    //使用星星(创建植物)
    public void SpendStars(int amount)
    {
        if (stars >= amount)
        {
            stars -= amount;
            UpdateDisplay();
        }
    }
    
}

编写脚本:

我们还要创建一个Defender的脚本给我们的向日葵Trophy

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);
    }
}

那我们到底要在哪里用这个AddStars(int)呢,这里就到了使用动画事件的时候了。

点击你想要的帧数,可以看到Samples 右边有个Add Events像个竖杠,这里就创建好了

点击后在inspector面板可以看到我们把刚刚创建的方法选择好改变它的int的值

当运行游戏时每当运行到这一帧的时候Star的值就会加一次3 

我们再来搞一下我们的仙人掌Cactus

他也需要一个Defender.cs来记录生成它需要花费多少Stars

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);
    }
}

还需要一个Shooter

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

public class Shooter : MonoBehaviour
{
    [SerializeField] GameObject projectTile;
    [SerializeField] GameObject gun;
    AttackSpawner myLaneSpawner;
    private void Start()
    {
        SetLaneSpawner();
    }
    private void Update()
    {
        if(IsAttackerInLand())
        {
            Debug.Log("Shoot");
        }
        else
        {
            Debug.Log("Sit and Lane");
        }
    }
    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); //生成子弹
    }
}

这里我们创建好的空对象Gun就作为发射点

同样我们还要创建一个子弹的Prefab,这里大伙应该都看得懂就不细讲了直接上图

我们还需要给它一个Projectile名字的脚本

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);
        }
        
    }
}

 创建敌人:

  我们先给它设置好这两项就到脚本的部分

 敌人当然需要生命值:

        Health的脚本如下

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秒后销毁生成的爆炸特效
    }
}

 这是向左移动的脚本

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

public class Attacker : MonoBehaviour
{
    [Range(0, 5)]
    float currentSpeed = 1f;  
    void Update()
    {
        transform.Translate(Vector2.left * currentSpeed * Time.deltaTime);
    }
    public void SetMovementSpeed(float speed)
    {
        currentSpeed = speed;
    }
}

进入游戏,敌人就会开始移动了,

有关敌人生成的位置以及点击植物来在场景中生成植物的内容,放在下一篇来讲。

猜你喜欢

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