一、准备工作

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 initializationpublic float speed=5.0f;void Start () {}// Update is called once per framevoid 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 initializationpublic float speed=5.0f;public Boundary boundary;void Start () {}// Update is called once per framevoid 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 initializationpublic float speed=10.0f;void Start () {GetComponent<Rigidbody>().velocity=transform.forward*speed;//向正前方飞}// Update is called once per framevoid 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 initializationpublic 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 framevoid 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 initializationpublic 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 framevoid 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 initializationvoid Start () {}// Update is called once per framevoid 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 initializationpublic float tumble=10.0f;//旋转系数void Start () {GetComponent<Rigidbody>().angularVelocity = Random.insideUnitSphere*tumble;//单位球体之间取随机值}// Update is called once per framevoid 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 framevoid 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 initializationpublic GameObject explosion;//子弹和小行星碰撞public GameObject playerExplosion;//飞船和小行星碰撞void Start () {}// Update is called once per framevoid 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 initializationpublic GameObject hazard;//障碍物,表示预制对象//public int hazardCount;private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0public Vector3 spawnValues;//位置控制,给spawnPosition提供炮弹private Quaternion spawnRotation;//四元素,旋转控制,更方便void Start () {SpawnWaves();//调用函数}// Update is called once per framevoid 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 initializationpublic GameObject hazard;//障碍物,表示预制对象public int hazardCount;//产生小行星的数量private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0public Vector3 spawnValues;//位置控制,给spawnPosition提供炮弹private Quaternion spawnRotation;//四元素,旋转控制,更方便void Start () {SpawnWaves();//调用函数}// Update is called once per framevoid 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 initializationpublic GameObject hazard;//障碍物,表示预制对象public int hazardCount;//产生小行星的数量private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0public Vector3 spawnValues;//位置控制,给spawnPosition提供炮弹private Quaternion spawnRotation;//四元素,旋转控制,更方便public float spawnWait;//等待时间void Start () {StartCoroutine(SpawnWaves ());//开启协程}// Update is called once per framevoid 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 initializationpublic GameObject hazard;//障碍物,表示预制对象public int hazardCount;//产生小行星的数量private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0public Vector3 spawnValues;//位置控制,给spawnPosition提供炮弹private Quaternion spawnRotation;//四元素,旋转控制,更方便public float spawnWait;//等待时间public float startWait=1.0f;//刚开始有一定的延迟void Start () {StartCoroutine(SpawnWaves ());//开启协程}// Update is called once per framevoid 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 initializationpublic GameObject hazard;//障碍物,表示预制对象public int hazardCount;//产生小行星的数量private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0public 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 framevoid 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 initializationpublic float lifetime=2.0f;void Start () {Destroy (gameObject,lifetime);//过一段时间再销毁}// Update is called once per framevoid 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 initializationpublic 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 framevoid 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 initializationpublic GameObject hazard;//障碍物,表示预制对象public int hazardCount;//产生小行星的数量private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0public 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;//开始为0UpdataScore ();//开始先更新一下分数//   gameOverText.text =" ";//    gameOver = false;//    restartText.text = "";// restart = false;}// Update is called once per framevoid 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 initializationpublic 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脚本代码的控制权elseDebug.Log ("找不到tag名为GameController的对象");if(gameController==null)Debug.Log ("找不到脚本GameController");}// Update is called once per framevoid 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 initializationpublic GameObject hazard;//障碍物,表示预制对象public int hazardCount;//产生小行星的数量private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0public 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;//开始为0UpdataScore ();//开始先更新一下分数gameOverText.text =" ";//赋值为空gameOver = false;//刚开始游戏不会结束//   restartText.text = "";// restart = false;}// Update is called once per framevoid 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 initializationpublic GameObject hazard;//障碍物,表示预制对象public int hazardCount;//产生小行星的数量private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0public 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;//开始为0UpdataScore ();//开始先更新一下分数gameOverText.text =" ";//赋值为空gameOver = false;//刚开始游戏不会结束restartText.text = "";restart = false;}// Update is called once per framevoid 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 initializationpublic 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 framevoid 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 initializationvoid Start () {}// Update is called once per framevoid 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 initializationpublic 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脚本代码的控制权elseDebug.Log ("找不到tag名为GameController的对象");if(gameController==null)Debug.Log ("找不到脚本GameController");}// Update is called once per framevoid 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 initializationpublic float tumble=10.0f;//旋转系数void Start () {GetComponent<Rigidbody>().angularVelocity = Random.insideUnitSphere*tumble;//单位球体之间取随机值}// Update is called once per framevoid Update () {}
}

Mover脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Mover : MonoBehaviour {// Use this for initializationpublic float speed=10.0f;void Start () {GetComponent<Rigidbody>().velocity=transform.forward*speed;//向正前方飞}// Update is called once per framevoid 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 initializationpublic GameObject hazard;//障碍物,表示预制对象public int hazardCount;//产生小行星的数量private Vector3 spawnPosition = Vector3.zero;//位置,初始位置0,0,0public 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;//开始为0UpdataScore ();//开始先更新一下分数gameOverText.text =" ";//赋值为空gameOver = false;//刚开始游戏不会结束restartText.text = "";restart = false;}// Update is called once per framevoid 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 initializationpublic float lifetime=2.0f;void Start () {Destroy (gameObject,lifetime);//过一段时间再销毁}// Update is called once per framevoid Update () {}
}

