学习Space shooter 小项目 总结

夏侯彬郁
2023-12-01
1.提前设置发布环境(Switch platform),并在发布环境中的PlayerSettings.Resolution设置默认屏幕宽度;

2.场景中游戏对象的位开始全部在(0,0,0),Translate属性中Reset,方便场景布置;

3.相机视角可以选择Orthographic(正交视角),并通过Size调整相机的焦距,镜头远近,应用于二维视角场景中,二维场景的背景可以通过创建一个Quad,并添加相应的的背景贴图;默认为Perspective(透视视角),应用于三维视角场景中,相机背景除了可以使用天空盒,也可以使用单色模式,默认为蓝色;

4.所有的场景中都会包含一个“Ambient Light”默认颜色为ARGB(51,51,51,255),在Edit.RenderSettting中设置,可以设置为黑色,避免影响其他的灯光;

5.在复杂模型中需要使用Mesh Collider时可以在游戏对象的Mesh Colider的Mesh中选择线条简单的模型;

6.需要照亮场景时,可以选择3个平行光,2个倾斜相反角度,1个从对象底部方向照射,使其轮廓更加清晰,并注意将灯光进行归类,便于管理,Ctrl+Shift+N 创建新的游戏对象,并Translate.lReset重置到原点位置;

7.在游戏对象身上绑定脚本组件时,若需要在检视面板中调节的public类型变量太多,可以通过在该脚本中新增一个public类,并将统一的public 类型变量归类至该类中,在调用时实例化,同时将该类进行序列化,即在定义该类之前添加[System.Serializable] 进行实例化,这样在检视面板中public变量更方便管理;

8.在通过物理方式使游戏对象发生移动时,使用FixedUpdate函数,在每一个固定的物理步骤前自动调用,与帧数无关,一般默认时间间隔为0.02s,可以通过ProjectSetting.Time更改。
        float speed ;
        float moveHorizontal = Input.GetAxis ( "Horizontal" );
         float moveVertical = Input.GetAxis ( "Vertical" );
 
         Vector3 movement =  new Vector3 (moveHorizontal, 0.0f, moveVertical);
         rigidbody.velocity = movement * speed;
 
在添加了刚体组件的游戏对象,可以通过ragidbody.velocity控制对象的简单移动;

        rigidbody.position =  new Vector3
         (
             Mathf.Clamp (rigidbody.position.x, boundary.xMin, boundary.xMax),
             0.0f,
             Mathf.Clamp (rigidbody.position.z, boundary.zMin, boundary.zMax)
         );
同时可以使用Mathf.Clamp(a,b,c)来控制a的值在b,c之间,使得游戏对象的位置得到控制,不会跑出边界;

9.采用如下代码来实例化对象,实例化对象需要传入实例化的对象,以及实例化后的对象translate和rotation信息,若不用跟踪实例化后的对象可以不用指定实例化后的对象类型,
fireRate和nextFire控制产生实例对象的数率;
   public float fireRate;
   private float nextFire;
   void Update ()
     {
         if (Input.GetButton( "Fire1" ) && Time.time > nextFire)
         {
             nextFire = Time.time + fireRate;
             Instantiate(shot, shotSpawn.position, shotSpawn.rotation);
         }
     }

10.建立CUBE并删除其meshRender组件,将其作为边界触发器使用,并添加如下代码:
    void OnTriggerExit(Collider other)
    {
        Destroy(other.gameObject);
    }
 使超出边界的游戏对象销毁;

11.在给游戏对象添加脚本组件时,创建空物体作为父级对象,并在父对象上编写逻辑,子对象上用于添加纹理效果,尤其是作为prefabs需要反复调用时;

12.Random类可以用于产生随机数,其中Random.insideUnitSphere,返回一个Vector 3类型的随机数,其(x,y,z)三个数都会产生0-1的随机数,这样通过
rigidbody.angularVelocity = Random.insideUnitSphere * 5;
来产生组件随机旋转的效果了;

13. 可以通过Tag来控制是否产生碰撞事件,对于需要忽略的碰撞,可以使用return来跳出检测;
    public GameObject explosion;
    public GameObject playerExplosion;
    void OnTriggerEnter(Collider other)
    {
        if (other.tag == "Boundary")
        {
            return;
        }
        Instantiate(explosion,transform.position,transform.rotation);
        if (other.tag == "Player")
        {
            Instantiate(playerExplosion, other.transform.position, other.transform.rotation);
        }
        Destroy(other.gameObject);
        Destroy(gameObject);
    }

14.一波一波实例的实现
    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);
        }
    }
使用协同程序可以实现暂停一段时间执行代码,但不暂停场景的运行,在一段代码执行完后,添加
 yield return new WaitForSeconds(spawnWait);
括号内参数为需要暂停的时间,协同程序的调用与一般的函数调用不同,需要如下关键字:
StartCoroutine(SpawnWaves());

15.Destroy函数
Destroy(gameObject, lifetime);
第二个参数为摧毁前等待时间
16.若要在一个游戏对象的脚本中调用另一个游戏对象的脚本中的方法,先要定义该脚本类型,其次要找到该脚本所依赖的游戏对象,并完成所定义脚本的实例化,之后才可调用该脚本中的public方法
    
    
  private GameController gameController;      
GameObject gameControllerObject = GameObject.FindWithTag ( "GameController" );
         if (gameControllerObject != null )
         {
             gameController = gameControllerObject.GetComponent <GameController>();
         }
         if (gameController == null )
         {
             Debug.Log ( "Cannot find 'GameController' script" );
         }
private GameController gameController;
17.若要重新加载场景,可以使用如下代码,不必输入场景或序号
 Application.LoadLevel (Application.loadedLevel);
 类似资料: