[Unity2D]CharacterController2D例子:炸弹包和医药包的实现

    首先需要先实现炸弹包和医药包的组合物体,实现下落和着落两个动画效果。

炸弹包

    下落动画为实现物体左右摆动的效果,着陆动画为降落伞收起的效果,这个通过Scale来实现,使用land参数来控制两个动画的切换。

组合的父对象添加刚体使其具有重力的效果。

炸弹添加了两个脚本,BombPickup.cs控制炸弹包碰撞的逻辑(被捡起),Bomb.cs控制炸弹被放下触发爆炸的逻辑。

using UnityEngine;
using System.Collections;

public class BombPickup : MonoBehaviour
{
    public AudioClip pickupClip;        // 音效


    private Animator anim;                // 动画管理器对象
    private bool landed = false;        // 是否已经着陆

    void Awake()
    {
        // 获取根目录的动画管理器
        anim = transform.root.GetComponent<Animator>();
    }

    void OnTriggerEnter2D (Collider2D other)
    {
        // 如果是玩家碰撞到
        if(other.tag == "Player")
        {
            // 播放捡到武器的音效
            AudioSource.PlayClipAtPoint(pickupClip, transform.position);

            // 增加玩家所拥有的炸弹数量
            other.GetComponent<LayBombs>().bombCount++;

            // 销毁当前的物体
            Destroy(transform.root.gameObject);
        }
        // 如果是着陆
        else if(other.tag == "ground" && !landed)
        {
            // 播放着陆动画
            anim.SetTrigger("Land");
            transform.parent = null;
            gameObject.AddComponent<Rigidbody2D>();
            landed = true;        
        }
    }
}
using UnityEngine;
using System.Collections;
// 炸弹脚本
public class Bomb : MonoBehaviour
{
    public float bombRadius = 10f;            // 爆炸的范围
    public float bombForce = 100f;            // 爆炸的力度
    public AudioClip boom;                    // 爆炸音效
    public AudioClip fuse;                    // 点燃导火线音效
    public float fuseTime = 1.5f;
    public GameObject explosion;            // 表示爆炸闪光的材质物体

    private LayBombs layBombs;                // 玩家的武器脚本
    private PickupSpawner pickupSpawner;    // 武器管理器脚本
    private ParticleSystem explosionFX;        // 爆炸的粒子效果

    void Awake ()
    {
        //根据tag 查找hierarchy里面的爆炸粒子效果
        explosionFX = GameObject.FindGameObjectWithTag("ExplosionFX").GetComponent<ParticleSystem>();
        // 根据名字查找hierarchy里面的武器管理器
        pickupSpawner = GameObject.Find("pickupManager").GetComponent<PickupSpawner>();
        //根据tag 查找hierarchy里面的爆炸粒子效果
        if(GameObject.FindGameObjectWithTag("Player"))
            // 获取LayBombs脚本
            layBombs = GameObject.FindGameObjectWithTag("Player").GetComponent<LayBombs>();
    }

    void Start ()
    {
        // transform.root == transform表示当前的物体没有父对象,那么这当前的炸弹是玩家自己放的
        if(transform.root == transform)
            StartCoroutine(BombDetonation());
    }

    IEnumerator BombDetonation()
    {
        // 播放音效
        AudioSource.PlayClipAtPoint(fuse, transform.position);

        // 等待两秒
        yield return new WaitForSeconds(fuseTime);

        // 引爆炸弹
        Explode();
    }

    public void Explode()
    {    
        // 表示炸弹已经放下,玩家可以继续放炸弹
        layBombs.bombLaid = false;

        // 武器管理器可以继续投放新的炸弹武器或者医药包
        pickupSpawner.StartCoroutine(pickupSpawner.DeliverPickup());

        // 使用2D射线在爆炸的范围找到所有的敌人物体
        Collider2D[] enemies = Physics2D.OverlapCircleAll(transform.position, bombRadius, 1 << LayerMask.NameToLayer("Enemies"));

        // 遍历敌人的碰撞体
        foreach(Collider2D en in enemies)
        {
            // 查找刚体
            Rigidbody2D rb = en.rigidbody2D;
            if(rb != null && rb.tag == "Enemy")
            {
                // 设置敌人的血条为0
                rb.gameObject.GetComponent<Enemy>().HP = 0;

                // 计算炸弹到敌人的向量
                Vector3 deltaPos = rb.transform.position - transform.position;

                // normalized规范化向量的长度为1 计算力度
                Vector3 force = deltaPos.normalized * bombForce;
                rb.AddForce(force);
            }
        }

        // 爆炸的粒子效果
        explosionFX.transform.position = transform.position;
        explosionFX.Play();

        // 初始化爆炸的闪光物体
        Instantiate(explosion,transform.position, Quaternion.identity);

        // 播放音效
        AudioSource.PlayClipAtPoint(boom, transform.position);

        // 销毁炸弹
        Destroy (gameObject);
    }
}

 

    炸弹包和医药包的组合对象实现之后,则将其保存为预设件Prefab。使用管理器来生成。

