Unity2D教程:物品拾取、Trigger、计时器

关注专栏,持续更新哦

教程总目录


物品若无法拾取也不会阻碍人物行动,所以设置为Is Trigger。
在这里插入图片描述

上代码

Helper.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 帮助类
/// </summary>
public class Helper : MonoBehaviour
{
    // 获取Collider2D collision所对应的PlayerHealthChange
    public static PlayerHealthChange GetPlayerByCollider2D(Collider2D collision)
    {
        return collision.gameObject.GetComponent<PlayerHealthChange>();
    }

    // 调整GameObject obj的不透明度为a
    public static void SetOpaquenessOfGameObject(GameObject obj, float a)
    {
        Color c = obj.GetComponent<SpriteRenderer>().material.color;
        c.a = a;
        obj.GetComponent<SpriteRenderer>().material.color = c;
    }
}

Resource.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 可拾取资源
/// </summary>
public class Resource : MonoBehaviour
{
    private int healthChangeValue;
    void Start()
    {
        if (tag == "Pepper") healthChangeValue = -1;
        else if (tag == "Mushroom") healthChangeValue = 1;
    }

    void Update()
    {
        
    }

    // 触碰玩家
    private void OnTriggerEnter2D(Collider2D collision)
    {
        PlayerHealthChange p = Helper.GetPlayerByCollider2D(collision);
        if (p == null)
            return;
        if (healthChangeValue >= 0)
        {
            if (p.GetHealth == p.GetMaxHealth)
                return;
            p.HealthChange(healthChangeValue);
            Destroy(gameObject);
        }
        else
        {
            p.HealthChange(healthChangeValue);
            Destroy(gameObject);
        }
    }
}

PlayerHealthChange.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 人物血量变化
/// </summary>
public class PlayerHealthChange : MonoBehaviour
{
    float maxHealth;
    float health;
    public float GetHealth { get { return health; } }
    public float GetMaxHealth { get { return maxHealth; } }

    bool invincible;
    float invincibleTime = 2f;
    float invincibleTimer;

    void Start()
    {
        invincible = false;
        maxHealth = 5;
        health = 3;
        Debug.Log("health is " + health);
    }

    void Update()
    {
        if (invincible)
        {
            invincibleTimer -= Time.deltaTime;
            if (invincibleTimer <= 0)
            {
                ChangeToVincible();
            }
        }
    }

    public void HealthChange(float value)
    {
        if (value >= 0)
        {
            Debug.Log(health + " to " + Mathf.Clamp(health + value, 0, maxHealth));
            health = Mathf.Clamp(health + value, 0, maxHealth);
        }
        else if(invincible)
        {
            return;
        }
        else
        {
            Debug.Log(health + " to " + Mathf.Clamp(health + value, 0, maxHealth));
            health = Mathf.Clamp(health + value, 0, maxHealth);

            invincible = true;
            invincibleTimer = invincibleTime;
            Helper.SetOpaquenessOfGameObject(gameObject, 0.5f);
        }
    }

    private void ChangeToVincible()
    {
        invincible = false;
        Helper.SetOpaquenessOfGameObject(gameObject, 1f);
    }
}

上面运用了invincibleTimer -= Time.deltaTime来计时。

另外还有使用协程进行计时的方法(invoke听说不太好就不了解了):

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 人物血量变化
/// </summary>
public class PlayerHealthChange : MonoBehaviour
{
    float maxHealth;
    float health;
    public float GetHealth { get { return health; } }
    public float GetMaxHealth { get { return maxHealth; } }

    bool invincible;
    float invincibleTime = 2f;

    void Start()
    {
        invincible = false;
        maxHealth = 5;
        health = 3;
        Debug.Log("health is " + health);
    }

    void Update()
    {

    }

    // 加血时检查是否满血
    // 扣血后变为无敌状态,角色变为半透明,invincibleTime后恢复
    public void HealthChange(float value)
    {
        if (value >= 0)
        {
            Debug.Log(health + " to " + Mathf.Clamp(health + value, 0, maxHealth));
            health = Mathf.Clamp(health + value, 0, maxHealth);
        }
        else if(invincible)
        {
            return;
        }
        else
        {
            Debug.Log(health + " to " + Mathf.Clamp(health + value, 0, maxHealth));
            health = Mathf.Clamp(health + value, 0, maxHealth);

            invincible = true;
            Helper.SetOpaquenessOfGameObject(gameObject, 0.5f);
            StartCoroutine(Timer(invincibleTime));
        }
    }

    // second秒后运行ChangeToVincible()
    public IEnumerator Timer(float second)
    {
        while (second >= 0)
        {
            second -= 1f;
            if (second < 0)
            {
                ChangeToVincible();
                yield break;//停止协程
            }
            else
            {
                yield return new WaitForSeconds(1);// 等待 1 秒
            }
        }
    }

    // 变为非无敌状态
    private void ChangeToVincible()
    {
        invincible = false;
        Helper.SetOpaquenessOfGameObject(gameObject, 1f);
    }
}


猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/106950695