跳至主要內容

13-随机生成物体

AI悦创原创Unity休闲手机游戏开发UnityUnity休闲手机游戏开发Unity大约 22 分钟...约 6463 字

你好,我是悦创。

我先快速给你演示一下另外的两个汽车:

1. Car02 修改锚点
1. 修改锚点
  • Car01: 2.1
  • Car02: 2.5
  • Car03: 3

三种车,设置三种不同的速度。

在这节课中,我们要学会如何生成一个物体。并且可以随机生成三种车中的一种。

1. 编写代码

我们要编写代码,绑定在我们的 SpawnPoint A、SpawnPoint B,包括我们未来的小木板,也用同样的方式生成。

1.1 新建代码

新建我们的代码:

同时选择我们的 SpawnPoint A、SpawnPoint B,同时添加我们的脚本:

1.2 开始编写

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Spawner : MonoBehaviour
{
    // 为了,让我们能获得,这所有三种小汽车的 prefabs。然后,让它们生成在场景中。
    // 所以,我们要创建一个列表来保存我们的小汽车。
    // 所以我们先创建列表 <表示要拿到的类型>
    public List<GameObject> spawnObjects;

}






 
 
 
 


编写好代码后,我们回到我们的 Unity,查看一下。

1.3 添加预制体角色

添加有三种方法,我来一一演示给你。

1.3.1 方法1

1

1.3.2 方法2

1

以此类推操作。

1.3.3 方法三

接下来,这个方法可以同时选择多个预制体,拖入 Spawn Objects。

但是,这个选择多个预制体之后,右边的显示框会跑到别的地方。

1. 点击锁头

接着,我们回到代码中继续编写。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Spawner : MonoBehaviour
{
    // --- snip ---

    private void Start() {
        Spawn();
    }

    // 我们接下来要编写一个生成的方法
    private void Spawn()
    {
        // 在这个函数中,我们要学会如何生成物体
        // 我们先试一试生成列表中的第一个
        // Instabtiate(角色, 生成的位置,是否旋转,生成之后成为当前物体的子物体)
        // transform.position 生成到当前角色的 position,因为我们的代码是绑定在 SpawnPoint 生成点上
        // 不需要任何旋转的话,我们使用:Quaternion.identity,意思是保留当前的状态,不使用任何的旋转
        // spawnObjects[0] 找到序号为 0 的角色
        Instantiate(spawnObjects[0], transform.position, Quaternion.identity, transform);  // 放到 Start 中执行一下
    }
}








 
 
 

 
 
 
 
 
 
 
 
 
 


我们一运行游戏,就会执行 Start 的方法,执行之后就是调用 Spawn。

1.4 测试运行

我们可以看到,它们都同时生成了,并且生成到了它们的子物体。

2. 随机生成小汽车

现在,我们就可以生成一个物体了,现在我们希望随机生成小汽车,应该怎么办呢?

我们需要一个随机的方法,随机的方法就是 Random。

1
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Spawner : MonoBehaviour
{
    // --- snip ---
    private void Spawn()
    {
        // --- snip ---
        var index = Random.Range(0, spawnObjects.Count); // 浮点数左闭右闭,整数:左闭右开 , 使用我们 list 列表的个数 spawnObjects.Count
        Instantiate(spawnObjects[index], transform.position, Quaternion.identity, transform);  // 放到 Start 中执行一下
    }
}










 
 


我们可以测试一下:

我们可以发现,小车只生成一次,并没有重复生成。

3. 循环实现随机小汽车生成

我们如何在随机时间中,循环生成小汽车呢?

我们首先注释或者去掉 Spawn();

private void Start() {
        // Spawn();
        // 我们用另外一个方法来实现,也是 unity 自带的
        // InvokeRepeating();  // 它在我们一开始的时候,就执行我们的方法
        // InvokeRepeating(string的方法名, 从几时开始,重复的频率、间隔多少秒、随机间隔);  
    }

 




修改后的代码如下:

private void Start() {
        // Spawn();
        // 我们用另外一个方法来实现,也是 unity 自带的
        // InvokeRepeating();  // 它在我们一开始的时候,就执行我们的方法
        // InvokeRepeating(string的方法名, 从几时开始,重复的频率、间隔多少秒、随机间隔);  
        // nameof 为了让我们输入的时候有提示,确保我们不会写错名称
        InvokeRepeating(nameof(Spawn), 0.2f, Random.Range(5f, 7f));  // 我希望游戏开始 0.2s 后开始 // 间隔时间是随机5s或7s的时间内

    }






 


