Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Player sometimes lags/glitches and jumps very high when instantiating prefab beneath it

Discussion in 'Scripting' started by phantom_x404, Aug 8, 2020.

  1. phantom_x404

    phantom_x404

    Joined:
    Apr 26, 2020
    Posts:
    26
    Hello,
    I am trying to spawn prefabs beneath the player using the following script(more explanation below the script):

    Code (CSharp):
    1. using System.Collections;
    2.     using System.Collections.Generic;
    3.     using UnityEngine;
    4.     using UnityEngine.UI;
    5.     using UnityEngine.EventSystems;
    6.  
    7.     public class Spawn : MonoBehaviour
    8.     {
    9.         public float jumpForce;
    10.         public Transform SpawnPoint;
    11.         public GameObject Prefab;
    12.  
    13.         public Transform player;
    14.  
    15.         float timeCounter;
    16.  
    17.         // Start is called before the first frame update
    18.         void Start()
    19.         {
    20.  
    21.         }
    22.  
    23.         IEnumerator waitSpawn()
    24.         {
    25.             yield return new WaitForSeconds(0.2921f);
    26.             Instantiate(Prefab, SpawnPoint.position, SpawnPoint.rotation).transform.parent = GameObject.Find("Player").transform;
    27.         }  
    28.         // Update is called once per frame
    29.         void Update()
    30.         {
    31.             if (player.transform.position.y < 12f)
    32.             {
    33.                 if (player.transform.position.y > -4f)
    34.                 {
    35.  
    36.                     timeCounter += -1 * Time.deltaTime; //to set the time before player can touch screen again
    37.  
    38.                     if ((Input.touchCount > 0))
    39.                     {
    40.                         foreach (Touch touch in Input.touches) //so that it does not continue going up if screen is continuously touched
    41.                         {
    42.                             if (touch.phase == TouchPhase.Began && !(EventSystem.current.IsPointerOverGameObject(touch.fingerId)))
    43.                             {
    44.                                 if (timeCounter < 0)
    45.                                 {
    46.                                     timeCounter = 0.29f; // Or whatever delay you want
    47.                                     GetComponent<Rigidbody>().AddRelativeForce(Vector3.up * jumpForce);
    48.                                     StartCoroutine(waitSpawn());  
    49.                                 }
    50.                             }
    51.                         }
    52.                     }
    53.                 }
    54.             }
    55.  
    56.             if (Input.GetMouseButtonDown(0))
    57.             {
    58.                 if (timeCounter < 0)
    59.                 {
    60.                     timeCounter = 0.29f; // Or whatever delay you want
    61.                     GetComponent<Rigidbody>().AddRelativeForce(Vector3.up * jumpForce);
    62.                     StartCoroutine(waitSpawn());
    63.                 }
    64.             }
    65.     }
    I make the player jump using add force whenever the screen is tapped or the mouse is clicked so that the object does not spawn right under the player, causing it to glitch and fly really high, I also tried to add a pause before the player can spawn objects again, but this still happens sometimes.
    I would appreciate if someone told me a way to fix this, code examples are greatly appreciated, I am a beginner so this way I can learn some more too. Thank You!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,780
    When you Instantiate something that is already overlapping in the physics system, you essentially surprise the physics system with a sudden massive collision problem it has to solve and it can only do so with forces.

    The collision rules say the player can't be inside the object, so the physics system begins computing a massive force to squirt the player out.

    Instead, make sure the player is not overlapping with the instantiated object's position (including collider) before you spawn it. Or otherwise deconflict it some way. OR... you can spawn the object much further below the player, and then use the Rigidbody
    .MovePosition()
    call to move it into place smoothly (using a coroutine or in Update()) under the player, giving the player time to get out of the way.

    Either way , don't startle the Physics system. Think what would happen if a car suddenly spawned right where you were standing... you'd have to shoot out to one side pretty quickly.
     
  3. phantom_x404

    phantom_x404

    Joined:
    Apr 26, 2020
    Posts:
    26
    Thanks for replying, in order to not startle the physics system, I have put the spawn position below the player(not inside of it), and then I made the spawn position a child of maiin player in order to move the spawn position along with it. I will try using RigidBody.MovePosition() and keep you updated
     
    Kurt-Dekker likes this.