unity射击游戏:超萌射手(3)怪物生成和射击逻辑

前言


本文由作者@zx一路飞奔出品,转载请注明出处

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

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


怪物生成


(1)刷新点

使用粒子系统,在地图上创建刷新点


unity射击游戏:超萌射手(3)怪物生成和射击逻辑_第1张图片


使用PoolManager插件,创建对象池


unity射击游戏:超萌射手(3)怪物生成和射击逻辑_第2张图片

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的烘焙 


unity射击游戏:超萌射手(3)怪物生成和射击逻辑_第3张图片


在小怪身上挂上NavMeshAgent组件,实现对人物的追击


unity射击游戏:超萌射手(3)怪物生成和射击逻辑_第4张图片


using UnityEngine;
using System.Collections;

public class EnemyMove : MonoBehaviour {

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

    void Awake() {
        agent = this.GetComponent();
        anim = this.GetComponent();
    }
    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)当小怪受到攻击时,身上的粒子特效会执行,产生爆炸效果


unity射击游戏:超萌射手(3)怪物生成和射击逻辑_第5张图片


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();
        agent = this.GetComponent();
        move = this.GetComponent();
        capsuleCollider = this.GetComponent();
        particleSystem = this.GetComponentInChildren();
        enemyAttack = this.GetComponentInChildren();
    }

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

    public void OnTriggerStay(Collider col) {
        if (col.tag == Tags.player &&health.hp>0 ) {
            timer += Time.deltaTime;
            if (timer >= attackTime) {
                timer -= attackTime;
                col.GetComponent().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().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();
        this.playerMove = this.GetComponent();
        //bodyRenderer = transform.Find("Player").renderer as SkinnedMeshRenderer;
        playerShoot = this.GetComponentInChildren();
    }
    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界面,实现分数显示等等。

你可能感兴趣的:(【unity3d】【项目】)