Unity-飞行射击实例的代码

花了一天的时间,照着官方的说明将spaceshoot这个DEMO撸了一遍,实现了一个简单飞行射击游戏应有的小功能,本想着用Unet这个组件把这个游戏做成一个联网的,无奈只能实现飞机运动之间的同步,其余部分画面都是不同步的。等经过进一步的学习之后我会再把这个DEMO进行完善。
接下来就分析一下这个DEMO的各个游戏对象与组件的关系。
1.场景:这个飞行射击游戏只有需要一个场景,一张用图片来做背景的星空图,一些粒子效果来模拟星星。
2.游戏对象:1.1玩家飞机:用WASD来进行控制,移动有范围限制,鼠标左键开火,撞到子弹,陨石,敌机会爆炸并附带音效;
1.2 陨石:在玩家上方随机生成并向下移动并具有旋转,离开边界范围会自动销毁,被子弹击中会爆炸,撞击到玩家飞机会爆炸并附带音效
1.3 敌机:在玩家上方随机生成并向下移动,并且可以开火,被子弹击中会爆炸,与玩家飞机相撞会爆炸,超出边界范围会销毁
1.4 子弹:可以由玩家和敌机生成,在Z轴上具有一定的速度,遇见玩家,陨石,敌机,进行爆炸并附带音效,超过生命周期会销毁
3.UI界面:需要一个计分板,玩家死亡后的结束游戏提示,和按R重新开始提示

脚本:
3.1玩家控制脚本

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
[System.Serializable]public class Boundary
{
    public float xMin,zMin,xMax,zMax;//这是设定玩家运动的边界范围


}
public class playercontroller : MonoBehaviour {
    public float speed;//移动速度
    public Boundary boundary;//边界
    public float tilt = 4;//旋转速度
    public float fireRate = 0.2f;//开或延迟
    public GameObject shot;//子弹对象

    public Transform shotspawn;//子弹生成地点
    private float nextfire = 0;//开火间隔

    // Use this for initialization
    void Update () {
        //if (isLocalPlayer) {
            if (Input.GetButton ("Fire1") && Time.time > nextfire) {//按下鼠标左键并且时间大于开火间隔
                nextfire = Time.time + fireRate;//更新最近开火时间
                Instantiate (shot, shotspawn.position, shotspawn.rotation); //生成子弹对象
                GetComponent ().Play ();//播放射击音效
            }
        //}
    }

    // Update is called once per frame
    void FixedUpdate () {
        //if (isLocalPlayer) {
            float moveHorizontal = Input.GetAxis ("Horizontal");//获得水平输入值
            float moveVertical = Input.GetAxis ("Vertical");//获得竖直方向上的输入值
            Vector3 movement = new Vector3 (moveHorizontal, 0, moveVertical);//定义一个三维变量用于储存玩家进行的移动操作
            Rigidbody rb = GetComponent ();
            if (rb != null) {
                rb.velocity = movement * speed;//设定刚体在某方向上的速度
                rb.position = new Vector3 (Mathf.Clamp (rb.position.x, boundary.xMin, boundary.xMax), 0, Mathf.Clamp (rb.position.z, boundary.zMin, boundary.zMax));//更新位置,并且处在设定范围内
                rb.rotation = Quaternion.Euler (0, 0, rb.velocity.x * -tilt);//计算旋转,因为Z轴上的旋转逆时针为正值,所以假设向左移动,X轴上的速度为负值,这时需要乘以一个负的旋转速度来实现
            }



        }
    //}



}

3.2敌对物体移动与旋转位置随机化脚本

//设定移动速度
using UnityEngine;
using System.Collections;

public class Mover : MonoBehaviour {

    public float speed;

    void Start ()
    {
        GetComponent().velocity = transform.forward * speed;//设定Z轴上的速度
    }
}
//随机旋转速度
using UnityEngine;
using System.Collections;

public class RandomRatator : MonoBehaviour {
    public float tumble;//旋转速度
    void Start () {
        GetComponent ().angularVelocity = Random.insideUnitSphere * tumble;//随机化欧拉角的速度

    }
}

3.3销毁游戏对象的方法脚本:超出边界,碰撞,超过生命周期

