文章目录
游戏画面
中线为Line调整为0.1cm,左边为玩家操作的球拍,右边为Ai自动操控的球拍。注意中线设置的细一点不然会影响美观。
场景搭建
需要搭建的物体有四个墙体,球体,两个球拍。位置可以根据自己喜好摆放,下面我们进入物体设置。
场景设置
1.我们首先对墙体进行设置,我们需要四面墙体,来阻挡球体的运行和得分项的判断。
我们先进行墙体碰撞器的设置,我们需要当球体与墙体碰撞时给我们及时的反馈
这里我们使用的2D碰撞器,可以直接编辑碰撞器的长宽
我们在这里是需要设置四面墙体(碰撞器)将屏幕画面围起来,模拟桌面。这样我们发射球体的时候,球体就不会跑到屏幕外面,他就会按照我们设置到的速度和轨迹一直在游戏中运行。
需要注意的是我们将墙体摆设时不要在交界处留有缝隙,以免球体跑出,相对的墙体Tansform中的position的X,Y值是相反的。
2.设置球拍(两个长方体)
给两个球拍添加刚体组件用于球体碰撞时进行对球的弹回。
因为游戏只需要球拍进行Y轴的移动所以我们将X,Z轴进行锁定。
3.球体的设置:我们首先给球体添加RigidBody 2D(刚体组件),Box Collider 2D(碰撞器)
球体位置我们设置到桌子中心就可以了,球体大小自由设置。
脚本设置
在这里我就不解释代码的运行逻辑了,注释我都标注过了。有不懂问题可以评论留言。
球体代码:
using UnityEngine;
public class Ball : MonoBehaviour
{
//初始速度
public float speed = 200.0f;
//刚体组件变量名
private Rigidbody2D _rigidbody;
private void Awake()
{
_rigidbody = GetComponent<Rigidbody2D>();
}
private void Start()
{
AddStartingForce();
ResetPosition();
}
public void AddStartingForce()
{
//初始时随机向一个方向移动
float x = Random.value < 0.5f ? -1.0f : 1.0f;
//为球初始发射提供方向角度
float y = Random.value < 0.5f ? Random.Range(-1.0f, 0.5f):
Random.Range(0.5f,1.0f);
//给球体赋值
Vector2 direction=new Vector2(x,y);
//给球体发射速度
_rigidbody.AddForce(direction*this.speed);
}
public void AddForce(Vector2 force)
{
_rigidbody.AddForce(force);
}
public void ResetPosition()
{
//重新定义球位置
_rigidbody.position = Vector3.zero;
_rigidbody.velocity= Vector3.zero;
}
}
2.玩家球拍的脚本
移动脚本
using UnityEngine;
public class PlayerPaddle :Paddle
{
//定义私有的方向变量 用于球拍跟踪
private Vector2 _direction;
private void Update()
{
//给球拍移动按键 判断往那个方向移动
if (Input.GetKey(KeyCode.W)||Input.GetKey(KeyCode.UpArrow)) {
_direction = Vector2.up;
}else if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
{
_direction=Vector2.down;
}
else
{
_direction= Vector2.zero;
}
}
private void FixedUpdate()
{
//判断球是否在往某个方向移动
if(_direction.sqrMagnitude != 0)
{
//调用Paddle中的变量名 给球体一个加速度
_rigidbody.AddForce(_direction*this.speed);
}
}
}
给球拍反作用力脚本
using UnityEngine;
public class BouncySurface : MonoBehaviour
{
public float bounceStrength;
private void OnCollisionEnter2D(Collision2D collision)
{
//给球体一个反作用力
Ball ball=collision .gameObject.GetComponent<Ball>();
if(ball != null )
{
Vector2 normal =collision.GetContact(0).normal;
ball.AddForce(-normal*this.bounceStrength);
}
}
}
3.Ai脚本
using UnityEngine;
public class ComputerPaddle : Paddle
{
public Rigidbody2D ball;
private void FixedUpdate()
{
//判断球是否往电脑这边移动
if (this.ball.velocity.x > 0.0f)
{
//球拍开始往球落点的位置移动
//判断球的落点位置在球拍上方 还是下方
//给电脑赋值移动速度
if (this.ball.position.y > this.transform.position.y)
{ _rigidbody.AddForce(Vector2.up * this.speed);
} else if (this.ball.position.y < this.transform.position.y)
{ _rigidbody.AddForce(Vector2.down * this.speed);
}
}
else
{
if (this.transform.position.y > 0.0f)
{
_rigidbody.AddForce(Vector2.down * this.speed);
}
else if (this.transform.position.y < 0.0f)
{
_rigidbody.AddForce(Vector2.up * this.speed);
}
}
}
}
给Ai添加反作用力脚本 (与玩家球拍的脚本同一个)
using UnityEngine;
public class BouncySurface : MonoBehaviour
{
public float bounceStrength;
private void OnCollisionEnter2D(Collision2D collision)
{
//给球体一个反作用力
Ball ball=collision .gameObject.GetComponent<Ball>();
if(ball != null )
{
Vector2 normal =collision.GetContact(0).normal;
ball.AddForce(-normal*this.bounceStrength);
}
}
}
3.左右墙体脚本
规则:当球体碰到对方墙面时,自己得一分。
所以我们要对左右墙体添加脚本判定当球体碰到对面墙体时执行的命令。
using UnityEngine;
using UnityEngine.EventSystems;
public class ScoringZone : MonoBehaviour
{
//碰撞触发器
public EventTrigger.TriggerEvent scoreTrigger;
private void OnCollisionEnter2D(Collision2D collision)
{
Ball ball = collision.gameObject.GetComponent<Ball>();
if (ball != null)
{
BaseEventData eventData=new BaseEventData(EventSystem.current);
this.scoreTrigger.Invoke(eventData);
}
}
}
最后我们设置管理脚本
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public Ball ball;
private int _playerScore;
private int _computerScore;
//ui 分值
public Text plauerScoreText;
public Text computerScoreText;
public Paddle ComputerPaddle;
public Paddle PlayerPaddle;
public void PlayerScore()
{
//玩家积分累计
_playerScore++;
//ui界面
this.plauerScoreText .text = _playerScore.ToString();
RestRound();
}
public void CpmputerScore()
{
//电脑积分累计
_computerScore++;
//ui反馈
this.computerScoreText.text = _computerScore.ToString();
RestRound();
}
private void RestRound()
{
this.ball.AddStartingForce();
this.ball.ResetPosition();
this.PlayerPaddle.ResetPosition();
this.ComputerPaddle.ResetPosition();
}
}
我们还需要将得分的ui表示出来
因为我是用的2023版本unity我个人使用的text文本 是旧版
txt设置
值得一提的是我们在创建完游戏管理器后不要忘记添加对应的积分类(两面墙都需要添加对应的类)
有什么不懂的问题可以直接私聊我或者评论也可以。