In Unity object from ObjectPool appears with rotation of last appeared object

In my game i have ship that shoots lasers, i made shooting using ObectPool, but got stuck with lasers wrong direction. I make them move by adding RelativeForce, but they move sideways forward. I tryed to instantiate objects with _placeToSpawn.transform instead of its position, but instantiated object are childs of Ship and when ship moves lasers move too.
How to set force direction of activated laser right?
Video of wrong moving lasers:

ObjectPool code:

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

public class ObjectPool : MonoBehaviour
{
    [SerializeField] private GameObject _placeToSpawn;
    [SerializeField] private int _amount;

    private List<GameObject> _pool = new();

    protected void Initialize(GameObject prefab)
    {
        for (int i = 0; i < _amount; i++)
        {
            GameObject spawned = Instantiate(prefab, _placeToSpawn.transform.position, Quaternion.identity);
            spawned.SetActive(false);

            _pool.Add(spawned);
        }
    }

    protected bool TryGetObject(out GameObject result)
    {
        result = _pool.FirstOrDefault(gameObject => gameObject.activeSelf == false);

        return result != null;
    }
}

Ship shooting objects from ObjectPool code:

using UnityEngine;

[RequireComponent(typeof(AudioSource))]
public class ShipShooter : ObjectPool
{
    [SerializeField] private UIdata _score;
    [SerializeField] private GameObject _laser;
    [SerializeField] private AudioClip _shootAudio;
    [SerializeField] private AudioSource _indestructibleSource;
    [SerializeField] private float _laserSpeed;
    [SerializeField] private float _laserShootVolume;

    private AudioSource _source;
    private bool _laserShooted = false;

    private void Start()
    {
        Initialize(_laser);
        _source = GetComponent<AudioSource>();
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            CreateLaser();
        }
    }

    private void CreateLaser()
    {
        if (TryGetObject(out GameObject laser))
        {
            SetLaser(laser);
        }

    }

    private void SetLaser(GameObject laser)
    {
        laser.SetActive(true);

        laser.transform.SetPositionAndRotation(transform.position, transform.rotation);
        laser.GetComponent<Rigidbody2D>().AddRelativeForce(Vector2.up * _laserSpeed);
        laser.GetComponent<Laser>().score = _score;
        laser.GetComponent<Laser>().source = _indestructibleSource;
        _source.PlayOneShot(_shootAudio, _laserShootVolume);
        _laserShooted = false;
    }
}

Nothing magic here… the same simple steps to success:

  • get the laser object
  • compute the direction you want it to face
  • set that direction

This also may just be another example of the extremely high costs and issues associated with object pooling / pools.

Good luck debugging!

https://discussions.unity.com/t/892797/10

https://discussions.unity.com/t/833104/2

1 Like

I did it in line 43, but rotation didn’t change for current laser

Why don’t you properly debug and check the value before and after, and try to understand what went wrong?
You can very easily trace the execution and re-check your assumptions.

2 Likes

Worked with this line code instead of 44 line:

laser.GetComponent<Rigidbody2D>().AddForce(transform.up * _laserSpeed);