Search Unity

Question Transform.position of pooled object resetting to prefab value the frame after it spawns

Discussion in 'Scripting' started by somuchforpathos, Feb 14, 2024.

  1. somuchforpathos

    somuchforpathos

    Joined:
    Jan 28, 2022
    Posts:
    17
    Hi,

    I'm having an issue where prefabs spawned in with an object pooler are resetting to their prefab position the frame after they spawn in as shown below. The kicker is this only happens at lower frame rates, I have to limit my FPS below 60 to reliable reproduce it. At higher frame rates it works as intended.

    Pooler issue.png

    Here is my code for the object pooler, nothing else sets a ball's transform.position except here when the ball is spawned.

    Code (CSharp):
    1.  
    2. private void MultiBall(PlayerController player, GameObject mirrorObject)
    3. {
    4.     if (player.multiBallActive)
    5.     {
    6.         for (int i = 0; i < powerUpInfo.multiBallCount; i++)
    7.         {
    8.             // get a pooled ball object
    9.             GameObject ballObject = ballPool.objectPool.Get();
    10.  
    11.             // Store rigidbody
    12.             Rigidbody ballRb = ballObject.GetComponent<Rigidbody>();
    13.  
    14.             Debug.Log("Player " + player.playerID + " got a MultiBall. Ball spawned at " + ballObject.transform.position);
    15.  
    16.             // Assign the Player that is spawning the ball to newly spawned ball
    17.             ballObject.GetComponent<PlayerTracker>().SetCurrentPlayer(player.gameObject);
    18.  
    19.             // assign it to the ball object in the hierarchy
    20.             ballObject.transform.parent = ballContainer.transform;
    21.  
    22.             // spawn the balls above the player's block
    23.             ballObject.transform.position = new Vector3(player.transform.position.x, player.transform.position.y + 1, player.transform.position.z);
    24.  
    25.             Debug.Log("Player " + player.playerID + " set MultiBall position to " + ballObject.transform.position);
    26.  
    27.             // enable trail
    28.             ballObject.GetComponent<TrailRenderer>().enabled = true;
    29.  
    30.             // Add to the active ball count
    31.             player.activeBalls++;
    32.  
    33.             // Add ball to player's balls list
    34.             player.balls.Add(ballObject);
    35.  
    36.             // get the ball's rigidbody and give it a vertical velocity with a randomised direction on the x axis. I have honestly no idea why the y axis needs to be a negative to go upwards \o/
    37.             ballRb.velocity = new Vector3(Random.Range(-powerUpInfo.multiBallDirection, powerUpInfo.multiBallDirection), -1, 0).normalized * playerInfo.ballDefaultSpeed;
    38.  
    39.             Debug.Log("Player " + player.playerID + " MultiBall has a velocity of " + ballObject.GetComponent<Rigidbody>().velocity);
    40.         }
    41.  
    42.         // If Mirror is active spawn balls from there too
    43.         if (player.mirrorActive)
    44.         {
    45.             for (int i = 0; i < powerUpInfo.multiBallCount; i++)
    46.             {
    47.                 // Get a pooled ball object
    48.                 GameObject ballObject = ballPool.objectPool.Get();
    49.  
    50.                 // Store rigidbody
    51.                 Rigidbody ballRb = ballObject.GetComponent<Rigidbody>();
    52.  
    53.                 Debug.Log("Player " + player.playerID + " got a MirrorBall. Ball spawned at " + ballObject.transform.position);
    54.  
    55.                 // Assign the ball to the player
    56.                 ballObject.GetComponent<PlayerTracker>().SetCurrentPlayer(player.gameObject);
    57.  
    58.                 // assign it to the ball object in the hierarchy
    59.                 ballObject.transform.parent = ballContainer.transform;
    60.  
    61.                 // set start position just above the mirror's block
    62.                 ballObject.transform.position = new Vector3(mirrorObject.transform.position.x, mirrorObject.transform.position.y + 1, mirrorObject.transform.position.z);
    63.  
    64.                 Debug.Log("Player " + player.playerID + " set MirrorBall position to " + ballObject.transform.position);
    65.  
    66.                 // Enable trail
    67.                 ballObject.GetComponent<TrailRenderer>().enabled = true;
    68.  
    69.                 // Add to the active ball count
    70.                 player.activeBalls++;
    71.  
    72.                 // Add ball to player's balls list
    73.                 player.balls.Add(ballObject);
    74.  
    75.                 // get the ball's rigidbody and give it a vertical velocity with a randomised direction on the x axis. I have honestly no idea why the y axis needs to be a negative to go upwards \o/
    76.                 ballRb.velocity = new Vector3(Random.Range(-powerUpInfo.multiBallDirection, powerUpInfo.multiBallDirection), -1, 0).normalized * playerInfo.ballDefaultSpeed;
    77.  
    78.                 Debug.Log("Player " + player.playerID + " MirrorBall has a velocity of " + ballObject.GetComponent<Rigidbody>().velocity);
    79.             }
    80.         }
    81.  
    82.         player.multiBallActive = false;
    83.     }
    84. }
    I found this thread with someone having the same problem as me unfortunately the fix that worked for them didn't for me https://www.reddit.com/r/Unity3D/comments/10gk5xh/20222_transformposition_being_reset_to_prefab/

    Anybody have any idea what might be causing this?
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,907
    Move the Rigidbody, not the Transform.
     
    somuchforpathos likes this.
  3. somuchforpathos

    somuchforpathos

    Joined:
    Jan 28, 2022
    Posts:
    17
    Thank you for the quick reply. I tried setting the rigidbody position instead but the same thing happened but in reverse, it spawned at the prefab position then warped to the correct position the next frame. So figured if I set the transform and the rigidbody position on spawn it wouldn't warp around, and et voila it works.

    Code (CSharp):
    1. // spawn the balls above the player's block
    2. Vector3 spawnPos = new Vector3(player.transform.position.x, player.transform.position.y + 1, player.transform.position.z);
    3. ballObject.transform.position = spawnPos;
    4. ballRb.position = spawnPos;
    5.  
    Thanks again, I've been banging my head against the wall with this one.