Unity3D星际航行游戏完整开发过程相关推荐

  1. Unity官方案例之星际航行游戏(Space Shooter)学习总结

    这几天我学习了<Unity官方案例精讲>的Space Shooter部分,这个案例作为刚刚学习Unity的入门还是不错的,这是整个案例的代码. 下面对我觉得比较常见的几个用法进行一下总结. ...

  2. 星际航行游戏流程(Unity 初学者)

    第一节 创建工程 1.创建3D项目工程 创建一个文件夹,命名为_Scene 新建场景,然后保存[CTRL+S],将其命名为myscene 2.设置游戏窗口的大小 400*600 选择文件菜单,单击Bu ...

  3. 2019年4月份整理的Unity3D游戏完整源码

    Unity3D ×××游戏完整源码 GI Racing 2 http://www.idoubi.net/unity3d/complete-project/3570.html Unity3D 街机几何跳 ...

  4. Unity3D官方案例1-星际航行游戏Space Shooter

    Unity3D官方案例1-星际航行游戏Space Shooter [1]学习中的使用的类 1.Input:使用此类读取常规游戏设置中的轴,访问移动设备的多点触控和加速度. 本例使用到的方法: GetA ...

  5. unity3d游戏2d横版射击游戏完整项目源码分享

    unity3d游戏2d横版射击游戏完整项目源码分享 免费下载地址: 链接:https://pan.baidu.com/s/1YwhEy7DeKIHFU8pBLdJFPg 提取码:3wnx 复制这段内容 ...

  6. unity3d游戏3d局域网联机吃球游戏完整项目源码分享

    unity3d游戏3d局域网联机吃球游戏完整项目源码分享 免费下载地址: 链接:https://pan.baidu.com/s/1APlOCmoK9aUfiVJD48dBQA 提取码:p5nl 复制这 ...

  7. unity3d横版游戏移动_制作游戏并不困难。 回顾Unity3D上的小型移动项目

    unity3d横版游戏移动 Clearly, I'm telling about my experience and my vision, but many things would be commo ...

  8. unity3D埃及探险游戏源码,支持安卓+IOS双端 unity2019 C#语言开发

    unity3D埃及探险游戏源码,支持安卓+IOS双端 unity2019 C#语言开发.完整的源码可直接运营.拿来学习研究和二次开发都很不错. 源码下载 unity3D埃及探险游戏源码C#语言开发.完 ...

  9. 是寒冬还是风口?2015年HTML5游戏完整产业链报告

    策划/采访:尚言 编辑:徐乙榛 文案:李菁 制图:华丽胖子 目录 一.HTML5游戏产业链之研发篇 1-1 开发成本 1-2 开发瓶颈 二.HTML5游戏产业链之渠道篇 2-1 渠道商业模式 2-2 ...

最新文章

  1. ifconfig命令实例
  2. python计算出nan_python如何进行汇总统计?
  3. NLTK找出最频繁的名词标记的程序(代码详细解释)
  4. SharePoint要在master page中动态显示List数据的几种方式
  5. 中大型计算机代表型号,目前个人计算机主要机型.doc
  6. Eclipse配置自动补齐键为alt+/
  7. java数字时钟代码,[Java教程]Javascript 数字时钟
  8. Sublime Text 使用介绍、全套快捷键及插件推荐
  9. 几何修复_*ST海润:实施终止退市 光伏产业修复成几何?
  10. 操作系统---页面置换算法
  11. 企业的IT 建设的三个过程
  12. POJ 3537.Crosses and Crosses(定义sg函数)
  13. 面试中被问到:你在工作中碰到的最困难的问题是什么?
  14. Freeway:Maximizing MLP for Slice-Out-of-Order Execution
  15. 常见Web服务器简介
  16. 【牛客】新建 Microsoft Office Word 文档题解
  17. 微信小程序开发01 双线程模型:为什么小程序不用浏览器的线程模型?
  18. 我的平安健康生活---师旭平
  19. Unity 报错之 ToLua打包:Unable to find tolua DllNotFoundException: tolua
  20. 当我亲身面对大数据杀熟的商家.....

热门文章

  1. 【面试宝典】软件测试工程师2021烫手精华版(第三章Mysql基础篇)
  2. Swan Song 第十一周Scrum Meeting
  3. Docker 私有仓库
  4. Java抽象方法和抽象类
  5. 洛谷P1936 水晶灯火灵 P1775 古代人的难题_NOI导刊2010提高(02)【重题请做P1936】...
  6. 调度算法—FCFS调度算法详解
  7. java实现串的反转
  8. css1vh等于多少px,css单位px、rem、em、vw、vh
  9. 使用ARP命令来绑定IP和MAC地址
  10. 汇龙贷CEO受邀参加深圳金融规范管理论坛会