unity射擊遊戲:超萌射手(3)怪物生成和射擊邏輯

前言


本文由作者@zx一路飛奔出品,轉載請註明出處

文章地址:http://blog.csdn.net/u014735301/article/details/42705443

作者微博:http://weibo.com/u/1847349851


怪物生成


(1)刷新點

使用粒子系統,在地圖上創建刷新點



使用PoolManager插件,創建對象池




using UnityEngine;
using System.Collections;
using PathologicalGames;

public class Spawn : MonoBehaviour {

    public GameObject enemyPrefab;
    public float spawnTime = 3;
    //對象池
    SpawnPool spawnPool;
    void Start() {
        spawnPool = PoolManager.Pools["Spawn"];
        InvokeRepeating("SpawnEnemy", 2, spawnTime);
    }
    
    void SpawnEnemy() {
        spawnPool.Spawn(enemyPrefab.transform, new Vector3(transform.position.x, 0,transform.position.z), Quaternion.identity);
    }

}


(2)Navigation自動尋路

對場景進行NavMesh的烘焙 



在小怪身上掛上NavMeshAgent組件,實現對人物的追擊



using UnityEngine;
using System.Collections;

public class EnemyMove : MonoBehaviour {

    private NavMeshAgent agent;
    private Transform player;
    private Animator anim;

    void Awake() {
        agent = this.GetComponent<NavMeshAgent>();
        anim = this.GetComponent<Animator>();
    }
    void Start() {
        player = GameObject.FindGameObjectWithTag(Tags.player).transform;
    }
    
	
	// Update is called once per frame
	void Update () {
        if (Vector3.Distance(transform.position, player.position) < 0.2f) {
            agent.Stop();
            anim.SetBool("Move", false);
        } else {
            agent.SetDestination(player.position);
            anim.SetBool("Move", true);
        }
	}
}

(3)當小怪受到攻擊時,身上的粒子特效會執行,產生爆炸效果




using UnityEngine;
using System.Collections;

public class EnemyHealth : MonoBehaviour {

    public float hp = 100;
    private Animator anim;
   // private AnimationState stateInfo;
    private NavMeshAgent agent;
    private EnemyMove move;
    private CapsuleCollider capsuleCollider;
    private ParticleSystem particleSystem;
    public AudioClip dealthClip;
    private EnemyAttack enemyAttack;
    private bool isDead;
    void Awake() {
        anim = this.GetComponent<Animator>();
        agent = this.GetComponent<NavMeshAgent>();
        move = this.GetComponent<EnemyMove>();
        capsuleCollider = this.GetComponent<CapsuleCollider>();
        particleSystem = this.GetComponentInChildren<ParticleSystem>();
        enemyAttack = this.GetComponentInChildren<EnemyAttack>();
    }

    void Start() {
        isDead = false;
    }

    void Update() {
        //死亡時,執行死亡動畫,執行完畢後 dosomethiing
        if (this.hp <= 0) {       
            AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo(0);
            if (stateInfo.nameHash == Animator.StringToHash("Base Layer.Death")){
                if (stateInfo.normalizedTime >= 1.0f){
                    Debug.Log("死亡動畫播放結束");
                    Reset();
                    this.gameObject.SetActive(false);
                 }
            }   
        }
    }


    public void TakeDamage(float damage,Vector3 hitPoint) {
        if (this.hp <= 0) return;
        audio.Play();
        particleSystem.transform.position = hitPoint;
        particleSystem.Play();
        this.hp -= damage;
        if (this.hp <= 0) {
           Dead();
        }
    }

    //用這個方法來處理敵人死亡後的後事
    void Dead() {
        Debug.Log("dead");
        anim.SetBool("Dead", true);
        agent.enabled = false;
        move.enabled = false;
        capsuleCollider.enabled = false;
        AudioSource.PlayClipAtPoint(dealthClip, transform.position,0.5f);
        enemyAttack.enabled = false;
    }

    void Reset() {
        Debug.Log("reset");
        this.hp = 100;
        anim.SetBool("Dead", false);
        agent.enabled = true;
        move.enabled = true;
        capsuleCollider.enabled = true;
        enemyAttack.enabled = true;
    }

}

(4)小怪攻擊腳本


using UnityEngine;
using System.Collections;

public class EnemyAttack : MonoBehaviour {

    public float attack = 5;
    public float attackTime = 1;
    private float timer ;
    private EnemyHealth health;

    void Start() {
        timer = attackTime;
        health = this.GetComponent<EnemyHealth>();
    }

    public void OnTriggerStay(Collider col) {
        if (col.tag == Tags.player &&health.hp>0 ) {
            timer += Time.deltaTime;
            if (timer >= attackTime) {
                timer -= attackTime;
                col.GetComponent<PlayerHealth>().TakeDamage(attack);
            }
        }
    }

}

射擊邏輯


人物發射子彈,通過射線檢測到碰撞的物體,從而調用物體身上所掛腳本中的方法,達到射擊邏輯的控制 


  void Shoot() {
        light.enabled = true;
        particleSystem.Play();
        this.lineRenderer.enabled = true;
        lineRenderer.SetPosition(0, transform.position);
        //----------判斷射擊到敵人時的遊戲邏輯-----------
        Ray ray = new Ray(transform.position, transform.forward);
        RaycastHit hitInfo;
        if (Physics.Raycast(ray, out hitInfo)) {
            lineRenderer.SetPosition(1, hitInfo.point);
            //判斷當前的射擊有沒有碰撞到敵人
            if (hitInfo.collider.tag == Tags.enemy) {
                hitInfo.collider.GetComponent<EnemyHealth>().TakeDamage(attack,hitInfo.point);
            }

        } else {
            lineRenderer.SetPosition(1, transform.position + transform.forward * 100);
        }
        //播放射擊音效
        audio.Play();

        Invoke("ClearEffect", 0.05f);
    }


人物受到攻擊時


using UnityEngine;
using System.Collections;

public class PlayerHealth : MonoBehaviour {

    public float hp = 1000;
    public float smoothing = 5;
    public SkinnedMeshRenderer bodyRenderer;

    private Animator anim;
    private PlayerMove playerMove;
    private PlayerShoot playerShoot;

    void Awake() {
        anim = this.GetComponent<Animator>();
        this.playerMove = this.GetComponent<PlayerMove>();
        //bodyRenderer = transform.Find("Player").renderer as SkinnedMeshRenderer;
        playerShoot = this.GetComponentInChildren<PlayerShoot>();
    }
    void Update() {

        bodyRenderer.material.color = Color.Lerp(bodyRenderer.material.color, Color.white, smoothing * Time.deltaTime);
       // bodyRenderer.material.color = Color.white;
        
    }

    public void TakeDamage(float damage) {
        Debug.Log("玩家收到啦傷害");
        if (hp <= 0) return;
        this.hp -= damage;
        bodyRenderer.material.color = Color.red;
        if (this.hp <= 0) {
            anim.SetBool("Dead", true);
            Dead();
        }

    }

    void Dead() {
        this.playerMove.enabled = false;
        this.playerShoot.enabled = false;
    }

}

總結

至此,遊戲demo大致就做出來了,通過虛擬手柄,點擊射擊按鈕發射子彈來攻擊不斷從刷新點出來的小怪。

之後可以增加UI界面,實現分數顯示等等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章