//按时销毁
using UnityEngine;
using System.Collections;

public class DestroyByTime : MonoBehaviour {

    public float lifeTime=2.0f;//设定生命周期为2S
    void Start () {
        Destroy (gameObject, lifeTime);//指定时间后销毁游戏对象
    }

}
//超过边界销毁
using UnityEngine;

using System.Collections;

public class DestoyByBoundary : MonoBehaviour
{
    void OnTriggerExit (Collider other) //离开触发器
    {
        Destroy(other.gameObject);//销毁游戏对象
    }
}
//碰撞销毁
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class DestroyByContact : MonoBehaviour {
    public int scoreValues;//本物体被击杀分数
    private GameController gameController1;//游戏控制对象
    public GameObject explosion;//爆炸粒子效果
    public GameObject playerExplosion;//玩家爆炸粒子效果

    void OnTriggerEnter(Collider other)//进入触发器
    {

            if (other.tag == "Boundary" || other.tag == "Enemy")//如果是边界或敌机就不爆炸,避免误伤
                return;
            Instantiate (explosion, transform.position, transform.rotation);
            if (other.tag == "Player") {//撞到玩家

                Instantiate (playerExplosion, other.transform.position, other.transform.rotation);//播放玩家的爆炸动画
                gameController1.gameOver ();//游戏结束,进入重置画面
            }
            gameController1.addScore (scoreValues);//增加分数
            Destroy (other.gameObject);//删除对方游戏对象
            Destroy (gameObject);//自我删除

    }

    void Start ()
    {

        GameObject gameControllerObject = GameObject.FindGameObjectWithTag ("GameController");//获得游戏控制器对象
        if (gameControllerObject != null)
        {
            gameController1 = gameControllerObject.GetComponent ();//初始化游戏控制组件
        }
        if (gameController1 == null)
        {
            Debug.Log ("Cannot find 'GameController' script");
        }
    }
}
//玩家爆炸脚本
using UnityEngine;
using System.Collections;

public class player_explosion : MonoBehaviour {
    private GameController gameController1;
    public GameObject playerExplosion;
    // Use this for initialization
    void Start () {
        GameObject gameControllerObject = GameObject.FindGameObjectWithTag ("GameController");
        if (gameControllerObject != null)
        {
            gameController1 = gameControllerObject.GetComponent ();
        }
        if (gameController1 == null)
        {
            Debug.Log ("Cannot find 'GameController' script");
        }
    }

      void OnTriggerEnter(Collider other)
    {

        if (other.tag == "Boundary"||other.tag=="Player")//遇到边界或其他玩家不爆炸
            return;
        if (other.tag == "Bullet") {//遇见子弹,因为陨石和敌机已经写了遇见玩家爆炸两者一起销毁的代码,所以只需要写子弹的
            Instantiate (playerExplosion, other.transform.position, other.transform.rotation);//播放爆炸动画
            gameController1.gameOver();//游戏结束
        }
        Destroy (other.gameObject);
        Destroy (gameObject);
    }

}

3.4游戏控制脚本

public class GameController : NetworkBehaviour {
    public Text scoreText;//计分板
    public Text gameOverText;//游戏结束提示
    public Text restartText;//重新开始提示
    public bool restart;//是否重置
    public bool gameover;//是否结束
    public int score;//初始分数

    public float starWait;//开始之前的等待时间
    public float waveWait;//每一波敌人之间的间隔
    public float spawnwait;//每个物体生成之间的间隔
    public float hazardCount;//一波敌人的数量
    public GameObject[] hazards;//敌对物体游戏对象数组
    public Vector3 spawnValues;//出生地点
    private Vector3 spawnPosition = Vector3.zero;
    private Quaternion spawnRotation;//出生旋转速度

    public void addScore(int newScoreValues){ 
        score += newScoreValues;
        UpdateScore ();//更新分数
    }

