@yraiv

Почему у объекта может импульс применяться неправильно?

Делаю игру, где пули отлетают от стен при столкновении с ними под зеркальным углом. Если смотреть через Debug Line, то траектории при выстреле и при отражении идеально как надо, но вот полёт объекта меня огорчает. В момент выстрела пуля летит как надо, но при столкновении с стеной, она не отражается туда, куда смотрит её новое направление, а просто останавливается или иногда с огромной скоростью улетает вбок, в чём причина?
public void OnCollisionEnter2D(Collision2D collision)
    {
        if(collision.gameObject.tag == "Wall")
        {

            Vector2 inDirection = rb.velocity;
            Vector2 inNormal = collision.contacts[0].normal;
            Vector2 newVelocity = Vector2.Reflect(inDirection, inNormal);       
            Debug.DrawLine(transform.position,newVelocity, Color.red,5);
            GetComponent<Rigidbody2D>().AddForce(newVelocity * BulletSpeed, ForceMode2D.Impulse);
            if (CountCollision <= 7)
            {
                CountCollision++;
            }
            else
            {
                Destroy(this.gameObject);
            }
        }
  • Вопрос задан
  • 51 просмотр
Решения вопроса 1
K0TlK
@K0TlK
Буллю людей.
Тебе не нужна здесь физика и AddForce тем более. Просто двигай пулю, изменяя позицию, лови столкновение через OnCollisionEnter и отражай направление движения.

Пуля

using UnityEngine;

namespace Bullets
{
    [RequireComponent(typeof(Rigidbody2D), typeof(Collider2D))]
    public class Bullet : MonoBehaviour, IBullet
    {
        [SerializeField] private float _speed = 5f;
        [SerializeField] private int _damage = 10;
        [SerializeField] private int _maxReflections = 5;

        private Rigidbody2D _rigidbody;
        private Vector2 _direction = Vector2.zero;

        private void Awake()
        {
            _rigidbody = GetComponent<Rigidbody2D>();
            _rigidbody.isKinematic = true;
            _rigidbody.useFullKinematicContacts = true;
        }
        
        public void Shoot(Vector2 direction)
        {
            _direction = direction.normalized;
        }

        private void FixedUpdate()
        {
            if (_direction == Vector2.zero) return;

            var deltaMovement = _direction * _speed * Time.deltaTime;

            _rigidbody.MovePosition(_rigidbody.position + deltaMovement);
        }

        private void OnCollisionEnter2D(Collision2D other)
        {
            if (other.transform.TryGetComponent(out IDamageable damageable))
            {
                damageable.ApplyDamage(_damage);
                Destroy();
                return;
            }

            var normal = other.GetContact(0).normal;
            Reflect(normal);
        }

        private void Destroy()
        {
            Destroy(gameObject);
        }

        private void Reflect(Vector2 normal)
        {
            if (_maxReflections - 1 == 0) Destroy();

            _maxReflections--;
            _direction = Vector2.Reflect(_direction, normal).normalized;
        }
    }
}



И убогий скрипт оружия

using UnityEngine;

namespace Bullets
{
    public class SomeGun : MonoBehaviour
    {
        [SerializeField] private Bullet _bulletPrefab;
        [SerializeField] private Transform _bulletOrigin;
        [SerializeField] private Camera _camera;

        private void Update()
        {
            LookAtMouse(Input.mousePosition);

            if (Input.GetKeyDown(KeyCode.Mouse0))
            {
                Shoot();
            }
        }

        private void LookAtMouse(Vector3 mousePosition)
        {
            var gunScreenPosition = _camera.WorldToScreenPoint(transform.position);
            
            var direction = mousePosition - gunScreenPosition;

            direction.Scale(new Vector3(1, 1, 0));

            transform.up = direction;
        }

        private void Shoot()
        {
            var bullet = Instantiate(_bulletPrefab, _bulletOrigin.position, Quaternion.identity);

            bullet.Shoot(transform.up);
        }
    }
}



Физика здесь абсолютно не нужна, как и рейкасты.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы