1、先导入SpaceShooter的环境资源,将Models下的vehicle_playerShip放到Hierachy窗口,改名为Player.Rotation x改为270,为Player添加mesh collider组件,将vehicle_playerShip_collider放到Mesh属性里面,为Player添加刚体,去掉重力的勾选,将Prefebs中的engines_player放到Hierarchy,并调好位置。
2、进入3D视图,将MainCamera中的Projection改为Orthographic,摄像机视图变为矩形视图。将Camered的背景改为黑色。将Player的Rotation x 改为零。Camera的Rotation改为90,移动摄像机,调节位置在Game视图中查看。通过调节Camera的Size来调节Player的大小,通过调节Camera的Position来调节Player的位置,适当即可。
3、添加一个Directional Light,改名为Main Light,然后reset,改Rotation x为20,y为245.Intensity改为0.75,同理继续添加一个,改名为Fill Light,将Rotation y改为125,点开color将RGB分别改为128,192,192.在添加一个Rim Light,将Rotation x,y分别改为345,65,Indensity改为0.25,Ctrl+Shift+N创建一个GameObject,改名为Light,将三个Light放进去。
4、添加一个Quad组件,改名为Background,rotation x 90,添加一个纹理tile_nebula_green_dff,将tile_nebula_green_dff中的shader改为Unlity/Texture,将Position y 改为-10,将Scale x, y改为15和30,这是纹理图片的大小比例决定的,1:2。
5、创建GameObject,改名为GameCotroller,添加脚本GameCotroller.cs,为Player添加一个新的脚本,命名为PlayerController,脚本为:
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Boundary
{
   
    public float zMin = -3.3f;
    public float zMax = 14f;
    public float xMin = -6.5f;
    public float xMax = 6.5f;
}
public class PlayerController : MonoBehaviour {
    public float speed = 10f;
    public Boundary bound;
    void FixedUpdate()
    {
       
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        Vector3 move = new Vector3(h, 0, v);
        rigidbody.velocity = speed * move;
        rigidbody.position = new Vector3(Mathf.Clamp(rigidbody.position.x, bound.xMin, bound.xMax), 0, Mathf.Clamp(rigidbody.position.z, bound.zMin, bound.zMax));
    }
}
代码心得:限制需要在Game视图移动来调节。记住了rigidbody的velocity方法,限制Player的飞行范围可通过rigidbody.position来控制。学习了Mathf.Clamp(rigidbody.position.x, bound.xMin, bound.xMax)的用法。学习了系列化[System.Serializable]在窗口视图中显示。
6、创建一个GameObject,改名为Bolt,创建一个GameObject,改名为VFX,放到Bolt下,将fx_lazer_orange_dff拖到VFX Inspector中,将Shader改为Particles/Additive可将背景设置为透明。给Bolt加上RigidBody,去掉use Gravity.添加Mover脚本:
using UnityEngine;
using System.Collections;
public class Mover : MonoBehaviour {
    public float speed = 20f;
 // Use this for initialization
 void Start () {
        rigidbody.velocity = transform.forward * speed;
 }
}
再添加一个Capsule Collider用于碰撞检测,将Radius和height的值设为0.05,0.55.direction设为Z-Axis,现在报错,是因为FBX的MeshRenderer和Bolt的Capsule Collider冲突,删掉FBX的MeshRenderer。注意一点要想把改变的同步到Prefabs中就得点击应用。
开始添加子弹,创建新的GameObject,命名为SpawnPos放到Player下面。继续编辑PlayerController脚本。代码如下:
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Boundary
{
   
    public float zMin = -3.3f;
    public float zMax = 14f;
    public float xMin = -6.5f;
    public float xMax = 6.5f;
}
public class PlayerController : MonoBehaviour {
    public float speed = 10f;
   
    public Boundary bound;
    public GameObject bolt;
    public Transform spawnPos;
    void Update()
    {
        if(Input.GetButton("Fire1"))
        {
            Instantiate(bolt, spawnPos.position, spawnPos.rotation);
        }
    }
    void FixedUpdate()
    {
       
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        Vector3 move = new Vector3(h, 0, v);
        rigidbody.velocity = speed * move;
        rigidbody.position = new Vector3(Mathf.Clamp(rigidbody.position.x, bound.xMin, bound.xMax), 0, Mathf.Clamp(rigidbody.position.z, bound.zMin, bound.zMax));
    }
}
问题:运行游戏,发现游戏的子弹是散的。将Bolt里面的is Trigger勾选上可防止这种情况的出现。现在发现子弹的发射过于连续,添加代码:
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Boundary
{
   
    public float zMin = -3.3f;
    public float zMax = 14f;
    public float xMin = -6.5f;
    public float xMax = 6.5f;
}
public class PlayerController : MonoBehaviour {
    public float speed = 10f;
   
