Unity5.x制作FPS游戏
发表于2017-05-13
和RPG游戏一样,FPS游戏(第一人称设计游戏)也是开发者喜欢开发的游戏类型之一,下面就教给大家使用Unity5.x制作FPS游戏的方法,具体会从枪支的创建、敌人的AI逻辑和目标靶的制作这三面讲解主要技术点。
一.枪支的创建
在GamePlaying.cs中接收鼠标左击事件,当触发后机枪将进行开火,播放音效,抖动,子弹实例化的状态
GamePlaying.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | using UnityEngine; using System.Collections; public class GamePlaying : MonoBehaviour { //使得一定时间开始开枪 public float firingInterval=2.0f; // Use this for initialization void Start () { } // Update is called once per frame void Update () { if (firingInterval > 0) { firingInterval -= Time.deltaTime; } else { if (Input.GetMouseButtonDown(0)) { PlayerCharacter.player.Fire(); } } } } |
PlayerCharater.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | using UnityEngine; using System.Collections; public class PlayerCharacter : MonoBehaviour { public static PlayerCharacter player; public GameObject weapon; public GameObject bullet; public Transform firePosition; public EllipsoidParticleEmitter particleFire; public AudioSource audio; // Use this for initialization void Start () { //单例模式 PlayerCharacter.player = this ; } // Update is called once per frame void Update () { } public void Fire() { //机枪运动 this .weapon.GetComponent ().CrossFade ( "Fire" ); this .weapon.GetComponent ().Play ( "Fire" ,PlayMode.StopAll); //实例化子弹和火焰 GameObject.Instantiate (bullet,firePosition.position,weapon.transform.rotation); GameObject.Instantiate (particleFire,firePosition.position,weapon.transform.rotation); //播放抢声 this .audio.Play (); } } |
二.敌人的AI逻辑
在这里简单模拟了敌人AI逻辑:
当主角靠近敌人一段距离时,敌人将开始面朝主角,朝主角方向移动,然当到达目的地后开始对主角进行攻击
当主角远离敌人时,敌人将的随机的获得目的地,并移动到目的地,到达后又将获取新的随机目的地
代码如下:
EnemyAI.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | using UnityEngine; using System.Collections; public class EnemyAI : MonoBehaviour { public Transform hero; private int heroHP=5; //获取寻路组件 private NavMeshAgent nav; //获取动作组件 private Animation ani; //获取声音组件 private AudioSource aud; //自动寻路范围 private float range=40.0f; //寻路目的的 Vector3 destination; //是否处于寻路状态 private bool isLoading= false ; //是否死亡 private bool isDie= false ; //死亡状态 private float lifeTime=2.0f; // Use this for initialization void Start () { ani = this .transform.GetComponent (); nav = this .transform.GetComponent(); aud = this .transform.GetComponent (); } // Update is called once per frame void Update () { if (isDie) { if (lifeTime>=0.0) { lifeTime-=Time.deltaTime; } else { Destroy( this .gameObject); } } else { if (Vector3.Distance (hero.position, this .transform.position) < 25.0f) { isLoading= false ; ani.CrossFade( "walk1" ); nav.SetDestination (hero.position); if (Vector3.Distance (hero.position, this .transform.position) < 10.0f) { aud.Play(); ani.CrossFade( "attack1" ); } } else { if (!isLoading) { Vector3 pos= new Vector3(Random.Range(-range,range),0,Random.Range(-range,range)); destination=pos+ this .transform.position; ani.CrossFade( "walk2" ); nav.SetDestination(destination); isLoading= true ; } if (Vector3.Distance( this .transform.position,destination)<6.0f) { ani.CrossFade( "idle" ); isLoading= false ; } } } } public void ReduceHP() { this .heroHP -= 1; if (heroHP == 0) { if (!aud.isPlaying) { aud.Play(); } nav.Stop(); ani.CrossFade( "die" ); isDie= true ; } } } |
三.目标靶的制作
创建一个Sprite的2D游戏对象,将其拖动在屏幕中央
使用射线碰撞的方法检测是否瞄准了敌人
PhysicalCollision.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | using UnityEngine; using System.Collections; public class PhysicalCollision : MonoBehaviour { public GameObject target; //物理碰撞检测 private RaycastHit hit; // Use this for initialization void Start () { target.transform.GetComponent().color=Color.green; } // Update is called once per frame void Update () { QueryEnemy (); } void QueryEnemy() { Ray ray = Camera.main.ScreenPointToRay ( new Vector2(Screen.width/2,Screen.height/2)); if (Physics.Raycast(ray, out hit)) { if (hit.collider.CompareTag( "Enemy" )) { target.transform.GetComponent().color=Color.red; if (Input.GetMouseButtonDown(0)) { hit.collider.GetComponent().ReduceHP(); } } else { target.transform.GetComponent().color=Color.green; } } } } |