当前位置: 首页 > news >正文

一周一个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中运行后效果如下所示。

        这个弹板就会跟随我们的鼠标移动,并且即便鼠标超出边界也弹板也会停留在边界处。

相关文章:

  • React面试葵花宝典之二
  • 年后 总结
  • 【PCIe 总线及设备入门学习专栏 1.2 -- 访问 PCIe 设备过程】
  • 实现遍历Windows所有字体的基本属性
  • 从黑暗到光明:FPC让盲人辅助眼镜成为视障者的生活明灯!【新立电子】
  • 学习笔记--大模型外接数据库
  • MybatisPlus实战:
  • R语言+AI提示词:贝叶斯广义线性混合效应模型GLMM生物学Meta分析
  • 10.【线性代数】—— 四个基本子空间
  • GC垃圾回收介绍及GC算法详解
  • python -ssh学习
  • dify接入语音转文本模型后报错: microphone not authorized
  • C++ 变量的输入输出教程
  • 智科技赋能宠物关怀新时代
  • 纯代码实战--用Deepseek+SQLite+Ollama搭建数据库助手
  • 微信小程序自定义导航栏实现指南
  • vscode使用豆包MARSCode----集成doubao1.5 DeepSeekR1 DeepseekV3模型的ai编程插件
  • 【Go | 从0实现简单分布式缓存】-3:分布式节点通信
  • DeepSeek模型认识:R1V3
  • 密码学(哈希函数)
  • 市政府统一建设网站的提议/外贸网站推广方法之一
  • 章丘做网站公司/品牌推广文案
  • 网站没有备案做竞价吗/网络营销网络推广
  • 网站的落地页/360网站安全检测
  • 武汉专业做网站的公司/网页制作教程视频
  • 个人网站经营性备案/seo优化搜索推广