using UnityEngine;
using System.Collections;

public class PickupSpawner : MonoBehaviour
{
    public GameObject[] pickups;                // Array of pickup prefabs with the bomb pickup first and health second.
    public float pickupDeliveryTime = 5f;        // Delay on delivery.
    public float dropRangeLeft;                    // Smallest value of x in world coordinates the delivery can happen at.
    public float dropRangeRight;                // Largest value of x in world coordinates the delivery can happen at.
    public float highHealthThreshold = 75f;        // The health of the player, above which only bomb crates will be delivered.
    public float lowHealthThreshold = 25f;        // The health of the player, below which only health crates will be delivered.


    private PlayerHealth playerHealth;            // Reference to the PlayerHealth script.


    void Awake ()
    {
        // Setting up the reference.
        playerHealth = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerHealth>();
    }


    void Start ()
    {
        // Start the first delivery.
        StartCoroutine(DeliverPickup());
    }


    public IEnumerator DeliverPickup()
    {
        // Wait for the delivery delay.
        yield return new WaitForSeconds(pickupDeliveryTime);

        // Create a random x coordinate for the delivery in the drop range.
        float dropPosX = Random.Range(dropRangeLeft, dropRangeRight);

        // Create a position with the random x coordinate.
        Vector3 dropPos = new Vector3(dropPosX, 15f, 1f);

        // If the player's health is above the high threshold...
        if(playerHealth.health >= highHealthThreshold)
            // ... instantiate a bomb pickup at the drop position.
            Instantiate(pickups[0], dropPos, Quaternion.identity);
        // Otherwise if the player's health is below the low threshold...
        else if(playerHealth.health <= lowHealthThreshold)
            // ... instantiate a health pickup at the drop position.
            Instantiate(pickups[1], dropPos, Quaternion.identity);
        // Otherwise...
        else
        {
            // ... instantiate a random pickup at the drop position.
            int pickupIndex = Random.Range(0, pickups.Length);
            Instantiate(pickups[pickupIndex], dropPos, Quaternion.identity);
        }
    }
}

 放炸弹脚本:

using UnityEngine;
using System.Collections;

public class LayBombs : MonoBehaviour
{
    [HideInInspector]
    public bool bombLaid = false;        // Whether or not a bomb has currently been laid.
    public int bombCount = 0;            // How many bombs the player has.
    public AudioClip bombsAway;            // Sound for when the player lays a bomb.
    public GameObject bomb;                // Prefab of the bomb.


    private GUITexture bombHUD;            // Heads up display of whether the player has a bomb or not.


    void Awake ()
    {
        // Setting up the reference.
        bombHUD = GameObject.Find("ui_bombHUD").guiTexture;
    }


    void Update ()
    {
        // If the bomb laying button is pressed, the bomb hasn't been laid and there's a bomb to lay...
        if(Input.GetButtonDown("Fire2") && !bombLaid && bombCount > 0)
        {
            // Decrement the number of bombs.
            bombCount--;

            // Set bombLaid to true.
            bombLaid = true;

            // Play the bomb laying sound.
            AudioSource.PlayClipAtPoint(bombsAway,transform.position);

            // 初始化炸弹
            Instantiate(bomb, transform.position, transform.rotation);
        }

        // The bomb heads up display should be enabled if the player has bombs, other it should be disabled.
        bombHUD.enabled = bombCount > 0;
    }
}

 

posted on 2014-09-26 17:00  linzheng  阅读(1651)  评论(0)    收藏  举报

导航