Дрожание объекта (Андроид)

Рейтинг: -1Ответов: 1Опубликовано: 21.07.2023

Здравствуйте проблема такая что, мяч работает на пк нормально! А когда билдишь на андроид, то мяч фризит/дрожит/отстает по кадрово непонятно что это!

Видео прикрепляю https://youtu.be/GR2SWx15XHE

И код

using UnityEngine;
using UnityEngine.EventSystems;

public class BallController : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
    public HappyManager happyManager;
    private bool isDragging = false;
    private bool isOnTarget = false;
    private Rigidbody2D rb;
    private Vector2 dragStartPos;
    private Vector2 initialPosition;
    public float initialVelocity = 5f; // Начальная скорость мяча при броске

    public float throwForce = 5f;
    public AudioSource wallAudioSource;

    public bool IsMoving
    {
        get { return rb.velocity.magnitude > 0.1f; }
    }

    private void Start()
    {
        Physics2D.velocityThreshold = 100f; // Устанавливаем более высокий порог скорости для уменьшения дрожания
        rb = GetComponent<Rigidbody2D>();
        initialPosition = transform.position;
    }


    private void Update()
    {
        if (isDragging)
        {
            Vector2 touchPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            transform.position = new Vector3(touchPos.x, touchPos.y, transform.position.z);
        }
        else if (rb.velocity.magnitude > 0.1f)
        {
            // Применяем затухание к скорости мяча
            rb.velocity *= 0.99f; // Затухание в 1% от текущей скорости

            // Ограничиваем максимальную скорость мяча
            rb.velocity = Vector2.ClampMagnitude(rb.velocity, throwForce);

            // Ограничиваем перемещение мяча в пределах стены
            if (!IsInsideWall())
            {
                Vector2 ballPosition = transform.position;
                Vector2 wallPosition = GetWallPosition();
                Vector2 wallSize = GetWallSize();

                float minX = wallPosition.x - wallSize.x / 2f;
                float maxX = wallPosition.x + wallSize.x / 2f;
                float minY = wallPosition.y - wallSize.y / 2f;
                float maxY = wallPosition.y + wallSize.y / 2f;

                ballPosition.x = Mathf.Clamp(ballPosition.x, minX, maxX);
                ballPosition.y = Mathf.Clamp(ballPosition.y, minY, maxY);

                transform.position = ballPosition;
            }
        }
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        isDragging = true;
        dragStartPos = Camera.main.ScreenToWorldPoint(eventData.position);

        rb.velocity = Vector2.zero;
        rb.isKinematic = true;
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        isDragging = false;

        Vector2 dragEndPos = Camera.main.ScreenToWorldPoint(eventData.position);
        Vector2 throwDirection = (dragEndPos - dragStartPos).normalized;
        rb.velocity = throwDirection * initialVelocity;

        rb.isKinematic = false;

        if (!IsInsideWall())
        {
            Vector2 ballPosition = transform.position;
            Vector2 wallPosition = GetWallPosition();
            Vector2 wallSize = GetWallSize();

            float minX = wallPosition.x - wallSize.x / 2f;
            float maxX = wallPosition.x + wallSize.x / 2f;
            float minY = wallPosition.y - wallSize.y / 2f;
            float maxY = wallPosition.y + wallSize.y / 2f;

            ballPosition.x = Mathf.Clamp(ballPosition.x, minX, maxX);
            ballPosition.y = Mathf.Clamp(ballPosition.y, minY, maxY);

            transform.position = ballPosition;
        }

        CheckIfOnTarget();
    }

     public void OnDrag(PointerEventData eventData)
    {
        if (isDragging)
        {
            Vector2 touchPos = Camera.main.ScreenToWorldPoint(eventData.position);
            transform.position = new Vector3(touchPos.x, touchPos.y, transform.position.z);
        }
    }
    private bool IsInsideWall()
    {
        Vector2 ballPosition = transform.position;
        Vector2 wallPosition = GetWallPosition();
        Vector2 wallSize = GetWallSize();

        float minX = wallPosition.x - wallSize.x / 2f;
        float maxX = wallPosition.x + wallSize.x / 2f;
        float minY = wallPosition.y - wallSize.y / 2f;
        float maxY = wallPosition.y + wallSize.y / 2f;

        return ballPosition.x >= minX && ballPosition.x <= maxX && ballPosition.y >= minY && ballPosition.y <= maxY;
    }

    private Vector2 GetWallPosition()
    {
        GameObject wall = GameObject.FindGameObjectWithTag("Wall");
        return wall != null ? wall.transform.position : Vector2.zero;
    }

    private Vector2 GetWallSize()
    {
        GameObject wall = GameObject.FindGameObjectWithTag("Wall");
        return wall != null ? wall.GetComponent<Collider2D>().bounds.size : Vector2.zero;
    }

    private void CheckIfOnTarget()
    {
        // Здесь может быть логика для проверки, попал ли мяч в цель после его броска
    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            isOnTarget = true;
        }
    }

    private void OnTriggerExit2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            isOnTarget = false;
        }
    }

    // Проверяем, если мяч выходит за пределы объекта "wall", применяем обратную силу
    private void OnTriggerStay2D(Collider2D other)
    {
        if (other.CompareTag("Wall"))
        {
            Vector2 ballPosition = transform.position;
            Vector2 wallPosition = other.transform.position;
            Vector2 wallSize = other.bounds.size;

            float minX = wallPosition.x - wallSize.x / 2f;
            float maxX = wallPosition.x + wallSize.x / 2f;
            float minY = wallPosition.y - wallSize.y / 2f;
            float maxY = wallPosition.y + wallSize.y / 2f;

            if (ballPosition.x < minX || ballPosition.x > maxX)
            {
                rb.velocity = new Vector2(-rb.velocity.x, rb.velocity.y); // Меняем направление по горизонтали
                ballPosition.x = Mathf.Clamp(ballPosition.x, minX, maxX); // Запрещаем мячу выходить за границы стены
                wallAudioSource.Play(); // Воспроизводим звук при соприкосновении с границей по горизонтали
            }

            if (ballPosition.y < minY || ballPosition.y > maxY)
            {
                rb.velocity = new Vector2(rb.velocity.x, -rb.velocity.y); // Меняем направление по вертикали
                ballPosition.y = Mathf.Clamp(ballPosition.y, minY, maxY); // Запрещаем мячу выходить за границы стены
                wallAudioSource.Play(); // Воспроизводим звук при соприкосновении с границей по вертикали
            }

            transform.position = ballPosition;
        }
    }
}

Ответы

▲ -2

Нашёл решение, может быть пригодиться на будущее!

Создаёшь скрипт FrameRate

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FrameRate : MonoBehaviour
{
    // Start is called before the first frame update
    void Awake()
    {
        Application.targetFrameRate = 60;
    }

}

И прикрепляешь к камере на сцене. Всё игра идёт плавно!