    public Boundary bound;
    public GameObject bolt;
    public Transform spawnPos;
    public float fireRate = 0.1f;
    private float nextFire;
    void Update()
    {
        if(Input.GetButton("Fire1") && Time.time > nextFire)
        {
            nextFire = Time.time + fireRate;
            Instantiate(bolt, spawnPos.position, spawnPos.rotation);
        }
    }
    void FixedUpdate()
    {
       
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        Vector3 move = new Vector3(h, 0, v);
        rigidbody.velocity = speed * move;
        rigidbody.position = new Vector3(Mathf.Clamp(rigidbody.position.x, bound.xMin, bound.xMax), 0, Mathf.Clamp(rigidbody.position.z, bound.zMin, bound.zMax));
    }
}
Bolt(clone)不会消失,现在开始制作子弹的边界。
创建一个cube,改名为Boundary,将Box Collider的Size改为15 和 30,位置调节到与Background位置一致。删除掉mesh collider等组件,添加脚本DesdroyByBoundary。代码如下:
using UnityEngine;
using System.Collections;
public class DestroyByBoundary : MonoBehaviour
{
void OnTriggerExit(Collider other)
    {
        Destroy(other.gameObject);
    }
}
现在开始创建陨石,创建新的GameObject,改名为Asteroid,将prop_asteroid_01拖入其中,添加Rigidbody和Capsule Collider,修改参数使Capsule Collider与物体差不多吻合。RigidBody去掉use Gravity.添加一个脚本,RandomRotation,代码如下:
using UnityEngine;
using System.Collections;
public class RandomRotation : MonoBehaviour {
public float tumble = 5;
 // Use this for initialization
 void Start () {
        rigidbody.angularVelocity = Random.insideUnitSphere * tumble;
 }
 
}
Asteroid添加一个Mover,改Speed为-5。现在陨石可以向下旋转且下落。
同理添加Asteroid2和Asteroid3.
添加一个脚本,改名为DestroyByCantact,如下:
using UnityEngine;
using System.Collections;
public class DestroyByCantact : MonoBehaviour {
void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "Boundary")
        {
            return;
        }
        Destroy(other.gameObject);
        Destroy(this.gameObject);
    }
}
添加到各个Asteroid中。
DestroyByCantact添加代码:
using UnityEngine;
using System.Collections;
public class DestroyByCantact : MonoBehaviour {
    public GameObject explossion;
    public GameObject playerExplosion;
 void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "Boundary")
        {
            return;
        }
        if(other.gameObject.tag == "player")
        {
            Instantiate(playerExplosion, this.transform.position, this.transform.rotation);
        }
        Destroy(other.gameObject);
        Destroy(this.gameObject);
        Instantiate(explossion, this.transform.position, this.transform.rotation);
    }
}
将各个爆炸效果分别拖到脚本中,应用到Prefabs当中。
接下来给GameCotroller脚本加代码:
using UnityEngine;
using System.Collections;
public class GameController : MonoBehaviour
{
public Vector3 spawnValues;
    public GameObject[] hazards;
    // Use this for initialization
    void Start()
    {
}
// Update is called once per frame
    void Update()
    {
        if (Random.value < 0.1)
        {
            Spawn();
        }
    }
    void Spawn()
    {
        GameObject o = hazards[Random.Range(0, hazards.Length)];
        Vector3 p = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
        Quaternion q = Quaternion.identity;
        Instantiate(o, p, q);
    }
}
将三个陨石分别添加到Hazards里面。
继续修改GameController代码:
using UnityEngine;
using System.Collections;
public class GameController : MonoBehaviour
{
public Vector3 spawnValues;
    public GameObject[] hazards;
    public int numPerWave = 10;
public float startWait = 2f;   //出现小行星之前的等待时间
    public float spanWait = 1f;     //一波小行星内的间隔时间
    public float waveWait = 4f;   //每两波时间间隔
    // Use this for initialization
    void Start()
    {
        StartCoroutine(SpawnWaves());
    }
// Update is called once per frame
    void Update()
    {
        //if (Random.value < 0.1)
        //{
         //   Spawn();
    //}
    }
    IEnumerator SpawnWaves()
    {
        yield return new WaitForSeconds(startWait);
        while(true)
        {
            for (int i = 0; i < numPerWave; i++)
            {
                Spawn();
                yield return new WaitForSeconds(spanWait);
            }
            yield return new WaitForSeconds(waveWait);
        }
       
    }
private void WaitForSeconds(float spanWait)
    {
        throw new System.NotImplementedException();
    }
    void Spawn()
    {
        GameObject o = hazards[Random.Range(0, hazards.Length)];
        Vector3 p = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
        Quaternion q = Quaternion.identity;
        Instantiate(o, p, q);
    }
}
里面涉及到技巧性。
添加音效,有几个可以直接添加。对于player发射子弹的声音可以在代码中添加。
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Boundary
{
   
    public float zMin = -3.3f;
    public float zMax = 14f;
    public float xMin = -6.5f;
    public float xMax = 6.5f;
}
public class PlayerController : MonoBehaviour {
    public float speed = 10f;
   
