0
\$\begingroup\$

I've created a prefab of a stick object, the stick scales as in a mobile game stick hero, the thing is I want to instantiate the prefab, but the already instantiated stick somehow affects the prefab and sets its scale to the one of the previous stick, as well as deleting user input from the object. I think it's the problem with the prefab itself, as the code worked somewhat okay before making a prefab. Main code that invokes such behaviour is GameLogic script:

public class GameLogic : MonoBehaviour, IGameLogic
{
    [SerializeField] private CollisionDetection _collisionDetection; //collision point of a child gameobject with 2D collider attached
    [SerializeField] private UnityEvent _onLevelPassed;
    [SerializeField] private UnityEvent _onLevelFailed;//currently unused event 
    private void Awake()
    {
        
    }
    public void Fail()
    {
        _onLevelFailed?.Invoke(); //display Fail UI
    }
    public void Pass()
    {
        _collisionDetection.Reset();//resets collision detection script for the next pillar
        _onLevelPassed?.Invoke();//instantiates the stick at collision point
    }
    public void Determine() // calls the functions based on whether or not the stick collided with the pillar
    {
        IEnumerator GameLoop()
        {
            yield return new WaitForSeconds(.1f);
            if (_collisionDetection._collided)
                Pass();
            else
                Fail();
        }
        StartCoroutine(GameLoop());
    }
}

When the level is passed, I remove input from the stick, as well as move it to the point of collision and then I instantiate it, however the new stick gameobject seems to be a modified version of the previous stick even though I set it up to be a Transform of the stick with the needed scale and input. InputRemover script:

public class InputRemover : MonoBehaviour, IRemoveInput
{
    private InputHandler _inputHandler;
    private void Start()
    {
        _inputHandler = transform.GetComponent<InputHandler>();
    }
    public void RemoveInput()
    {
        Destroy(_inputHandler);
    }

    
}

The Scale script:

public class StickGrower : MonoBehaviour, IStickGrower
{
    [SerializeField] private float _speed;
    public void Grow()
    {
        var scale = transform.localScale;
        scale.y += _speed * Time.deltaTime;
        transform.localScale = scale;
    }
    
}

And the Instantiator script

public class StickInstantiator : MonoBehaviour, IStickInstantiator
{
    [SerializeField] private Transform _stickPrefab;
    [SerializeField] private UnityEvent _onStickInstantiated;
    private Vector2 _instantiationPosition;
    public void Instantiate()
    {
        Instantiate(_stickPrefab, _instantiationPosition, Quaternion.identity);
        _onStickInstantiated?.Invoke();
    }
}

InputRemover removes input when the stick has rotated, while the StickScale script scales the object on key down.

enter image description here enter image description here

\$\endgroup\$
3
  • 1
    \$\begingroup\$ You left out how you create a new stick in _stick.GetComponent<IStickInstantiator>().Instantiate(); And if _stick is your prefab, why are you calling _stick.GetComponent<IStickMover>().Move(_collisionDetection._collisionPosition); on the prefab and not the current instance of the stick? \$\endgroup\$
    – Zibelas
    Nov 10, 2022 at 15:02
  • \$\begingroup\$ Thank you for pointing that out, I will add the changes in a few minutes. \$\endgroup\$
    – koogel
    Nov 10, 2022 at 15:25
  • \$\begingroup\$ Thank for your comment, basically I understood what is happening, the object gets instantiated with the parents scale and then the previous stick gets moved, but that still doesn't explain the fact that input handler is gone. \$\endgroup\$
    – koogel
    Nov 10, 2022 at 16:08

1 Answer 1

0
\$\begingroup\$

It looks like you're not capturing a reference to the new instance of the prefab you spawned. So when you invoke your events, you're invoking them on the original prefab, not the spawned instance.

You probably want to do something a bit more like this:

public class StickInstantiator : MonoBehaviour, IStickInstantiator
{
    [SerializeField] private UnityEvent _onStickInstantiated;
    private Vector2 _instantiationPosition;
    public void Instantiate()
    {
        // Instantiate a copy, and hold a reference to that copy.
        StickInstantiator instance = Instantiate(this, _instantiationPosition, Quaternion.identity);

        // Invoke the event on the copy, not on the original.
        instance._onStickInstantiated?.Invoke();
    }
}

But you have not shown us the full configuration of the Stick prefab, including the StickInstantiator component in the inspector, so it's still difficult to say for sure. This is why I asked you to share a Minimal Complete verifiable example. A good question leaves nothing undefined that we'd need to ask you follow-up questions to clarify.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .