一周一个Unity小游戏2D反弹球游戏 - 移动的弹板(鼠标版)
前言
本文将实现控制弹板移动,通过Unity的New Input System,可以支持鼠标移动弹板跟随移动,触控点击跟随移动,并且当弹板移动到边界时,弹板不会移动超过边界之外。
创建移动相关的InputAction
项目模版创建的时候默认会有一个InputAction类型的文件,名字为InputSystem_Actions,如下所示。
在双击打开之后,里面有一些默认设置的按键绑定,把里面默认的按键绑定全部删除,重新创建本游戏所需要的按键绑定。
绑定触屏点击和触屏点击位置
创建新的按键绑定,点击+号,创建名为GamePlay的Action Maps。然后将第一个Action命名为Point,然后点击Point右侧的+号添加绑定,选择Press(即触屏点击),如下。
鼠标移动时的位置可以直接从代码里获取,因此此处可以不做绑定。
再添加一个新的Action命名为Position,用来获取触屏点击时的位置。此时Position的Action Type为Value,Control Type为Vector2。里面对应绑定的就是Touchscreen的Position。
点击Save Asset,至此绑定对应的输入键的部分完成了。
创建移动的弹板
基本设置
因为我们要做一个竖版的反弹球游戏,需要将当前的分辨率设置为竖屏的,如下。
首先创建一个2D Square的SpriteRenderer,命名为SpringBoard。
调整下它的位置和大小,如下所示。
在其上添加必要的组件,添加一个BoxCollider 2D的碰撞器,使其能够产生物理的碰撞,从而做后续的反弹。
移动弹板
创建一个脚本,命名为SpringBoardController用来控制弹板的移动逻辑。创建一个Scripts的文件夹用来存放所有的游戏脚本,然后将创建的SpringBoardController放在里面。
以下的代码是实现移动弹板的,首先是鼠标跟随移动的部分。
using UnityEngine;
using UnityEngine.InputSystem;
namespace ReboundBall
{
public class SpringBoardController : MonoBehaviour
{
private SpriteRenderer _spriteRenderer;
private Camera _mainCamera;
private float _minXPosition;
private float _maxXPosition;
private bool _hasMainCamera;
private float _currentXPosition;
private Vector2 _currentPosition;
private void Awake()
{
_spriteRenderer = GetComponent<SpriteRenderer>();
_mainCamera = Camera.main;
if (_mainCamera != null)
{
_hasMainCamera = true;
var spriteWidth = _spriteRenderer.bounds.size.x;
_minXPosition = _mainCamera.ScreenToWorldPoint(Vector3.zero).x + spriteWidth / 2;
_maxXPosition = Mathf.Abs(_minXPosition);
}
}
private void Update()
{
if (_hasMainCamera)
{
if (Application.isEditor || Application.platform == RuntimePlatform.WindowsPlayer)
{
var mousePosition = Mouse.current.position.ReadValue();
_currentXPosition = _mainCamera.ScreenToWorldPoint(mousePosition).x;
_currentXPosition = Mathf.Clamp(_currentXPosition, _minXPosition, _maxXPosition);
}
transform.position = new Vector2(_currentXPosition, transform.position.y);
}
}
}
}
在Awake方法中,我们获取当前游戏物体的SpriteRenderer,然后获取当前的主相机,通过计算SpriteRender的bounds宽度,基于左下角的屏幕坐标原点计算出这个SpriteRender在左边的边界最小值,即一半的bounds宽度加上屏幕左下角在游戏世界的坐标位置。然后取绝对值获取对应的右边边界的最大值。
在Update方法中,由于我们是用鼠标的跟随,所以先判断当前的平台是否是编辑器或者Windows系统,然后读取鼠标的坐标,并将鼠标的屏幕坐标转化为游戏世界坐标,通过一个Clamp裁剪取值,最后将计算得出的X的值和原始的Y值赋给弹板。在Unity中运行后效果如下所示。
这个弹板就会跟随我们的鼠标移动,并且即便鼠标超出边界也弹板也会停留在边界处。