天天看点

Unity实例开发-太空射手

此案例学习自漠刀凡尘 

传送门:

太空射手

运行结果:

Unity实例开发-太空射手

脚本:

BGScroll:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BGScroll : MonoBehaviour {
    public float scrollSpeed; 																	//背景图片滚动速度
    public float tileSizeZ; 																	//滚动长度
    private Vector3 startPosition; 																//记录初始变量 

    void Start () {
	startPosition = transform.position;	
    }

    void Update () {
	float newPosition = Mathf.Repeat (Time.time * scrollSpeed, tileSizeZ); 					//求Time.time * scrollSpeed % tileSizeZ
	transform.position = startPosition + Vector3.forward * newPosition;
    }
}
           

DestroyByBoundary:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DestroyByBoundary : MonoBehaviour {

    // Use this for initialization
    void Start () {
		
    }
	
    // Update is called once per frame
    void Update () {
		
    }

    private void OnTriggerExit(Collider other)
    {
	//与Boundary发生碰撞的直接销毁
	Destroy (other.gameObject);
    }
}
           

DestroyByContact:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DestroyByContact : MonoBehaviour {
    public GameObject explosion;   													//小行星爆炸特效
    public GameObject explosion_player; 											//玩家飞船爆炸特效
    public int scoreValue;															//击毁获得的分值
    private GameController gameController;

    void Start()
    {
	GameObject gameControllerObj = GameObject.FindGameObjectWithTag ("GameController");
	if (gameControllerObj)
	    gameController = gameControllerObj.GetComponent<GameController> ();
	else
	    Debug.Log ("Not find 'GameController' script");
    }
    //碰撞检测的回调函数,需要勾选 is Trigger选项
    void OnTriggerEnter(Collider other)
    {
	//当是敌人或者边界时,不计算碰撞
	if (other.tag == "Enemy" || other.tag == "Boundary")
	    return;
	if (explosion) 
	    Instantiate (explosion, transform.position, transform.rotation);        //实例化特效
	if (other.tag == "Player" && explosion_player) {
	    Instantiate (explosion_player, transform.position, transform.rotation);
	    gameController.GameOver ();
	}
	//分数递增
	gameController.AddScore (scoreValue);
	//销毁特效
	Destroy (other.gameObject);
	Destroy (gameObject);
    }
}
           

DestroyByTime:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DestroyByTime : MonoBehaviour {
    public float lifeTime;     			//延续多少秒后销毁
    // Use this for initialization
    void Start () {
        Destroy (gameObject, lifeTime);
    }
	
    // Update is called once per frame
    void Update () {
		
    }
}
           

EvasiveManeuver:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EvasiveManeuver : MonoBehaviour {
    public Boundary boundary;														//边界
    public float tilt;																//翻转度
    public float dodge;     
    public float smoothing;															//平滑度
    public Vector2 StartWait;														//刚开始等待时间
    public Vector2 ManeuverTime;													//规避时间
    public Vector2 ManeuverWait;													//距离下次规避需要等待时间

    private float currentSpeed;    													//记录z轴的速度
    private float targetManeuver; 													//获得x轴目标速度
    private Rigidbody rb;

    void Start()
    {
	rb = GetComponent<Rigidbody> ();
	currentSpeed = rb.velocity.z;
	StartCoroutine (Evade());
    }
    //规避
    IEnumerator Evade()
    {
	//首先等待一段时间
	yield return new WaitForSeconds (Random.Range (StartWait.x, StartWait.y));
	while (true) {
	    targetManeuver = Random.Range (1, dodge) * -Mathf.Sign (rb.position.x);
	yield return new WaitForSeconds (Random.Range (ManeuverTime.x, ManeuverTime.y));
	    //目标速度归0
	targetManeuver = 0;
	yield return new WaitForSeconds (Random.Range (ManeuverWait.x, ManeuverWait.y));
        }
    }

    void FixedUpdate()
    {
         //改变rb.velocity.x向targetManeuver靠近  smoothing * Time.deltaTime为应用到该值的最大变化
         float newManeuver = Mathf.MoveTowards (rb.velocity.x, targetManeuver, smoothing * Time.deltaTime);
	 rb.velocity = new Vector3 (newManeuver, 0.0f, currentSpeed);
	 rb.position = new Vector3
	 (
	    Mathf.Clamp(rb.position.x, boundary.xMin, boundary.xMax),
	    0.0f,
	    Mathf.Clamp(rb.position.z, boundary.zMin, boundary.zMax)
	 );
	 rb.rotation = Quaternion.Euler (0.0f, 0.0f, rb.velocity.x * -tilt);
    }
}
           