    public Boundary bound;
    public GameObject bolt;
    public Transform spawnPos;
    public float fireRate = 0.1f;
    private float nextFire;
    public AudioClip fire;
    void Update()
    {
        if(Input.GetButton("Fire1") && Time.time > nextFire)
        {
            nextFire = Time.time + fireRate;
            Instantiate(bolt, spawnPos.position, spawnPos.rotation);
            audio.PlayOneShot(fire);
        }
    }
    void FixedUpdate()
    {
       
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        Vector3 move = new Vector3(h, 0, v);
        rigidbody.velocity = speed * move;
        rigidbody.position = new Vector3(Mathf.Clamp(rigidbody.position.x, bound.xMin, bound.xMax), 0, Mathf.Clamp(rigidbody.position.z, bound.zMin, bound.zMax));
    }
}
添加脚本将爆炸效果去除
创建DestroyByTime,如下:
using UnityEngine;
using System.Collections;
public class DestroyByTime : MonoBehaviour {
public float lifeTime = 2;
 // Use this for initialization
 void Start () {
        Destroy(this.gameObject, lifeTime);
 }
 
 // Update is called once per frame
 void Update () {
 
 }
}
添加分数,创建一个GUIText,修改y为1,修改代码GameController
using UnityEngine;
using System.Collections;
public class GameController : MonoBehaviour
{
public Vector3 spawnValues;
    public GameObject[] hazards;
    public int numPerWave = 10;
public float startWait = 2f;   //出现小行星之前的等待时间
    public float spanWait = 1f;     //一波小行星内的间隔时间
    public float waveWait = 4f;   //每两波时间间隔
public GUIText scoreText;
    private int score;
    // Use this for initialization
    void Start()
    {
        StartCoroutine(SpawnWaves());
        scoreText.text = "Score: " + score;
    }
// Update is called once per frame
    void Update()
    {
        //if (Random.value < 0.1)
        //{
         //   Spawn();
    //}
    }
    IEnumerator SpawnWaves()
    {
        yield return new WaitForSeconds(startWait);
        while(true)
        {
            for (int i = 0; i < numPerWave; i++)
            {
                Spawn();
                yield return new WaitForSeconds(spanWait);
            }
            yield return new WaitForSeconds(waveWait);
        }
       
    }
private void WaitForSeconds(float spanWait)
    {
        throw new System.NotImplementedException();
    }
    void Spawn()
    {
        GameObject o = hazards[Random.Range(0, hazards.Length)];
        Vector3 p = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
        Quaternion q = Quaternion.identity;
        Instantiate(o, p, q);
    }
    public void AddScore(int v)
    {
        score += v;
        scoreText.text = "Score: " + score;
    }
}
将GameController物体的TAG改为GameController,修改DesdroyByContact脚本:
using UnityEngine;
using System.Collections;
public class DestroyByCantact : MonoBehaviour {
    public GameObject explossion;
    public GameObject playerExplosion;
private GameController gameController;
    public int score = 10;
    void Start()
    {
        GameObject gameControllerObject = GameObject.FindWithTag("GameController");
        if(gameControllerObject != null)
        {
            gameController = gameControllerObject.GetComponent<GameController>();
        }
        if(gameControllerObject == null)
        {
            Debug.Log("TaoCheng");
        }
    }
 void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "Boundary")
        {
            return;
        }
        if(other.gameObject.tag == "player")
        {
            Instantiate(playerExplosion, this.transform.position, this.transform.rotation);
        }
        if(other.gameObject.tag == "enemy")
        {
            return;
        }
        Destroy(other.gameObject);
        gameController.AddScore(score);
        Destroy(this.gameObject);
        Instantiate(explossion, this.transform.position, this.transform.rotation);
    }
}
做显示游戏结束和游戏重新开始。
GameCotroller脚本代码如下:
using UnityEngine;
using System.Collections;
public class GameController : MonoBehaviour
{
public Vector3 spawnValues;
    public GameObject[] hazards;
    public int numPerWave = 10;
public float startWait = 2f;   //出现小行星之前的等待时间
    public float spanWait = 1f;     //一波小行星内的间隔时间
    public float waveWait = 4f;   //每两波时间间隔
public GUIText scoreText;
    private int score;
    private bool gameOver;
    public GUIText gameOverText;
    public GUIText helpText;
    // Use this for initialization
    void Start()
    {
        StartCoroutine(SpawnWaves());
        scoreText.text = "Score: " + score;
        gameOverText.text = "";
        helpText.text = "";
    }
// Update is called once per frame
    void Update()
    {
        if(gameOver && Input.GetKeyDown(KeyCode.R))
        {
            Application.LoadLevel(Application.loadedLevel);
        }
        //if (Random.value < 0.1)
        //{
         //   Spawn();
    //}
    }
    IEnumerator SpawnWaves()
    {
        yield return new WaitForSeconds(startWait);
        while(true)
        {
            for (int i = 0; i < numPerWave; i++)
            {
                Spawn();
                yield return new WaitForSeconds(spanWait);
            }
            yield return new WaitForSeconds(waveWait);
            if (gameOver)
                break;
        }  
    }
private void WaitForSeconds(float spanWait)
    {
        throw new System.NotImplementedException();
    }
    void Spawn()
    {
        GameObject o = hazards[Random.Range(0, hazards.Length)];
        Vector3 p = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
        Quaternion q = Quaternion.identity;
        Instantiate(o, p, q);
    }
    public void AddScore(int v)
    {
        score += v;
        scoreText.text = "Score: " + score;
    }
    public void GameOver()
    {
        gameOver = true;
        gameOverText.text = "Game Over!";
        helpText.text = "Press 'R' to Restart!";
    }
}
DestroyByContact脚本代码如下:
using UnityEngine;
using System.Collections;
public class DestroyByCantact : MonoBehaviour {
    public GameObject explossion;
    public GameObject playerExplosion;
private GameController gameController;
    public int score = 10;
    void Start()
    {
        GameObject gameControllerObject = GameObject.FindWithTag("GameController");
        if(gameControllerObject != null)
        {
            gameController = gameControllerObject.GetComponent<GameController>();
        }
        if(gameControllerObject == null)
        {
            Debug.Log("TaoCheng");
        }
    }
 void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "Boundary")
        {
            return;
        }
        if(other.gameObject.tag == "Player")
        {
            Instantiate(playerExplosion, this.transform.position, this.transform.rotation);
            gameController.GameOver();
            Debug.Log("Error");
        }
        if(other.gameObject.tag == "enemy")
        {
            return;
        }
        Destroy(other.gameObject);
        gameController.AddScore(score);
        Destroy(this.gameObject);
        Instantiate(explossion, this.transform.position, this.transform.rotation);
    }
}
设置一个GUIText组,分别添加到代码中。
SpaceShooter基本功能完成。

