unity2017官方案例 SpaceShooter 浅析学习

来源:互联网 发布:淘宝网首页 编辑:程序博客网 时间:2024/05/20 03:45

unity2017 SpaceShooter 浅析学习

  1. shift+ctrl+B键快速打开Building Settings窗口。遇到问题:无法像案例那样在playersettings修改分辨率。最终通过增加摄像机视野达到想要的效果。
  2. 让Player漂浮,添加刚体组件后禁用UseGravity。

    void Update () {
    if (Input.GetKeyDown (KeyCode.Space)) {
    this.GetComponent ().useGravity = true;
    }
    }

    让漂浮的刚体重新受重力影响。相反操作的话,在原先启用重力已经下坠后通过脚本禁用重力,刚体不会停止下坠。

  3. [System.Serializable]:有了这行代码,同一脚本里单类的公有数据成员也会出现在脚本组件。

  4. Mathf.Clamp(float value, float min, float max) 钳制:限制value的值在min和max之间, 如果value小于min,返回min。 如果value大于max,返回max,否则返回value。案例中用于限制Player的移动范围。
  5. 让Player发射子弹思路:先创建空物体ShotSpawn(作为子弹生成容器)作为Player的子物体,再用Instantiate(Object , Vector3 position, Quaternion rotation)方法。 发射的子弹不会成为ShotSpawn的子物体。
  6. 让子弹消失思路:用Cube作为触发器建立边界,去除两个mesh组件。当子弹达到边界外子弹销毁。或者添加DestroyByTime脚本。
  7. Random.insideUnitSphere,随机返回半径为1的球体内的一个点(只读)。这里写图片描述
  8. 案例中使用Debug.Log(other.name)检测Asteroid在进入游戏模式后消失的原因。
  9. 让某个游戏物体(Boundary)进入触发范围但是不受影响的方法:
    void OnTriggerEnter(Collider other)
    {
    if (other.tag == "Boundary")
    {
    return;
    }
    //Destroy(other.gameObject);
    //Destroy(gameObject);
    }

    上方代码中,当执行return语句时,即使函数主体中还有其他语句,函数执行也会停止。原理?
  10. 案例中实现行星出现运用到了协程:
    . void Start (){
    StartCoroutine (SpawnWaves ());
    }
    IEnumerator SpawnWaves ()
    {
    yield return new WaitForSeconds (startWait);
    while (true)
    {
    for (int i = 0; i < hazardCount; i++)
    {
    Vector3 spawnPosition = new Vector3 (Random.Range (-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
    Quaternion spawnRotation = Quaternion.identity;
    Instantiate (hazard, spawnPosition, spawnRotation);
    yield return new WaitForSeconds (spawnWait);
    }
    yield return new WaitForSeconds (waveWait);
    }
    }

    疑问:为什么要用到协程?因为需要让行星以有时间间隔,等待一定时间后的一个接一个的形式出现。那么什么是协程:简单说,在脚本运行过程中,需要额外的执行一些其他的代码,这个时候就可以将“其他的代码”以协程的形式来运行。类似于开启了一个线程,但是协程不是线程(参考自网络)。协同程序返回值类型是IEnumerator,返回需要用yield return ,开启协程是StartCoroutine()。关于协程,参考:[http://blog.csdn.net/huang9012/article/details/38492937]。

  11. public void AddScore(int ScoreValue){
    score =score + ScoreValue;
    updateScore ();
    }

    在一个脚本实例中对一个成员函数设为公有成员才可在其他脚本实例里使用。当然,在另一个脚本实例里也需要对那个脚本实例进行引用。

    ***private GameController gameController;***
    void Start()
    {
    GameObject gameControllerObject = GameObject.FindWithTag ("GameController");
    if (gameControllerObject != null)
    {
    gameController = gameControllerObject.GetComponent <GameController>();
    }
    if (gameController == null)
    {
    Debug.Log ("Cannot find 'GameController' script");
    }
    }

  12. `if (gameover) {
    restartText.text = “Press ‘R’ for Restart”;
    restart = true;

    }`这段代码如果按照案例书写似乎并不会实现相应效果,于是将它修改到update(),可以实现。
  13. 学习两个案例的过程中,发现他们都用到了GameController的空物体。这个空物体挂载脚本后有效地控制游戏进程,起到很大的作用。unity代码组织参考:https://www.zhihu.com/question/21070379。


案例扩展部分:

  1. 生成不同形状的行星的思路:在原来Asteroid基础上(将预制体拖至hierachy面板修改其子物体,因为一开始就有了几个相关的组件,修改方便)再创建几个不同的Asteroid,同样设为预制体。GameController.cs代码修改点:public GameObject[] hazards; GameObject hazard = hazards [Random.Range(0,hazards.Length)];
  2. 让背景滚动思路:复制一个新背景作为本体的子物体,移动位置到本体的后方。代码:
    `public class BGScroller : MonoBehaviour {
    public float scrollSpeed;
    public float tilleSizeZ;
    private Vector3 startPosition;

    // Use this for initialization
    void Start () {
    startPosition = transform.position;
    }

    // Update is called once per frame
    void Update () {
    float newPosition = Mathf.Repeat (Time.time * scrollSpeed,tilleSizeZ);
    transform.position = startPosition + Vector3.forward * newPosition;
    }
    }`

  3. 配置完敌人后,让它发射子弹:`public GameObject shot;
    public Transform shotSpawn;
    public float delay;
    public float FireRate;
    private AudioSource audioSource;
    // Use this for initialization
    void Start () {
    audioSource = this.GetComponents ();
    InvokeRepeating (“Fire”, delay, FireRate);
    }

    void Fire()
    {
    Instantiate (shot, shotSpawn.transform, shotSpawn.rotation);
    audioSource.Play ();
    }`
    InvokeRepeating():多少秒后执行该方法,并且之后每隔多少秒执行。


由于该案例扩展部分的视频无字幕,有些地方听不懂,所以忽略过去了大部分内容。。。

注意点:
•Shift+Ctrl+N 快捷键创建空物体。一般需要设置为中心位置。
• 新版本Unity废除了小写组件名称代替GetComponent<组件>()制。
•案例中改变Collider外形是在scene界面按住shift,不过目前版本需要在Collider组件点击Edit Collider。
•案例中的音频资源在inspector面板有3d source 开关。关闭后,将音频文件拖拽到游戏物体或预制体即可变成组件形式并不会出现在hierarchy。在新版本中则有所区别。
•新版本中Application.LoadLevel (Application.loadedLevel)加载场景的方式也被废弃了,改用SceneManager.LoadScene ()。但是加载新场景后,场景变暗,原因参考:[http://blog.csdn.net/u011704031/article/details/54288553]。不过,在使用这个方法之前,需要添加相应头文件,即在上方编写using UnityEngine.SceneManagement。在此之前,因为没有添加UI头文件,而无法定义Text类型数据成员。