概述
一、准备工作
1、第一步
添加飞船:导入包——新建场景并保存场景——删除Done——Models倒数第二个拖入Main场景并命名为player——Transform(设置reset)——加组件(Add Component—-physics—Rigidbody)不使用重力(Gravity)——加碰撞体Mesh Collider(Conver和inflate mesh都勾选)——碰撞体Material可以更换为材质少的——prefab里面的Engines最后一个拖给player
2、第二步
主相机和飞船方向一致:切换Main Camera——Rotation的X为90,position的Y,Z变大10,5——Clear Flags选择Solid Color,背景色变黑——投影projection设置正交orthographics(因为模型偏二维)Size变大为10
(projection 投影 orthographics 正交)
3、第三步
添加背景图片:设置承载对象(Create-3D-Quad四边形)重命名为background——删掉remove MeshColider——Rotation:X90——Textures第二排第7个拖给background——选择background让游戏进入播放状态(不能全屏播放)——不在播放状态选择Scale改为48.6,30,1,背景扩充了——如果有阴影,Shader-Standard-Unlit-Texture——背景置于模型下方Position的Y值改为-10——星星闪烁效果,Prefab-Starfield然后拖到层次面板——准备工作结束
(U3D第二个视频1:35:40开始总结)
二、飞船和子弹
1、第一步
NewBehaviourScript脚本代码初步,飞船可以上下左右移动
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour {
// Use this for initialization
public float speed=5.0f;
void Start () {
}
// Update is called once per frame
void Update () {
float moveH=Input.GetAxis("Horizontal");//获取水平方向
float moveV=Input.GetAxis("Vertical");//获取垂直方向
Vector3 movement= new Vector3(moveH, 0.0f, moveV);
GetComponent<Rigidbody>().velocity=movement*speed;//刚体属性有速度,就可以运动
}
}
2、第二步
NewBehaviourScript脚本代码补充,飞船不会跑出边界
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]//序列化,使得自己定义的类可以出现在面板
public class Boundary{
public float xMin,xMax,zMin,zMax;
}
public class NewBehaviourScript : MonoBehaviour {
// Use this for initialization
public float speed=5.0f;
public Boundary boundary;
void Start () {
}
// Update is called once per frame
void Update () {
float moveH=Input.GetAxis("Horizontal");//获取水平方向
float moveV=Input.GetAxis("Vertical");//获取垂直方向
Vector3 movement= new Vector3(moveH, 0.0f, moveV);
//GetComponent<Rigidbody>().velocity=movement*speed;//刚体属性有速度,就可以运动
Rigidbody rb=GetComponent<Rigidbody>();
if(rb!=null){
rb.velocity=movement*speed;
rb.position=new Vector3(Mathf.Clamp(rb.position.x,boundary.xMin,boundary.xMax),0.0f,Mathf.Clamp(rb.position.z,boundary.zMin,boundary.zMax));//介于最小值和最大值之间,以防越界
}
}
}
3、第三步
子弹的设置:创建一个空并命名为Bolt——让飞船不显示,为子弹添加刚体组件并去掉重力——承载纹理,加Quad四边形并重命名为VFX——将VFX拖给Bolt,删掉Mesh Collider——将VFX的Rotation90——Materials第一个拖给VFX——给Bolt添加碰撞体capsule collider——Is Trigger勾选,触发会有后续操作,Driection切换为Z轴——重新勾选player,写代码,新建脚本Mover——挂载给子弹-——将子弹设为预制体,将Bolt拖到下方层次面板
注:Instantiate (prefab, position, rotation)实例化可以自动产生子弹
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Mover : MonoBehaviour {
// Use this for initialization
public float speed=10.0f;
void Start () {
GetComponent<Rigidbody>().velocity=transform.forward*speed;//向正前方飞
}
// Update is called once per frame
void Update () {
}
}
4、第四步
添加一个空并命名为shotspawn拖给player——在第一个脚本继续写代码
查看发射键:Edit-Project Settings-Input 右方面板即可查看
Shot和ShotSpawn没有赋值,不会自动发射子弹,所以,将Bolt拖给Shot,将ShotSpawn拖给player展开面板右下方的ShotSpawn——按住左Ctrl或鼠标左键即可发射子弹
5、第五步
继续补充NewBehaviourScript代码,使飞船能够发射子弹,并且能够不断产生子弹
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]//序列化,使得自己定义的类可以出现在面板
public class Boundary{
public float xMin,xMax,zMin,zMax;
}
public class NewBehaviourScript : MonoBehaviour {
// Use this for initialization
public float speed=5.0f;
public Boundary boundary;
public float fireRate=0.5f;//子弹发射间隔时间
public GameObject shot;//表示子弹预制体
public GameObject shotSpawn;//表示位置和旋转角度
private float nextFire=0.0f;//表示子弹下次发射的时间
void Start () {
}
// Update is called once per frame
void Update () {
float moveH=Input.GetAxis("Horizontal");//获取水平方向
float moveV=Input.GetAxis("Vertical");//获取垂直方向
Vector3 movement= new Vector3(moveH, 0.0f, moveV);
//GetComponent<Rigidbody>().velocity=movement*speed;//刚体属性有速度,就可以运动
Rigidbody rb=GetComponent<Rigidbody>();
if(rb!=null){
rb.velocity=movement*speed;
rb.position=new Vector3(Mathf.Clamp(rb.position.x,boundary.xMin,boundary.xMax),0.0f,Mathf.Clamp(rb.position.z,boundary.zMin,boundary.zMax));//介于最小值和最大值之间,以防越界
}
if(Input.GetButton("Fire1")&&Time.time>nextFire)//从游戏开始到现在的时间大于下次开火时间
{
nextFire=Time.time+fireRate;
Instantiate(shot,shotSpawn.GetComponent<Transform>().position,shotSpawn.GetComponent<Transform>().rotation);//用来自动发射子弹
}
}
}
6、第六步
优化代码——重新拖shotSpawn——
射出边界后自动消失掉:添加一个Cube并命名为Boundary——position的Z设置为5,和主摄相机在一个平面——将scale的X和Z拖至铺满屏幕直至边界——Is trigger勾选——删掉Mesh Rrenderer,以免浪费资源——写代码——新建脚本命名为DestroyByRoundary
优化NewBehaviourScript代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]//序列化,使得自己定义的类可以出现在面板
public class Boundary{
public float xMin,xMax,zMin,zMax;
}
public class NewBehaviourScript : MonoBehaviour {
// Use this for initialization
public float speed=5.0f;
public Boundary boundary;
public float fireRate=0.5f;//子弹发射间隔时间
public GameObject shot;//表示子弹预制体
//public GameObject shotSpawn;//表示位置和旋转角度
public Transform shotSpawn;
private float nextFire=0.0f;//表示子弹下次发射的时间
void Start () {
}
// Update is called once per frame
void Update () {
float moveH=Input.GetAxis("Horizontal");//获取水平方向
float moveV=Input.GetAxis("Vertical");//获取垂直方向
Vector3 movement= new Vector3(moveH, 0.0f, moveV);
//GetComponent<Rigidbody>().velocity=movement*speed;//刚体属性有速度,就可以运动
Rigidbody rb=GetComponent<Rigidbody>();
if(rb!=null){
rb.velocity=movement*speed;
rb.position=new Vector3(Mathf.Clamp(rb.position.x,boundary.xMin,boundary.xMax),0.0f,Mathf.Clamp(rb.position.z,boundary.zMin,boundary.zMax));//介于最小值和最大值之间,以防越界
}
if(Input.GetButton("Fire1")&&Time.time>nextFire)//从游戏开始到现在的时间大于下次开火时间
{
nextFire=Time.time+fireRate;
//Instantiate(shot,shotSpawn.GetComponent<Transform>().position,shotSpawn.GetComponent<Transform>().rotation);//用来自动发射子弹
Instantiate(shot,shotSpawn.position,shotSpawn.rotation);
}
}
}
7、第七步
DestroyByBoundary代码挂载在Boundary
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 () {
}
void OnTriggerExit(Collider other){
Destroy(other.gameObject);//溢出触发器的操作,销毁子弹
}
}
三、小行星
添加小行星,随机产生,射中就爆炸销毁,飞船撞上小行星游戏结束
1、第一步
创建小行星:创建一个空命名为asteroid,用来承载——添加刚体组件,去掉使用重力,添加Capsule collide并勾选Is Triggerr——将Models里第一个拖给asteroid——小行星position的Z给10,direction改为Z轴
2、第二步
让小行星动起来:写代码——创建脚本代码RandomRotator——挂载给asteroid
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RandomRorator : MonoBehaviour {
// Use this for initialization
public float tumble=10.0f;//旋转系数
void Start () {
GetComponent<Rigidbody>().angularVelocity = Random.insideUnitSphere*tumble;//单位球体之间取随机值
}
// Update is called once per frame
void Update () {
}
}
3、第三步
小行星越转越慢:将Angular Drag设置为0
写代码,小行星和飞船碰撞后销毁:新建脚本代码DestroyByContact——DestroyByContact代码挂载在小行星上
给Boundary加标签——右上方Tag选择Boundary——写代码——Prefabs里Explosions第一个拖给asteroid右下方面板Destroy By Contac脚本的Explosion
将Prefabs里Explosions第3个拖给asteroid右下方面板Destroy By Contac脚本的Player Explosion
给player加标签——右上方Tag选择Player
DestroyByCotac初步代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DestroyByCotac : MonoBehaviour {
// Use this for initialization
//public GameObject explosion;//子弹和小行星碰撞
//public GameObject playerExplosion;//飞船和小行星碰撞
//public int scoreValue;
//private GameController gameController;
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnTriggerEnter(Collider other){
if (other.tag == "Boundary")
return;//如果是边界直接返回
Destroy (other.gameObject);//和小行星碰撞的,子弹或飞船
Destroy (gameObject);//小行星也销毁
print (other.name);//测试边界是否被销毁,看看other是谁,发现边界和小行星发生碰撞了
// Instantiate (explosion,transform.position,transform.rotation);//实例化
// if (other.tag == "Player") {
//
Instantiate (playerExplosion,other.transform.position,other.transform.rotation);//飞船爆炸实例化
// gameController.AddScore (scoreValue);
// gameController.GameOver ();
// }
}
}
4、第四步
优化代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DestroyByContact : MonoBehaviour {
// Use this for initialization
public GameObject explosion;//子弹和小行星碰撞
public GameObject playerExplosion;//飞船和小行星碰撞
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnTriggerEnter(Collider other){
if (other.tag == "Boundary")
return;//如果是边界直接返回
Destroy (other.gameObject);//和小行星碰撞的,子弹或飞船
Destroy (gameObject);//小行星也销毁
print (other.name);//测试边界是否被销毁,看看other是谁,发现边界和小行星发生碰撞了
Instantiate (explosion,transform.position,transform.rotation);//实例化
if (other.tag == "Player") {
Instantiate (playerExplosion,other.transform.position,other.transform.rotation);//飞船爆炸实例化,和子弹爆炸效果不同
}
}
}
5、第五步
让小行星能掉下:代码重用,将Mover脚本挂载在小行星asteroid上——speed给一个负值-5
小行星随机产生:将其做成预制体,实例化,让位置随机——将asteroid拖到下方prefab层次面板中,然后删掉原来的——create一个空的游戏对象,命名为GameController——Tag勾选GameController——新建脚本文件命名为GameController——写代码
将脚本GameController代码挂载在GameController上——将小行星预制体拖给右上方 hazard;——可以把小行星预制体重新拖到面板上找X和Z的临界值,也就是X最大Z最大值是多少——X是21.65,Z是13.89
GameController 代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour {
// Use this for initialization
public GameObject hazard;//障碍物,表示预制对象
//public int hazardCount;
private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0
public Vector3 spawnValues;//位置控制,给spawnPosition提供炮弹
private Quaternion spawnRotation;//四元素,旋转控制,更方便
void Start () {
SpawnWaves();//调用函数
}
// Update is called once per frame
void Update () {
}
void SpawnWaves(){
spawnPosition.x = Random.Range (-spawnValues.x,spawnValues.x);//取区间的随机值
spawnPosition.z = spawnValues.z;//Z方向值
spawnRotation = Quaternion.identity;//不发生旋转
Instantiate (hazard,spawnPosition,spawnRotation);//实例化
}
}
6、第六步
优化代码:产生批量小行星
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour {
// Use this for initialization
public GameObject hazard;//障碍物,表示预制对象
public int hazardCount;//产生小行星的数量
private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0
public Vector3 spawnValues;//位置控制,给spawnPosition提供炮弹
private Quaternion spawnRotation;//四元素,旋转控制,更方便
void Start () {
SpawnWaves();//调用函数
}
// Update is called once per frame
void Update () {
}
void SpawnWaves(){
for (int i = 0; i < hazardCount; i++) {
spawnPosition.x = Random.Range (-spawnValues.x,spawnValues.x);//取区间的随机值
spawnPosition.z = spawnValues.z;//Z方向值
spawnRotation = Quaternion.identity;//不发生旋转?
Instantiate (hazard,spawnPosition,spawnRotation);//实例化
}
}
}
7、第七步
赋给hazardCount一个值,运行
批量产生会彼此碰撞,所以间隔一段时间再产生就可以避免
优化GameController代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour {
// Use this for initialization
public GameObject hazard;//障碍物,表示预制对象
public int hazardCount;//产生小行星的数量
private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0
public Vector3 spawnValues;//位置控制,给spawnPosition提供炮弹
private Quaternion spawnRotation;//四元素,旋转控制,更方便
public float spawnWait;//等待时间
void Start () {
StartCoroutine(SpawnWaves ());//开启协程
}
// Update is called once per frame
void Update () {
}
IEnumerator SpawnWaves(){
for (int i = 0; i < hazardCount; i++) {
spawnPosition.x = Random.Range (-spawnValues.x,spawnValues.x);//取区间的随机值
spawnPosition.z = spawnValues.z;//Z方向值
spawnRotation = Quaternion.identity;//不发生旋转?
Instantiate (hazard,spawnPosition,spawnRotation);//实例化
yield return new WaitForSeconds (spawnWait);//产生一个后中断一段时间再产生
}
}
}
Spawn Wait赋0.5运行,产生小行星,解决问题
8、第八步
让小行星刚开始有一定的延迟,优化GameController代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour {
// Use this for initialization
public GameObject hazard;//障碍物,表示预制对象
public int hazardCount;//产生小行星的数量
private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0
public Vector3 spawnValues;//位置控制,给spawnPosition提供炮弹
private Quaternion spawnRotation;//四元素,旋转控制,更方便
public float spawnWait;//等待时间
public float startWait=1.0f;//刚开始有一定的延迟
void Start () {
StartCoroutine(SpawnWaves ());//开启协程
}
// Update is called once per frame
void Update () {
}
IEnumerator SpawnWaves(){
yield return new WaitForSeconds (startWait);//实现协程,打断时间
for (int i = 0; i < hazardCount; i++) {
spawnPosition.x = Random.Range (-spawnValues.x,spawnValues.x);//取区间的随机值
spawnPosition.z = spawnValues.z;//Z方向值
spawnRotation = Quaternion.identity;//不发生旋转?
Instantiate (hazard,spawnPosition,spawnRotation);//实例化
yield return new WaitForSeconds (spawnWait);//产生一个后中断一段时间再产生
}
}
}
9、第九步
产生多轮小行星:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour {
// Use this for initialization
public GameObject hazard;//障碍物,表示预制对象
public int hazardCount;//产生小行星的数量
private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0
public Vector3 spawnValues;//位置控制,给spawnPosition提供炮弹
private Quaternion spawnRotation;//四元素,旋转控制,更方便
public float spawnWait;//等待时间
public float startWait=1.0f;//刚开始有一定的延迟
public float waveWait = 2.0f;//一轮后的等待时间
void Start () {
StartCoroutine(SpawnWaves ());//开启协程
}
// Update is called once per frame
void Update () {
}
IEnumerator SpawnWaves(){
yield return new WaitForSeconds (startWait);//实现协程,打断时间
while (true){
for (int i = 0; i < hazardCount; i++) {
spawnPosition.x = Random.Range (-spawnValues.x,spawnValues.x);//取区间的随机值
spawnPosition.z = spawnValues.z;//Z方向值
spawnRotation = Quaternion.identity;//不发生旋转?
Instantiate (hazard,spawnPosition,spawnRotation);//实例化
yield return new WaitForSeconds (spawnWait);//产生一个后中断一段时间再产生
}
yield return new WaitForSeconds (waveWait);//产生多轮小行星
}
}
}
10、第十步
过一段时间后积累的东西被销毁:新建脚本代码命名为DestroyByTime
代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DestroyByTime : MonoBehaviour {
// Use this for initialization
public float lifetime=2.0f;
void Start () {
Destroy (gameObject,lifetime);//过一段时间再销毁
}
// Update is called once per frame
void Update () {
}
}
11、第十一步
选中预制体Explosions中第一个,在Component——script——DestroyByTime——将代码挂载在爆炸体上了
四、音频添加
1、第一步
player直接添加Audio Source组件,将音频最后一个拖给AudioClip——将Play On Awake去掉勾选——写代码
NewBehaviourScript 补充:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]//序列化,使得自己定义的类可以出现在面板
public class Boundary{
public float xMin,xMax,zMin,zMax;
}
public class NewBehaviourScript : MonoBehaviour {
// Use this for initialization
public float speed=5.0f;
public Boundary boundary;
public float fireRate=0.5f;//子弹发射间隔时间
public GameObject shot;//表示子弹预制体
//public GameObject shotSpawn;//表示位置和旋转角度
public Transform shotSpawn;
private float nextFire=0.0f;//表示子弹下次发射的时间
void Start () {
}
// Update is called once per frame
void Update () {
float moveH=Input.GetAxis("Horizontal");//获取水平方向
float moveV=Input.GetAxis("Vertical");//获取垂直方向
Vector3 movement= new Vector3(moveH, 0.0f, moveV);
//GetComponent<Rigidbody>().velocity=movement*speed;//刚体属性有速度,就可以运动
Rigidbody rb=GetComponent<Rigidbody>();
if(rb!=null){
rb.velocity=movement*speed;
rb.position=new Vector3(Mathf.Clamp(rb.position.x,boundary.xMin,boundary.xMax),0.0f,Mathf.Clamp(rb.position.z,boundary.zMin,boundary.zMax));//介于最小值和最大值之间,以防越界
}
if(Input.GetButton("Fire1")&&Time.time>nextFire)//从游戏开始到现在的时间大于下次开火时间
{
nextFire=Time.time+fireRate;
//Instantiate(shot,shotSpawn.GetComponent<Transform>().position,shotSpawn.GetComponent<Transform>().rotation);//用来自动发射子弹
Instantiate(shot,shotSpawn.position,shotSpawn.rotation);
GetComponent<AudioSource>().Play ();//发射子弹有声音
}
}
}
2、第二步
加背景音:选择GameController——直接添加Audio Source组件,将音频4拖给AudioClip——勾选Loop,就可以循环播放了
加打中时的音频:Explosion第一个添加Audio Source——将音频第一个拖给AudioClip
飞船碰上小行星爆炸音:Explosion第三个添加Audio Source——将音频第三个拖给AudioClip——Play On Awake处于勾选状态
五、计分器、游戏结束和重新开始文本框
给游戏添加计分器,飞船撞小行星游戏结束,游戏介绍按R键重新开始游戏
1、第一步
添加文本框:create——UI——Text——重命名ScoreText,游戏简单可以删掉EventSystem
调节文字位置:Pos X和Y值慢慢调
选择GameController,写好代码后,将ScoreText拖到右方ScoreText上
prefab里asteroid右侧Score Value赋值10
GameController代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//引入UI系统
using UnityEngine.SceneManagement;
public class GameController : MonoBehaviour {
// Use this for initialization
public GameObject hazard;//障碍物,表示预制对象
public int hazardCount;//产生小行星的数量
private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0
public Vector3 spawnValues;//位置控制,给spawnPosition提供炮弹
private Quaternion spawnRotation;//四元素,旋转控制,更方便
public float spawnWait;//等待时间
public float startWait=1.0f;//刚开始有一定的延迟
public float waveWait = 2.0f;//一轮后的等待时间
public Text scoreText;//文本框绑定
private int score;//存放得分值
//public Text gameOverText;
//private bool gameOver;
// public Text restartText;
// private bool restart;
void Start () {
StartCoroutine(SpawnWaves ());//开启协程
score = 0;//开始为0
UpdataScore ();//开始先更新一下分数
// gameOverText.text =" ";
// gameOver = false;
// restartText.text = "";
// restart = false;
}
// Update is called once per frame
void Update () {
//if (restart) {
// if (Input.GetKeyDown (KeyCode.R))
//
SceneManager.LoadScene ("Main");
//}
}
IEnumerator SpawnWaves(){
yield return new WaitForSeconds (startWait);//实现协程,打断时间
while (true){
// if (gameOver) {
// restartText.text = "按住【R】键重新开始";
// restart = true;
// break;
//}
for (int i = 0; i < hazardCount; i++) {
spawnPosition.x = Random.Range (-spawnValues.x,spawnValues.x);//取区间的随机值
spawnPosition.z = spawnValues.z;//Z方向值
spawnRotation = Quaternion.identity;//不发生旋转?
Instantiate (hazard,spawnPosition,spawnRotation);//实例化
yield return new WaitForSeconds (spawnWait);//产生一个后中断一段时间再产生
}
yield return new WaitForSeconds (waveWait);
}
}
public void AddScore(int newScoreValue){
score += newScoreValue;//更新分数
UpdataScore ();
}
void UpdataScore(){
scoreText.text = "Score" + score;//屏幕上Score增加
}
// public void GameOver(){
// gameOver = true;
// gameOverText.text = "游戏结束";
//}
}
修改DestroyByContact代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DestroyByContact : MonoBehaviour {
// Use this for initialization
public GameObject explosion;//子弹和小行星碰撞
public GameObject playerExplosion;//飞船和小行星碰撞
public int scoreValue;//实参
private GameController gameController;//实例化,可以调用GameController的方法
void Start () {
GameObject go=GameObject.FindWithTag ("GameController");
if (go != null)
gameController = go.GetComponent<GameController> ();//拿到GameController脚本代码的控制权
else
Debug.Log ("找不到tag名为GameController的对象");
if(gameController==null)
Debug.Log ("找不到脚本GameController");
}
// Update is called once per frame
void Update () {
}
void OnTriggerEnter(Collider other){
if (other.tag == "Boundary")
return;//如果是边界直接返回
Destroy (other.gameObject);//和小行星碰撞的,子弹或飞船
Destroy (gameObject);//小行星也销毁
print (other.name);//测试边界是否被销毁,看看other是谁,发现边界和小行星发生碰撞了
Instantiate (explosion,transform.position,transform.rotation);//实例化
gameController.AddScore (scoreValue);//应该在这里
if (other.tag == "Player") {
Instantiate (playerExplosion,other.transform.position,other.transform.rotation);//飞船爆炸实例化
//gameController.AddScore (scoreValue);
//gameController.GameOver ();
}
}
}
2、第二步
GAME OVER设置
选中ScoreText然后Ctrl+D键即可复制,重命名为GameOverText——文本内容改为GAME OVER——调整位置——写好代码将GameOverText拖给GameController右侧Game OverText
GameController代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//引入UI系统
using UnityEngine.SceneManagement;
public class GameController : MonoBehaviour {
// Use this for initialization
public GameObject hazard;//障碍物,表示预制对象
public int hazardCount;//产生小行星的数量
private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0
public Vector3 spawnValues;//位置控制,给spawnPosition提供炮弹
private Quaternion spawnRotation;//四元素,旋转控制,更方便
public float spawnWait;//等待时间
public float startWait=1.0f;//刚开始有一定的延迟
public float waveWait = 2.0f;//一轮后的等待时间
public Text scoreText;//文本框绑定
private int score;//存放得分值
public Text gameOverText;//更新内容
private bool gameOver;//判断是否结束
//public Text restartText;
//private bool restart;
void Start () {
StartCoroutine(SpawnWaves ());//开启协程
score = 0;//开始为0
UpdataScore ();//开始先更新一下分数
gameOverText.text =" ";//赋值为空
gameOver = false;//刚开始游戏不会结束
// restartText.text = "";
// restart = false;
}
// Update is called once per frame
void Update () {
//if (restart) {
// if (Input.GetKeyDown (KeyCode.R))
//
SceneManager.LoadScene ("Main");
//}
}
IEnumerator SpawnWaves(){
yield return new WaitForSeconds (startWait);//实现协程,打断时间
while (true){
if (gameOver) {
// restartText.text = "按住【R】键重新开始";
// restart = true;
break;//游戏结束不再产生小行星
}
for (int i = 0; i < hazardCount; i++) {
spawnPosition.x = Random.Range (-spawnValues.x,spawnValues.x);//取区间的随机值
spawnPosition.z = spawnValues.z;//Z方向值
spawnRotation = Quaternion.identity;//不发生旋转?
Instantiate (hazard,spawnPosition,spawnRotation);//实例化
yield return new WaitForSeconds (spawnWait);//产生一个后中断一段时间再产生
}
yield return new WaitForSeconds (waveWait);
}
}
public void AddScore(int newScoreValue){
score += newScoreValue;//更新分数
UpdataScore ();
}
void UpdataScore(){
scoreText.text = "Score:" + score;//屏幕上Score增加
}
public void GameOver(){
gameOver = true;
gameOverText.text = "GAME OVER";
}
}
3、第三步
RESTART设置
重新复制一个文本框,重命名为RestartText——文本内容改为Restart——调整位置——写好代码将RestartText拖给GameController右侧RestartText
GameController代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//引入UI系统
using UnityEngine.SceneManagement;//和场景管理相关的操作都在里面
public class GameController : MonoBehaviour {
// Use this for initialization
public GameObject hazard;//障碍物,表示预制对象
public int hazardCount;//产生小行星的数量
private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0
public Vector3 spawnValues;//位置控制,给spawnPosition提供炮弹
private Quaternion spawnRotation;//四元素,旋转控制,更方便
public float spawnWait;//等待时间
public float startWait=1.0f;//刚开始有一定的延迟
public float waveWait = 2.0f;//一轮后的等待时间
public Text scoreText;//文本框绑定
private int score;//存放得分值
public Text gameOverText;//更新内容
private bool gameOver;//判断是否结束
public Text restartText;
private bool restart;//判断是否重新开始
void Start () {
StartCoroutine(SpawnWaves ());//开启协程
score = 0;//开始为0
UpdataScore ();//开始先更新一下分数
gameOverText.text =" ";//赋值为空
gameOver = false;//刚开始游戏不会结束
restartText.text = "";
restart = false;
}
// Update is called once per frame
void Update () {
if (restart) {
if (Input.GetKeyDown (KeyCode.R))
SceneManager.LoadScene ("Main");//执行重新开始操作
}
}
IEnumerator SpawnWaves(){
yield return new WaitForSeconds (startWait);//实现协程,打断时间
while (true){
if (gameOver) {
restartText.text = "按住【R】键重新开始";
restart = true;
break;//游戏结束不再产生小行星
}
for (int i = 0; i < hazardCount; i++) {
spawnPosition.x = Random.Range (-spawnValues.x,spawnValues.x);//取区间的随机值
spawnPosition.z = spawnValues.z;//Z方向值
spawnRotation = Quaternion.identity;//不发生旋转?
Instantiate (hazard,spawnPosition,spawnRotation);//实例化
yield return new WaitForSeconds (spawnWait);//产生一个后中断一段时间再产生
}
yield return new WaitForSeconds (waveWait);//一轮之后隔一段时间再产生
}
}
public void AddScore(int newScoreValue){
score += newScoreValue;//更新分数
UpdataScore ();
}
void UpdataScore(){
scoreText.text = "Score:" + score;//屏幕上Score增加
}
public void GameOver(){
gameOver = true;
gameOverText.text = "GAME OVER";
}
}
六、总结
游戏已做好,完整代码如下:
NewBehaviourScript脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]//序列化,使得自己定义的类可以出现在面板
public class Boundary{
public float xMin,xMax,zMin,zMax;
}
public class NewBehaviourScript : MonoBehaviour {
// Use this for initialization
public float speed=5.0f;
public Boundary boundary;
public float fireRate=0.5f;//子弹发射间隔时间
public GameObject shot;//表示子弹预制体
//public GameObject shotSpawn;//表示位置和旋转角度
public Transform shotSpawn;
private float nextFire=0.0f;//表示子弹下次发射的时间
void Start () {
}
// Update is called once per frame
void Update () {
float moveH=Input.GetAxis("Horizontal");//获取水平方向
float moveV=Input.GetAxis("Vertical");//获取垂直方向
Vector3 movement= new Vector3(moveH, 0.0f, moveV);
//GetComponent<Rigidbody>().velocity=movement*speed;//刚体属性有速度,就可以运动
Rigidbody rb=GetComponent<Rigidbody>();
if(rb!=null){
rb.velocity=movement*speed;
rb.position=new Vector3(Mathf.Clamp(rb.position.x,boundary.xMin,boundary.xMax),0.0f,Mathf.Clamp(rb.position.z,boundary.zMin,boundary.zMax));//介于最小值和最大值之间,以防越界
}
if(Input.GetButton("Fire1")&&Time.time>nextFire)//从游戏开始到现在的时间大于下次开火时间
{
nextFire=Time.time+fireRate;
//Instantiate(shot,shotSpawn.GetComponent<Transform>().position,shotSpawn.GetComponent<Transform>().rotation);//用来自动发射子弹
Instantiate(shot,shotSpawn.position,shotSpawn.rotation);
GetComponent<AudioSource>().Play ();//发射子弹有声音
}
}
}
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 () {
}
void OnTriggerExit(Collider other){
Destroy(other.gameObject);//溢出触发器的操作,销毁子弹
print (other.name);
}
}
DestroyByContact脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DestroyByContact : MonoBehaviour {
// Use this for initialization
public GameObject explosion;//子弹和小行星碰撞
public GameObject playerExplosion;//飞船和小行星碰撞
public int scoreValue;//实参
private GameController gameController;//实例化,可以调用GameController的方法
void Start () {
GameObject go=GameObject.FindWithTag ("GameController");
if (go != null)
gameController = go.GetComponent<GameController> ();//拿到GameController脚本代码的控制权
else
Debug.Log ("找不到tag名为GameController的对象");
if(gameController==null)
Debug.Log ("找不到脚本GameController");
}
// Update is called once per frame
void Update () {
}
void OnTriggerEnter(Collider other){
if (other.tag == "Boundary")
return;//如果是边界直接返回
Destroy (other.gameObject);//和小行星碰撞的,子弹或飞船
Destroy (gameObject);//小行星也销毁
print (other.name);//测试边界是否被销毁,看看other是谁,发现边界和小行星发生碰撞了
Instantiate (explosion,transform.position,transform.rotation);//实例化
gameController.AddScore (scoreValue);//应该在这里,射中子弹分数加加
if (other.tag == "Player") {
Instantiate (playerExplosion,other.transform.position,other.transform.rotation);//飞船爆炸实例化
//gameController.AddScore (scoreValue);
gameController.GameOver ();//飞船爆炸游戏结束
}
}
}
RandomRorator脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RandomRorator : MonoBehaviour {
// Use this for initialization
public float tumble=10.0f;//旋转系数
void Start () {
GetComponent<Rigidbody>().angularVelocity = Random.insideUnitSphere*tumble;//单位球体之间取随机值
}
// Update is called once per frame
void Update () {
}
}
Mover脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Mover : MonoBehaviour {
// Use this for initialization
public float speed=10.0f;
void Start () {
GetComponent<Rigidbody>().velocity=transform.forward*speed;//向正前方飞
}
// Update is called once per frame
void Update () {
}
}
GameController脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//引入UI系统
using UnityEngine.SceneManagement;//和场景管理相关的操作都在里面
public class GameController : MonoBehaviour {
// Use this for initialization
public GameObject hazard;//障碍物,表示预制对象
public int hazardCount;//产生小行星的数量
private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0
public Vector3 spawnValues;//位置控制,给spawnPosition提供炮弹
private Quaternion spawnRotation;//四元素,旋转控制,更方便
public float spawnWait;//等待时间
public float startWait=1.0f;//刚开始有一定的延迟
public float waveWait = 2.0f;//一轮后的等待时间
public Text scoreText;//文本框绑定
private int score;//存放得分值
public Text gameOverText;//更新内容
private bool gameOver;//判断是否结束
public Text restartText;
private bool restart;//判断是否重新开始
void Start () {
StartCoroutine(SpawnWaves ());//开启协程
score = 0;//开始为0
UpdataScore ();//开始先更新一下分数
gameOverText.text =" ";//赋值为空
gameOver = false;//刚开始游戏不会结束
restartText.text = "";
restart = false;
}
// Update is called once per frame
void Update () {
if (restart) {
if (Input.GetKeyDown (KeyCode.R))
SceneManager.LoadScene ("Main");//执行重新开始操作
}
}
IEnumerator SpawnWaves(){
yield return new WaitForSeconds (startWait);//实现协程,打断时间
while (true){
if (gameOver) {
restartText.text = "按住【R】键重新开始";
restart = true;
break;//游戏结束不再产生小行星
}
for (int i = 0; i < hazardCount; i++) {
spawnPosition.x = Random.Range (-spawnValues.x,spawnValues.x);//取区间的随机值
spawnPosition.z = spawnValues.z;//Z方向值
spawnRotation = Quaternion.identity;//不发生旋转?
Instantiate (hazard,spawnPosition,spawnRotation);//实例化
yield return new WaitForSeconds (spawnWait);//产生一个后中断一段时间再产生
}
yield return new WaitForSeconds (waveWait);//一轮之后隔一段时间再产生
}
}
public void AddScore(int newScoreValue){
score += newScoreValue;//更新分数
UpdataScore ();
}
void UpdataScore(){
scoreText.text = "Score:" + score;//屏幕上Score增加
}
public void GameOver(){
gameOver = true;
gameOverText.text = "GAME OVER";
}
}
DestroyByTime 脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DestroyByTime : MonoBehaviour {
// Use this for initialization
public float lifetime=2.0f;
void Start () {
Destroy (gameObject,lifetime);//过一段时间再销毁
}
// Update is called once per frame
void Update () {
}
}
最后
以上就是含蓄金针菇为你收集整理的Unity3D星际航行游戏完整开发过程一、准备工作 三、小行星四、音频添加五、计分器、游戏结束和重新开始文本框六、总结的全部内容,希望文章能够帮你解决Unity3D星际航行游戏完整开发过程一、准备工作 三、小行星四、音频添加五、计分器、游戏结束和重新开始文本框六、总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复