[Unity3D]Unity3D官方案例SpaceShooter开发教程相关推荐

  1. UNITY3D对接QQGame(PC)开发教程(2022)

    效果 目标:能在UNITY3D里通过qqgame充值 因为目前还没有这类文章,所以填补这下块空白 文章包含 QQGame登录器的制作 QQGAME和UNITY3D的交互 QQGame平台用户信息的读取 ...

  2. android studio的GearVR应用开发(二)、一个简单的VR app(Oculus官方GearVR开发教程,翻译转载)

    声明:本文是Oculus官方的GearVR开发教程,为本人翻译转载,供广大VR开发爱好者一同学习进步使用. 原文章 一个简单的VR app 概观 在搭建好GearVR框架后,让我们一起来创建第一个VR ...

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

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

  4. 【初阶】unity3d官方案例_太空射击SpacingShooter 学习笔记 显示分数时,如何让函数之间相互交流...

    [初阶]unity3d官方案例_太空射击SpacingShooter 学习笔记 显示分数时,如何让函数之间相互交流 一.关于 显示分数时,如何让函数之间相互交流 这是一个非常好的逻辑问题 1 思路:主 ...

  5. unity 彩带粒子_[Unity3D] 官方案例——粒子系统制作火焰效果

    1. 导入资源 打开素材里面的Shuriken场景,然后通过菜单GameObject->Particle System创建一个粒子系统对象,并将物体移至火把位置,此时效果如下: 2. 设置粒子系 ...

  6. Unity3D For Android 开发教程【转http://game.ceeger.com/Unity/Doc/2011/Unity3D_For_Android.html】...

    Unity3D For Android 开发教程 Date:2011-08-01 04:33 我自认为抵挡诱惑的能力还是很强大的,关键的时候还能把持住自己.今天逛了一下南京的丹凤街,终于受不住Andr ...

  7. Unity3D ——强大的跨平台3D游戏开发工具教程

    http://unity3d.9ria.com/?p=22 众所周知,Unity3D是一个能够实现轻松创作的多平台的游戏开发工具,是一个全面整合的专业游戏引擎.在现有的版本中,其强大的游戏制作功能已经 ...

  8. Unity官方案例噩梦射手开发总结<一> 角色的攻击功能实现

    愉悦的寒假生活总是会猝不及防地迎来尾声,这也意味着我大一生活的进度条已经过半了.幸运的是,在我某位优秀的学长的带领下,我完整地开发出来了unity的官方案例噩梦射手并基本实现所有功能,也是让我这个大一 ...

  9. Stack Ball 堆栈球小游戏unity3d开发教程

    Stack Ball 堆栈球小游戏unity3d开发教程 介绍 <Stack Ball>是一款3D街机游戏,玩家需要通过旋转的螺旋平台来打碎.撞击和弹跳,以达到终点. 听起来很容易?你可错 ...

