Unity3D星际航行游戏完整开发过程
一、准备工作
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星际航行游戏完整开发过程相关推荐
- Unity官方案例之星际航行游戏(Space Shooter)学习总结
这几天我学习了<Unity官方案例精讲>的Space Shooter部分,这个案例作为刚刚学习Unity的入门还是不错的,这是整个案例的代码. 下面对我觉得比较常见的几个用法进行一下总结. ...
- 星际航行游戏流程(Unity 初学者)
第一节 创建工程 1.创建3D项目工程 创建一个文件夹,命名为_Scene 新建场景,然后保存[CTRL+S],将其命名为myscene 2.设置游戏窗口的大小 400*600 选择文件菜单,单击Bu ...
- 2019年4月份整理的Unity3D游戏完整源码
Unity3D ×××游戏完整源码 GI Racing 2 http://www.idoubi.net/unity3d/complete-project/3570.html Unity3D 街机几何跳 ...
- Unity3D官方案例1-星际航行游戏Space Shooter
Unity3D官方案例1-星际航行游戏Space Shooter [1]学习中的使用的类 1.Input:使用此类读取常规游戏设置中的轴,访问移动设备的多点触控和加速度. 本例使用到的方法: GetA ...
- unity3d游戏2d横版射击游戏完整项目源码分享
unity3d游戏2d横版射击游戏完整项目源码分享 免费下载地址: 链接:https://pan.baidu.com/s/1YwhEy7DeKIHFU8pBLdJFPg 提取码:3wnx 复制这段内容 ...
- unity3d游戏3d局域网联机吃球游戏完整项目源码分享
unity3d游戏3d局域网联机吃球游戏完整项目源码分享 免费下载地址: 链接:https://pan.baidu.com/s/1APlOCmoK9aUfiVJD48dBQA 提取码:p5nl 复制这 ...
- unity3d横版游戏移动_制作游戏并不困难。 回顾Unity3D上的小型移动项目
unity3d横版游戏移动 Clearly, I'm telling about my experience and my vision, but many things would be commo ...
- unity3D埃及探险游戏源码,支持安卓+IOS双端 unity2019 C#语言开发
unity3D埃及探险游戏源码,支持安卓+IOS双端 unity2019 C#语言开发.完整的源码可直接运营.拿来学习研究和二次开发都很不错. 源码下载 unity3D埃及探险游戏源码C#语言开发.完 ...
- 是寒冬还是风口?2015年HTML5游戏完整产业链报告
策划/采访:尚言 编辑:徐乙榛 文案:李菁 制图:华丽胖子 目录 一.HTML5游戏产业链之研发篇 1-1 开发成本 1-2 开发瓶颈 二.HTML5游戏产业链之渠道篇 2-1 渠道商业模式 2-2 ...
最新文章
- ifconfig命令实例
- python计算出nan_python如何进行汇总统计?
- NLTK找出最频繁的名词标记的程序(代码详细解释)
- SharePoint要在master page中动态显示List数据的几种方式
- 中大型计算机代表型号,目前个人计算机主要机型.doc
- Eclipse配置自动补齐键为alt+/
- java数字时钟代码,[Java教程]Javascript 数字时钟
- Sublime Text 使用介绍、全套快捷键及插件推荐
- 几何修复_*ST海润:实施终止退市 光伏产业修复成几何?
- 操作系统---页面置换算法
- 企业的IT 建设的三个过程
- POJ 3537.Crosses and Crosses(定义sg函数)
- 面试中被问到:你在工作中碰到的最困难的问题是什么?
- Freeway:Maximizing MLP for Slice-Out-of-Order Execution
- 常见Web服务器简介
- 【牛客】新建 Microsoft Office Word 文档题解
- 微信小程序开发01 双线程模型:为什么小程序不用浏览器的线程模型?
- 我的平安健康生活---师旭平
- Unity 报错之 ToLua打包:Unable to find tolua DllNotFoundException: tolua
- 当我亲身面对大数据杀熟的商家.....