GameController:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class GameController : MonoBehaviour {
    public GameObject[] hazards; 						    //敌人预制体
    public Vector3 spawnValue;   						    //产生敌人位置最大值
    public long hazardCnt;							    //每波敌人的数目
    public float startWait;							    //生成敌人之前需要等待的时间
    public float waveWait;							   //每个敌人生成之间的时间间隔
    public float spawnWait;							   //每波敌人的间隔
    public Text gameOverText;   						    //结束文本
    public Text scoreText;							    //分数文本
    public Text restartText;							    //重新开始文本
    private int score; 								
    //分数
    private bool gameOver; 							    //是否游戏结束
    private bool restart;  							    //是否出现重新开始

    // Use this for initialization
    void Start () {
        StartCoroutine (SpawnWaves());
	score = 0;
	gameOver = false;
	restart = false;
	gameOverText.text = "";
	restartText.text = "";
	UpdateScore ();
    }

    // Update is called once per frame
    void Update () {
	//按下R键重新加载场景
	if (restart && Input.GetKeyDown (KeyCode.R))
	    SceneManager.LoadScene (SceneManager.GetActiveScene ().buildIndex);
    }
    //敌人的生成
    IEnumerator SpawnWaves()
    {
        yield return new WaitForSeconds (startWait);
	while (true) {
	    for (int i = 0; i < hazardCnt; ++i) {
	        GameObject hazard = hazards [Random.Range (0, hazards.Length)];
	        Vector3 spawnPosition = new Vector3 (
                    Random.Range (-spawnValue.x, spawnValue.x),
                    spawnValue.y,
	            spawnValue.z
	        );
                Instantiate (hazard, spawnPosition, Quaternion.identity);
	        yield return new WaitForSeconds (spawnWait);
            }
            if (gameOver) {
	         restart = true;
	         restartText.text = "Press 'R' for respart.";
	         break;
	    }
	    yield return new WaitForSeconds (waveWait);
         }
    }
    //分数更新
    private void UpdateScore()
    {
        scoreText.text = "Score:" + score.ToString ();
    }
    //分数增加
    public void AddScore(int newScore)
    {
        score += newScore;
	UpdateScore();
    }
    //游戏结束
    public void GameOver()
    {
        gameOver = true;
	gameOverText.text = "Game Over!"; 
    }
}
           

Mover:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Mover : MonoBehaviour {
    public float speed; 							//速度
    private Rigidbody rb;

    // Use this for initialization
    void Start () {
	rb = GetComponent<Rigidbody> ();
	rb.velocity = Vector3.forward * speed;
    }
	
    // Update is called once per frame
    void Update () {
		
    }
}
           

PlayerControl:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
//边界
public class Boundary
{
    public float xMin, xMax, zMin, zMax;
}

public class PlayerControl : MonoBehaviour {
    public float speed;								   //移动速度
    public Boundary boundary;
    public float tilt; 								
    //倾斜量
    public GameObject shot; 							
    //子弹
    public Transform shotSpawn; 						    //获取子弹挂载点的位置信息
    public float fireRate; 							    //子弹发射速率
    private float nextFire; 							    //判断是否可以进行下一颗子弹发射
    private AudioSource audioSrc;						    //音乐组件

    // Use this for initialization
    void Start () {
	audioSrc = GetComponent<AudioSource> ();
    }
	
    // Update is called once per frame
    void Update () {
	if (Input.GetButton ("Fire1") && Time.time >= nextFire) {
	    nextFire = Time.time + fireRate;
	    Instantiate (shot, shotSpawn.position, shotSpawn.rotation);
	    //音乐播放
	    audioSrc.Play ();
	}
    }

    void FixedUpdate()
    {
	//获取下列默认轴: “Horizontal” 和“Vertical” 映射于控制杆、A、W、S、D和箭头键(方向键)。 
	float moveHorizontal = Input.GetAxis ("Horizontal");
	float moveVertical = Input.GetAxis ("Vertical");

	Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical); 
	//设定刚体速度
	GetComponent<Rigidbody>().velocity = movement * speed;
	//限制运动范围
	GetComponent<Rigidbody> ().position = new Vector3 (
		    Mathf.Clamp(GetComponent<Rigidbody>().position.x, boundary.xMin, boundary.xMax),
	            0.0f,
		    Mathf.Clamp(GetComponent<Rigidbody>().position.z, boundary.zMin, boundary.zMax)
		);
	 //返回一个旋转角,绕x轴旋转x度,绕y轴旋转y度,绕z轴旋转z度。
	GetComponent<Rigidbody>().rotation = Quaternion.Euler (0.0f, 0.0f, GetComponent<Rigidbody>().velocity.x * -tilt);
    }
}
           

RandomRotator:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RandomRotator : MonoBehaviour {
	public float tumble; 											//翻滚速度
	private Rigidbody rb;

	// Use this for initialization
	void Start () {
		rb = GetComponent<Rigidbody> ();
		//改变刚体的角速度变量
		rb.angularVelocity = Random.insideUnitSphere * tumble; 		//随机返回单位球内任意一点
	}
	
	// Update is called once per frame
	void Update () {
		
	}
}
           

WeaponController:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WeaponController : MonoBehaviour {
	public GameObject shot;
	public Transform shotSpawn;
	public float shotRate;
	public float delay; 													//实例化敌机后多久发射子弹
	private AudioSource audioSrc;
	// Use this for initialization
	void Start () {
		//在delay秒调用Fire方法,以后每过shotRate秒重新调用Fire方法
		InvokeRepeating ("Fire", delay, shotRate);
		audioSrc = GetComponent<AudioSource> ();
	}
	
	// Update is called once per frame
	void Update () {
		
	}
	//发射子弹
	private void Fire()
	{
		Instantiate (shot, shotSpawn.position, shotSpawn.rotation);
		audioSrc.Play ();
	}
}
           

继续阅读