最新文章

  1. c语言基本类型学习小结
  2. 怎样用MATLAB将矩阵输出为图像并存到硬盘上-图像保存到硬盘
  3. vue 原型设计 拖拽_Vue 也能实现拖拽了 (vue-dragging)
  4. pku2229--sumsets(zjgsu,分花)
  5. 使用VirtualAlloc在0x400000处申请内存
  6. java点到原点距离_java-从经纬度坐标到欧氏距离(EuclideanDistance)完整代码
  7. 使用 cout 输出数据之控制输出格式(二)
  8. prometheus实战:
  9. 建模大师怎么安装到revit中_全面解析Revit软件在装配式建筑项目中的建模思路...
  10. 视频直播:实时数据可视化分析
  11. 【GitHub】GitHub 的 Pull Request 和 GitLab 的 Merge Request 有区别吗?
  12. 移动网站开发——标记语言
  13. iTerm2的颜色主题/配色主题/配色方案
  14. MTK 驱动开发(37)--如何确定阻止进入suspend的原因
  15. 通过demo搞懂encode_utf8和decode_utf8
  16. [msi]获取msi安装包的ProductCode
  17. 开课吧:Html5有哪些新特性?
  18. shell 模拟多进程(3)
  19. java后端技术有哪些_Java后端精选技术:什么是JVM?
  20. 【转】opencv中widthStep不一定等于width*nChannels的原因

热门文章

  1. 手把手教你做游戏外挂
  2. divgrad怎么求_请问高等数学中div(grad u)中的div是什么意思?
  3. 用Java开发50个棋类游戏
  4. 小米手机微信无法连接到服务器1-1,小米1S系统版本低不能登录微信解决办法
  5. vue在线预览excel
  6. 这16道题都能答上来?恭喜你,90%的面试都能通过!
  7. 【经验分享】BMPR文件及其打开软件Balsamiq Wireframes的下载和安装
  8. 36艺教育完成3000万元Pre-A轮融资,星火资本投资 1
  9. 英国帝国理工出品——SSIM对抗攻击
  10. poj 2683 Ohgas' Fortune 利率计算