我们执行测试一下:

虽然上面实现了,但是我们可以发现小汽车是同一个方向生成的,这样的情况下,我们的小青蛙是不可能取胜的。

我希望有一排车道是反方向行驶的。

4. 反方向汽车

1

现在我们运行游戏,小汽车还是会向右运行程序。

我们如何实现向左移动呢?——这个时候我们需要暴露一个参数来实现向左向右。可以想想我们之前青蛙是怎么实现的。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Spawner : MonoBehaviour
{
    public int direction;
    // --- snip ---
}






 


向左改为 -1,向右改为 1。

1

那,这个参数,每次是怎么告诉我们的小汽车呢?

我们生成之后,我们要在我们的代码中调用它,告诉小汽车移动方向。

1
// file: MoveForward.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoveForward : MonoBehaviour
{
    // 首先我们需要三种小汽车有不同的速度
    public float speed;  // 方便我们在界面操作设置速度
    public int dir;  // 用来记录小气的方向,也是小汽车移动的方向
    private Vector2 startPos;  // 用于记录我们初始坐标的位置
    
    // --- snip ---
}









 




现在可以测试运行效果,并且你也会发现,青蛙碰到小汽车后也会出现 GameOver:

现在,你可以自由发挥想象力,设置自己的马路,花花草草都可以。

别忘记设置好后,保存到 Terrain 做成预制体。

其实,到这里。你已经有足够的知识来生成这些随机的场景了。

我们用的方法,就是 Instantiate,知道要生成的是哪个角色。

5. 截止目前的完整代码

CameraControl.cs
// file: Assets/Scripts/Camera/CameraControl.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraControl : MonoBehaviour
{
    public Transform frog;  // 这个创建的类型,取决于我们想要用到 Unity 身上的哪些组件。 
    // public GameObject frog;  // 如果使用 GameObject,我们就需要 GameObject.Transform 然后获取坐标,这样显然太复杂而麻烦。
    // 拿到 Transform 坐标之后呢?我们需要实时的跟随。
    // 作为摄像机跟随,如果跟青蛙保持在同一个更新的频率上,很可能会造成画面的抖动。
    // 因为,Update 是根据不同设备来进行更新的。
    // 所以,我希望在 Frog 更新它的坐标的下一帧,然后才更新相机的坐标位置。
    // 所以,我们使用周期函数 LateUpdate
    public float offsetY;
    // unity 中可以通过内置的 Screen,就可以获取得到它的宽和它的高
    private float ratio; // 用来计算比例
    public float zoomBase;  // 我们需要一个基础的比例
    private void Start()
    {
        ratio = (float)Screen.height / (float)Screen.width;
        // Debug.Log(ratio);
        // 我们既然有这个比例,用基础的数值,乘以比例、乘以一半
        Camera.main.orthographicSize = zoomBase * ratio * 0.5f; // 使用这个代码就可以获取 Unity 当中被标记为 Main Camera 的主相机
    }
    private void LateUpdate()
    {
        // 在这里更新相机的 position;
        transform.position = new Vector3(transform.position.x, frog.transform.position.y + offsetY * ratio, transform.position.z);  // x and z 是保持不变。y 轴要有一个位移差。
        // 如果 y 轴完全等于我们青蛙的坐标会怎么样呢?「讲义有写」
    }

}

欢迎关注我公众号:AI悦创,有更多更好玩的等你发现!

公众号:AI悦创【二维码】

AI悦创·编程一对一

AI悦创·推出辅导班啦,包括「Python 语言辅导班、C++ 辅导班、java 辅导班、算法/数据结构辅导班、少儿编程、pygame 游戏开发、Linux、Web全栈」,全部都是一对一教学:一对一辅导 + 一对一答疑 + 布置作业 + 项目实践等。当然,还有线下线上摄影课程、Photoshop、Premiere 一对一教学、QQ、微信在线,随时响应!微信:Jiabcdefh

C++ 信息奥赛题解,长期更新!长期招收一对一中小学信息奥赛集训,莆田、厦门地区有机会线下上门,其他地区线上。微信:Jiabcdefh

方法一:QQopen in new window

方法二:微信:Jiabcdefh

上次编辑于:
贡献者: AndersonHJB
你认为这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度