【8.关卡游戏】2.创建工程并让篮子移动

2.创建工程并让篮子移动

2.1 创建工程

创建工程并命名为 “AppleCatch”,选择 Template 为 3D。

将素材添加到工程中。

设置移动平台:

File -> Build Settings,在 Build Settings 中选择对应的移动平台。

然后在场景视图中设置画面尺寸。

最后将场景保存为 GameScene。

2.2 配置舞台

将舞台设置到原点位置:

从工程窗口中将舞台对象 stage 拖拽到场景视图中,在层级窗口中选中 stage,在检视器窗口中设置:

  • Transform 项的 Position:x、y、z 均为 0

旋转场景使 x 轴方向朝右

调整摄像机位置和角度:

在层级窗口中选中 Main Camera,在检视器窗口中设置:

  • Transform 项的 Position:x、y、z 值为 0、3.8、-1.6

Rotation:x、y、z 值为 60、0、0

启动游戏后的效果如下:

【8.关卡游戏】2.创建工程并让篮子移动

设置光源:

设置光源的目的是让用户能够清楚道具会落到哪个地方,因为设置好光源会在道具下落时产生阴影。

Unity 提供的光源:

  • Directional Light - 像太阳光一样从无限远处发出平行光的光源,其光线强度不会随着距离增大而减弱
  • Point Light - 朝全方向发光,距离光源越远,光线强度越低
  • Spot Light - 朝特定方向按放射状发出光线,距离光源越远,光线强度越低
  • Area Light - 在一个长方形平面区域内朝全方向发出光线,只有在烘培为 1 时才能使用

将光源配置到场景中后,影子的位置和视觉效果都由 Unity 自动计算完成。

将光源配置为正对着下方,以确保道具的影子会出现在下落的地点。

在层级窗口中选中 Directional Light,在检视器窗口中设置:

  • Transform 项的 Rotation:x、y、z 值为 90、0、0。
  • 如果感觉从正上方照射下来的光线强度太大,可以调整光源的强度,设置 Light 项的 Intensity 为 0.7

2.3 配置篮子

篮子是运动的对象,所以篮子的 创建方法

  1. 在场景视图中配置篮子
  2. 编写用于描述篮子移动的脚本
  3. 将创建好的脚本挂载到篮子对象上

从工程窗口中将篮子 basket 拖拽到场景视图中,在层级窗口中选中篮子,在检视器窗口中设置:

  • Transform 项的 Position:x、y、z 均为 0

此时可能篮子的阴影看起来有“锯齿感”,在菜单栏中选择 Edit -> Project Settings,选中 Quality,设置其 Shadow Distance 值为 30。

接下来,我们创建控制篮子移动的脚本。 将舞台分为 3 X 3 的区域,篮子将移动到单击区域的中心。 如何实现呢?

舞台是一个边长为 3 的正方形,中心位于原点,所以,如下表:

篮子坐标(x,z)

[z]-1.5 ~ -0.5

[z]-0.5 ~ 0.5

[z]0.5 ~ 1.5

[x]-1.5 ~ -0.5

-1.0,-1.0

-1.0,0

-1.0,1.0

[x]-0.5 ~ 0.5

0,-1.0

0,0

0,1.0

[x]0.5 ~ 1.5

1.0,-1.0

1.0,0

1.0,1.0

对于用户单击的坐标位置可以使用 Input.mousePosition 来获取,获取后通过 ScreenPointToRay 转换为射线,与舞台碰撞后产生一个世界坐标点,通过判断该坐标点的位置来确定篮子的坐标。实际上,我们可以通过 Mathf.RountToInt 方法将坐标四舍五入后就直接得出了坐标位置。

代码如下:

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

public class BasketController : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0)) 
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, Mathf.Infinity))
            {
                float x = Mathf.RoundToInt(hit.point.x);
                float z = Mathf.RoundToInt(hit.point.z);
                transform.position = new Vector3(x, 0, z);
            }
        }
    }
}

在上面的代码中,通过摄像机位置射向画面深处的射线 Ray,该 Ray 可以与碰撞器发生碰撞,通过 Physics.Raycast 方法可以检测出射线与 stage 发生了碰撞,该方法的参数 hit 前面加了一个 out 关键字,表示在该方法中将会给 hit 变量赋值,然后获取 hit 的 point 属性值进行四舍五入转换后作为篮子的坐标值。

挂载脚本,启动游戏,我们发现单击画面后篮子没有反应,原因是舞台现在没有挂载碰撞器,射线无法与舞台发生碰撞,直接穿透了舞台。

为舞台挂载 Collider 组件

在层级窗口中选中 stage,在检视器窗口中单击 Add Component 按钮,选择 Physics -> Box Collider,在检视器窗口设置 Box Collider 的 x、y、z 值为 3、0.1、3。

启动游戏,篮子可以移动到我们单击的位置了。