在脚本里声明一个public的GameObject,只能从Project栏里将Object拖入Inspector中。
各种变量只能声明在类中各方法外。
在unity窗口上方的标题栏里依次显示场景名-项目名-发布平台,当场景未保存时场景名显示为untitled,场景只能保存在Asset文件夹下,一般建议在其中新建一个_scenes文件夹。
在Edit->Project Settings->Player的Resolution中设定Game视窗的宽高。然后不要忘了选择我们设置好的宽高!
MeshFilter获取我们的模型,MeshRenderer将其在场景中渲染。
在Camera的Inspector里设置背景。Skybox(天空盒)或SolidColor(单色背景板)。
保留原图大小和比例:因为Unity默认将导入的图片按照2的N次方的比例进行压缩,因此要想保留原尺寸,需要设定Type为EditGUI。
保留原图的色彩:设定Shader为Unlit->Texture。
控制飞船移动的代码(注意这里让飞船匀速移动,这与前面用力控制小球的移动是不同的)(PlayerShip):
public float speed;/**因为public这个选项可以在player的Inspector中输入*/
void FixedUpdate()/**与物理相关的代码写在这个方法里*/
{
float moveHorizontal = Input.GetAxis("Horizontal");/**水平方向的移动输入,左右*/
float moveVertical = Input.GetAxis("Vertical");/**垂直方向上的移动输入,前后*/
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);/**movement中存放了各方向上移动的数据*/
Rigidbody rigidbody = GetComponent<Rigidbody>();
rigidbody.velocity = movement*speed;
}
限制飞船移动范围(PlayerShip):
rigidbody.position = new Vector3(Mathf.Clamp(rigidbody.position.x,(float)-2.5,(float)2.5),0.0f, Mathf.Clamp(rigidbody.position.z, (float)-1.7, (float)5.7));
添加激光弹Object:创建一个Quad作为载体,将Material(材质)和Texture(纹理)拖入其中,将Shader设为Additive即可消去Quad中黑色部分同时将激光弹highlight。
让子弹向前移动的代码(AFX):
public float speed;
void Start()
{
Vector3 movement = new Vector3(0.0f, 0.0f, speed);
Rigidbody rigidbody;
rigidbody = GetComponent<Rigidbody>();
rigidbody.velocity =movement;
}
各个子Object的Transform都是相对于父Object的相对值!
实现按下空格发射子弹的代码(PlayerShip):
public GameObject shoot;
public Transform shootSpawn;
private GameObject newProjectile;
void Shoot()
{
if (Input.GetKey(KeyCode.Space) )
{
newProjectile = Instantiate(shoot, shootSpawn.transform.position, shootSpawn.transform.rotation) as GameObject;/**用shootspawn的position和rotation实例化shoot,一个as GameObject意为实例化一个shoot*/
}
}
private void Start()
{
InvokeRepeating("Shoot", 0.0F, 0.1F);/**(要调用的方法,开始时间,每隔多久调用)*/
}
设置游戏边界(利用Plane的Collider),删除触发边界的Object(Edge):
void OnTriggerEnter(Collider other)
{
Destroy(other.gameObject);/**删除碰撞到的object*/
}
在Planet撞击playerShip时制造爆炸效果并将player和自己删除(同时实现飞船的复活):
Planet(Planet):
public GameObject BoomLight;
public Transform Boom;
private GameObject newProjectile1;
public GameObject planet;
public GameObject reborn;
public GameObject player;
private GameObject newProjectile2;
IEnumerator MyMethod()/**要想实现停留若干秒,必须写这样一个方法,再通过协程调用这个方法完成停留若干秒后执行某操作*/
{
Debug.Log("Before Waiting 1 seconds");
newProjectile1 = Instantiate(BoomLight, Boom.transform.position, Boom.transform.rotation) as GameObject;
yield return new WaitForSeconds(1F);
Debug.Log("After Waiting 1 Seconds");
Destroy(newProjectile1);/**注意参数不是BoomLight*/
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
StartCoroutine(MyMethod());/**协程调用而非普通调用*/
Destroy(other.gameObject);
Destroy(planet);/**删除自己*/
newProjectile2 = Instantiate(player, reborn.transform.position, reborn.transform.rotation) as GameObject;
}
}
// Update is called once per frame
void Update () {
transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
}
子弹(AFX)(在子弹击中planet后制造爆炸效果并将自己和planet删除):
public GameObject BoomLight;/**要创建的实例*/
public Transform Boom;/**参照物挂靠在子弹上*/
public GameObject Afx;
private GameObject newProjectile;
IEnumerator MyMethod()/**要想实现停留若干秒,必须写这样一个方法,再通过协程调用这个方法完成停留若干秒后执行某操作*/
{
Debug.Log("Before Waiting 1 seconds");
newProjectile = Instantiate(BoomLight, Boom.transform.position, Boom.transform.rotation) as GameObject;
yield return new WaitForSeconds(1F);
Debug.Log("After Waiting 1 Seconds");
Destroy(newProjectile);/**注意参数不是BoomLight*/
Destroy(Afx);/**删除自己*/
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Enemy")
{
StartCoroutine(MyMethod());/**协程调用而非普通调用*/
Destroy(other.gameObject);
}
}
生成Planet波(GameContoller):
public GameObject hazard1;
public GameObject hazard2;
public GameObject hazard3;
public Vector3 spawnValues;
public int hazardCount;
public float spawnWait;
public float startWait;
void Start () {
StartCoroutine (SpawnWaves());/**协程调用*/
}
// Update is called once per frame
IEnumerator SpawnWaves () {/**函数要成为协同程序,必须返回IEnumerator,且在调用时要协程调用*/
yield return new WaitForSeconds(startWait);/**暂停代码而不暂停游戏,这个方法只有在协同程序中可用*/
for (int i = 0; i < hazardCount; i++)
{
//创建三个位置使得一个循环里的Planet不在同一处生成
Vector3 spawnPosition1 = new Vector3(UnityEngine.Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
Vector3 spawnPosition2 = new Vector3(UnityEngine.Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
Vector3 spawnPosition3 = new Vector3(UnityEngine.Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
Instantiate(hazard1, spawnPosition1, spawnRotation);/**实例化hazard1*/
yield return new WaitForSeconds(0.5F);/**实例化不同Planet间隔一段时间,这样它们就不可能重叠了*/
Instantiate(hazard2, spawnPosition2, spawnRotation);/**实例化hazard1*/
yield return new WaitForSeconds(0.5F);
Instantiate(hazard3, spawnPosition3, spawnRotation);/**实例化hazard1*/
yield return new WaitForSeconds(spawnWait);
}
}
给爆炸、发射子弹添加音效:
在explosion里添加AudioSource组件,将对应音效拖入Clip项;AFX也如此。这样一来在生成这些Object的同时就会播放音效,Object删除,音效随之消失。
制作计分器:
新建一个3DText,在其脚本(text)中写:
public static int count;/**一定要声明为静态域,所有text类实例都将共用一个count*/
void Start() {
count = 0;/**初始化,不能放在AFX里!*/
GetComponent<TextMesh>().text = "Count:"+count;/**在脚本中控制3Dtext的输出*/
}
public void Add()
{
count = count + 10;
}
IEnumerator MyMethod()
{
Debug.Log("Before Waiting 2 seconds");
GetComponent<TextMesh>().text = "Win!";/**在停留2s前执行的操作*/
yield return new WaitForSeconds(2);
Debug.Log("After Waiting 2 Seconds");
Application.Quit();/**在停留2s后执行的操作*/
}
// Update is called once per frame
void Update () {
if (count>150)
{
StartCoroutine(MyMethod());/**又忘了协程调用*/
}
else
{
GetComponent<TextMesh>().text = "Count:" + count;
}
}
然后要通过AFX的脚本实时改变count变量的值:
public text Text;/**直接用想要改变脚本所从属的类名来创建实例,通过这个实例调用其中方法*/
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Enemy")
{
StartCoroutine(MyMethod());/**协程调用而非普通调用*/
Destroy(other.gameObject);
Text.Add();/**只能通过调用另一个脚本的方法来改变其中的变量*/
}
}