    public void gameOver()
    {
        gameover = true;
        gameOverText.text="游戏结束";

    }
    public void UpdateScore()
    {
        scoreText.text = "得分:" + score;
    }
    IEnumerator spawnWaves()//使用了协程的函数写法
    {
        yield return new WaitForSeconds (starWait);//游戏开始前的间隔

        while(true){
            if (gameover) {
                restartText.text="按R键重新开始游戏";
                restart = true;
                break;
            }
            for (int i = 0; i < hazardCount; i++) {

                GameObject hazard = hazards [Random.Range (0, hazards.Length)];
                Vector3 spawnPosition = new Vector3 (Random.Range (-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);//随机化物体X轴上的位置
                spawnRotation = Quaternion.identity;//没旋转之前的初始角度
                Instantiate (hazard, spawnPosition, spawnRotation);//生成物体
                yield return new WaitForSeconds (spawnwait);//生成下个物体之间的间隔
            }
            yield return new WaitForSeconds (waveWait);//每波敌人之间的间隔
        }

    }


    void Start () {
        gameOverText.text = "";
        restartText.text = "";
        gameover = false;
        restart = false;
        score = 0;
        UpdateScore ();//初始化各项数据
        StartCoroutine (spawnWaves ());//启动协程
    }
    void Update () {
        if (restart) {

            if (Input.GetKeyDown (KeyCode.R))
                Application.LoadLevel (Application.loadedLevel);//重新加载场景

        }
    }
}

3.5敌机移动与开火脚本

//敌机子弹射击
using UnityEngine;
using System.Collections;

public class enamyFire : MonoBehaviour {
    public GameObject shot;//子弹
    public Transform shotSpawn;//子弹生成地点
    public float delay;//函数延迟
    public float fireRate;//开火延迟

    void Start () {

        InvokeRepeating ("Fire", delay, fireRate);//重复调用一个函数,第一个参数是被调用函数名字。后面参数的意思是首先在delay延迟后调用这个函数,以后以fireRate的时间间隔调用这个函数

    }
    void Fire () {

        Instantiate (shot, shotSpawn.position, shotSpawn.rotation);
        GetComponent ().Play ();//生成子弹并播放音效
    }
}
//敌机飞行轨迹
using UnityEngine;
using System.Collections;

public class enemyMove : MonoBehaviour {

    public Done_Boundary boundary;//边界
    public float tilt;//旋转毒素
    public float dodge;//闪避速度
    public float smoothing;//平滑度
    public Vector2 startWait;//改变轨迹之前的时间间隔
    public Vector2 maneuverTime;//闪避时间
    public Vector2 maneuverWait;//闪避之间的间隔

    private float currentSpeed;//当前速度
    private float targetManeuver;//闪避目标

    void Start ()
    {
        currentSpeed = GetComponent().velocity.z;//获得Z轴上的速度
        StartCoroutine(Evade());//启动协程
    }

    IEnumerator Evade ()//协程的写法
    {
        yield return new WaitForSeconds (Random.Range (startWait.x, startWait.y));//等待给定区间内的随机时间
        while (true)
        {
            targetManeuver = Random.Range (1, dodge) * -Mathf.Sign (transform.position.x);//判断飞机的X轴正负,正或0返回1,负的放回-1
            yield return new WaitForSeconds (Random.Range (maneuverTime.x, maneuverTime.y));//随机等待时间,旋转时间
            targetManeuver = 0;//旋转速度清零
            yield return new WaitForSeconds (Random.Range (maneuverWait.x, maneuverWait.y));
        }
    }

    void FixedUpdate ()
    {
        float newManeuver = Mathf.MoveTowards (GetComponent().velocity.x, targetManeuver, smoothing * Time.deltaTime);//第一个参数是当前值,第二值是要移向的位置,第三个是最大速度,不会超过它
        GetComponent().velocity = new Vector3 (newManeuver, 0.0f, currentSpeed);//设定当前移动速度
        GetComponent().position = new Vector3
            (
                Mathf.Clamp(GetComponent().position.x, boundary.xMin, boundary.xMax), 
                0.0f, 
                Mathf.Clamp(GetComponent().position.z, boundary.zMin, boundary.zMax)//计算移动后的位置,在一个闭区间内,不能移出边界
            );

        GetComponent().rotation = Quaternion.Euler (0, 0, GetComponent().velocity.x * -tilt);//设定旋转速度
    }
}

你可能感兴趣的:(unity,实例,unity,游戏)