Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question When I Make A Clone of my Prefab Only The First Instance Behaves As Expected.

Discussion in '2D' started by nelsonharrington17, May 14, 2024.

  1. nelsonharrington17

    nelsonharrington17

    Joined:
    Nov 22, 2023
    Posts:
    1
    Hi Guys

    I know the title probably doesn't explain stuff too well.

    if anyone could help I'd be eternally grateful.

    I'm currently making a hack and slash game, I've got to a point of doing the combat. Everything works with the one enemy but the moment I try to do it on an instatiated clone of my prefab the 'clone' acts as though it's code has already been updated. For example.

    I hit my first enemy > it dies

    I hit the second enemy (clone) and none of my old logic applies to it.

    I guess I am trying to find a way that makes it so every instance of a prefab behaviours in exactly the same way even if other gameobjects from the same prefab have been altered.

    I understand basic amounts of how prefabs work but from my knowledge, each clone so run off a clone of each component, including the scripts attached to it?

    I believe some of the issue comes from the way I edit the GameObjects my code is attached to.

    Here is how I reference the prefabs.

    My way of calling methods in my player script ( i.e. when I hit the enemy) - My enemy script is called "EnemyMovement"


    void Update()
    {

    EnemyHitAndDeath = GameObject.FindObjectOfType<EnemyMovement>();


    Then this is called via my collider trigger


    private void OnTriggerEnter2D(Collider2D other) {
    if (isAttacking && !playerInAirAttackingEnemy && other.CompareTag("Enemy"))
    {
    EnemyHitAndDeath.PlayerHitEnemy();
    SwordHitEffects.PlaySwordHitAnimations(gameObject);
    Debug.Log("Attack1");


    Which then triggers this inside my enemy


    public void PlayerHitEnemy()
    {
    myAnimController.SetBool("IsHit", true);
    IHaveBeenHit = true;

    if (!originalvelocityStored)
    {
    originalVelocity = rb2D.velocity;
    originalvelocityStored = true;
    }

    rb2D.velocity = originalVelocity;

    if (!StopAddingAcceleration)
    {
    if(transform.position.x > playerPos)
    {
    rb2D.AddForce(new Vector2(1f,0) * knockBackForce);
    StopAddingAcceleration = true;

    // This works!! //
    //rb2D.AddForce(new Vector2 (0, VerticalHit), ForceMode2D.Impulse);
    }
    else
    {
    rb2D.AddForce(new Vector2(-1f,-0) * knockBackForce);
    StopAddingAcceleration = true;
    }
    }
    StartCoroutine(SwitchBackAfterHit());
    }


    And so on.

    I just need it to be so every instance of the enemy operates independantly of the other one but for the life of me I can't work it out. I was considering using multiple copies of my prefab in my assets but with the way I have created my code, I would have to find a way to trigger the method inside all of the enemies or more so trigger the method relevant to that script which seems like a bad way to do it.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,321
  3. dstears

    dstears

    Joined:
    Sep 6, 2021
    Posts:
    209
    I think we will need to see how you are Instantiating your prefabs to see if you are somehow affecting the asset rather than the clone as Kurt suggested.

    This code may also be problematic:
    Code (CSharp):
    1. EnemyHitAndDeath = GameObject.FindObjectOfType<EnemyMovement>();
    If this script is on the enemy that you are hitting, then you should probably get it in your OnTriggerEnter2D function so that you are sure you are getting the instance of the enemy you just hit. You don't know which instance you are going to get when using FindObjectOfType and there are multiple instances.

    Code (CSharp):
    1. private void OnTriggerEnter2D(Collider2D other)
    2. {
    3.     if (isAttacking && !playerInAirAttackingEnemy && other.CompareTag("Enemy"))
    4.     {
    5.         EnemyMovement EnemyHitAndDeath = other.GetComponent<EnemyMovement>();
    6.         EnemyHitAndDeath.PlayerHitEnemy();
    7.         ...