Unity制作SpaceShooter游戏

在脚本里声明一个public的GameObject,只能从Project栏里将Object拖入Inspector中。
各种变量只能声明在类中各方法外。
在unity窗口上方的标题栏里依次显示场景名-项目名-发布平台,当场景未保存时场景名显示为untitled,场景只能保存在Asset文件夹下,一般建议在其中新建一个_scenes文件夹。
在Edit->Project Settings->Player的Resolution中设定Game视窗的宽高。然后不要忘了选择我们设置好的宽高!
设置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();/**只能通过调用另一个脚本的方法来改变其中的变量*/
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值