Unity 2D实现小球碰撞墙体后反弹的脚本编写方法
小球碰撞墙体反弹实现方案
一、HTML5 Canvas 原生实现
核心逻辑是实时检测小球边缘是否触达画布边界,触达后反转对应方向的速度分量,从而实现反弹效果。
完整代码示例:
<canvas id="canvas" width="400" height="300"></canvas> <script> const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); // 小球参数 const ball = { x: 50, y: 50, radius: 15, speedX: 3, speedY: 2 }; // 绘制小球 function drawBall() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.beginPath(); ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2); ctx.fillStyle = '#ff5722'; ctx.fill(); ctx.closePath(); } // 更新小球位置与碰撞检测 function updateBall() { // 碰撞左右边界,反转X轴速度 if (ball.x + ball.radius > canvas.width || ball.x - ball.radius < 0) { ball.speedX = -ball.speedX; } // 碰撞上下边界,反转Y轴速度 if (ball.y + ball.radius > canvas.height || ball.y - ball.radius < 0) { ball.speedY = -ball.speedY; } // 更新位置 ball.x += ball.speedX; ball.y += ball.speedY; } // 动画循环 function animate() { drawBall(); updateBall(); requestAnimationFrame(animate); } animate(); </script>
二、Unity 引擎实现
针对Unity场景,提供两种实现方式:
方式1:基于物理引擎(推荐)
利用Unity内置物理系统实现自然反弹:
- 给小球添加
Rigidbody2D(2D场景)或Rigidbody(3D场景)组件,取消Use Gravity(无需重力时)。 - 小球添加
CircleCollider2D,墙体添加BoxCollider2D,确保两者Is Trigger均未勾选。 - 创建材质并设置Bounciness为1(控制反弹力度)、Friction为0(消除摩擦干扰),将材质赋值给小球。
若需代码自定义反弹逻辑,可添加以下脚本:
using UnityEngine; public class BallBounce : MonoBehaviour { public float bounceForce = 5f; private void OnCollisionEnter2D(Collision2D collision) { // 仅对标签为"Wall"的墙体生效 if (collision.gameObject.CompareTag("Wall")) { // 通过碰撞法线计算反弹方向 Vector2 bounceDir = Vector2.Reflect(GetComponent<Rigidbody2D>().velocity, collision.contacts[0].normal); GetComponent<Rigidbody2D>().velocity = bounceDir * bounceForce; } } }
方式2:手动边界检测(无物理引擎)
适合简单场景,无需依赖物理组件:
using UnityEngine; public class BallManualBounce : MonoBehaviour { public float speed = 5f; private Vector3 moveDir; void Start() { // 初始化随机移动方向 moveDir = new Vector3(Random.Range(-1f, 1f), Random.Range(-1f, 1f), 0).normalized; } void Update() { transform.position += moveDir * speed * Time.deltaTime; // 获取屏幕世界坐标边界 Vector2 screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, 0)); float ballRadius = GetComponent<SpriteRenderer>().bounds.extents.x; // 左右边界碰撞检测 if (transform.position.x + ballRadius > screenBounds.x || transform.position.x - ballRadius < -screenBounds.x) { moveDir.x = -moveDir.x; } // 上下边界碰撞检测 if (transform.position.y + ballRadius > screenBounds.y || transform.position.y - ballRadius < -screenBounds.y) { moveDir.y = -moveDir.y; } } }
内容的提问来源于stack exchange,提问作者kaancf
相关产品推荐
相关产品推荐

