Выход ракетки за границы сцены в игре пинг понг юнити
При создании 2D игры по типу пинг понг на Юнити возникла проблема связанная с частичным выходом двух ракеток за поля сцены, причем если обе ракетки медленно подходят к нижнему и верхнему краю сцены они не выходят за границы, но с увеличением скорости их движения иногда такое происходит. Код отвечающий за движение ракеток ниже:
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Threading;
using UnityEngine;
public class Pad : MonoBehaviour
{
[SerializeField]
float speed;
float height;
string inpt;
public bool isRightPad;
// Вызывается в начале игры, перед первым обновлением кадра
void Start()
{
height = transform.localScale.y;
}
public void Init(bool isRight)
{
isRightPad = isRight;
Vector2 pos = Vector2.zero;
// Обрабатываем изменение позиции ракетки. Для левой и правой ракетки - отдельно.
if (isRight)
{
pos = new Vector2(GameManager.topRight.x, 0);
pos -= Vector2.right * transform.localScale.x;
inpt = "PadRight";
} else {
pos = new Vector2(GameManager.bottomLeft.x, 0);
pos += Vector2.right * transform.localScale.x;
inpt = "PadLeft";
}
transform.position = pos;
transform.name = inpt;
}
void Update()
{
// Блокируем выход ракетки за края экрана, обрабатываем изменение позиции на экране
float move = UnityEngine.Input.GetAxis(inpt) * Time.deltaTime * speed;
if(transform.position.y < GameManager.bottomLeft.y + height/2 && move < 0)
{
move = 0;
}
if (transform.position.y > GameManager.topRight.y - height / 2 && move > 0)
{
move = 0;
}
transform.Translate(move * Vector2.up);
}
}
В чем может быть проблема и какие возможны варианты ее решения? Спасибо.
Ответы (1 шт):
Автор решения: Yaroslav
→ Ссылка
Статика тут не нужна и ее легко избежать.
using UnityEngine;
public class Board : MonoBehaviour
{
[SerializeField] private Vector2 _size = new Vector2(10, 6);
[SerializeField] private Vector2 _ancore = Vector2.zero;
public Vector2 Size => _size;
public Vector2 Ancore => _ancore;
}
using UnityEngine;
public class Pad : MonoBehaviour
{
[HideInInspector] public float Velocity = 0;
[SerializeField] private float _speed = 1;
[SerializeField] private Vector2 _size = new Vector2(0.5f, 1);
[Space]
[SerializeField] private Board _board;
private Transform _transform;
private void Start()
{
_transform = transform;
ToSideBorder();
}
private void Update()
{
Move();
}
private void Move ()
{
_transform.position += new Vector3(0, Velocity*_speed*Time.deltaTime, 0);
CheckBorders();
}
private void CheckBorders ()
{
Vector3 position = _transform.position;
float min = _board.Ancore.y+(-_board.Size.x+_size.y)*0.5f;
float max = _board.Ancore.y+(_board.Size.x-_size.y)*0.5f;
position.y = Mathf.Clamp(position.y, min, max);
_transform.position = position;
}
private void ToSideBorder ()
{
if (_transform.position.x < _board.Ancore.x)
_transform.position = _board.Ancore+new Vector2((-_board.Size.x+_size.x)*0.5f, 0);
else
_transform.position = _board.Ancore+new Vector2((_board.Size.x-_size.x)*0.5f, 0);
}
}
Управление это отдельная ответственность.
using UnityEngine;
[RequireComponent(typeof(Pad))]
public class PadPlayerController : MonoBehaviour
{
[SerializeField] private string _axisName = "Vertical";
private Pad _pad;
private void Start ()
{
_pad = GetComponent<Pad>();
}
private void Update()
{
float axis = Input.GetAxis(_axisName);
_pad.Velocity = axis;
}
}