0 votes

I am creating a simple 2D top down moving games, where different kinds of obstacles come from top, player has to avoid obstacles and move towards coins to collect. In this case I am creating obstacles programmatically and adding it to scene tree using Instance method as follows.

var enemy1 = EnemyKindOne.instance()
add_child(enemy1)

I am creating enemy for every 1 second and adding it to scene tree. At the time of creating and adding enemy there is a noticeable jerk. Because of this game is not looking smooth, How to solve this?

in Engine by (106 points)
edited by

Could you share more of your script?

Also, what do you mean by "jerk"? Is it a framerate drop, or a visual glitch?

You might want to check the "remote" tab of your scene (see here: https://docs.godotengine.org/en/stable/tutorials/debug/overview_of_debugging_tools.html#remote-in-scene-dock) while the game is running and check that you are not spawning in more obstacles than you think.

This could be down to some code in the enemy's _ready() function or possibly any nodes that can cause lag such as a particle node with preprocess set higher than 0.

Here is the code for cloning obstacles in MainScene.gd

export (PackedScene) var HoriLeft       #Obstacle type 1
export (PackedScene) var HoriLeftSmall  #Obstacle type 2
export (PackedScene) var HoriRight      #Obstacle type 3
export (PackedScene) var HoriRightSmall #Obstacle type 4

var HoriLeftIns : EnemyClass  #is a Script attached to enemy
var HoriLeftSmallIns : EnemyClass
var HoriRightIns : EnemyClass
var HoriRightSmallIns : EnemyClass

func _ready():
    HoriLeftIns = HoriLeft.instance()
    HoriLeftSmallIns  = HoriLeftSmall.instance()
    HoriRightIns  = HoriRight.instance()
    HoriRightSmallIns  = HoriRightSmall.instance()


func _on_MobTimer_timeout():
    if player:
        var block_type = Globals.blocks_list[randi()%Globals.blocks_list.size()]
        if block_type == "ls":
            var enemy : EnemyClass = HoriLeftSmallIns.duplicate()
            get_tree().get_root().call_deferred("add_child", enemy)
            enemy.move_enemy(player.position)
        elif block_type == "rs":
            var enemy : EnemyClass = HoriRightSmallIns.duplicate()
            get_tree().get_root().call_deferred("add_child", enemy)
            enemy.move_enemy(player.position)
        elif block_type == "lh":
            var enemy : EnemyClass = HoriLeftIns.duplicate()
            get_tree().get_root().call_deferred("add_child", enemy)
            enemy.move_enemy(player.position)
        elif block_type == "rh":
            var enemy : EnemyClass = HoriRightIns.duplicate()
            get_tree().get_root().call_deferred("add_child", enemy)
            enemy.move_enemy(player.position)
        elif block_type == "ls_rs":
            var enemy1 : EnemyClass = HoriLeftSmallIns.duplicate()
            get_tree().get_root().call_deferred("add_child", enemy1)
            enemy1.move_enemy(player.position)
            var enemy2 : EnemyClass = HoriRightSmallIns.duplicate()
            get_tree().get_root().call_deferred("add_child", enemy2)
            enemy2.move_enemy(player.position)
        elif block_type == "ls_rl":
            var enemy1 : EnemyClass = HoriLeftSmallIns.duplicate()
            get_tree().get_root().call_deferred("add_child", enemy1)
            enemy1.move_enemy(player.position)
            var enemy2 : EnemyClass = HoriRightIns.duplicate()
            get_tree().get_root().call_deferred("add_child", enemy2)
            enemy2.move_enemy(player.position)
        elif block_type == "rs_ll":
            var enemy1 : EnemyClass = HoriLeftIns.duplicate()
            get_tree().get_root().call_deferred("add_child", enemy1)
            enemy1.move_enemy(player.position)
            var enemy2 : EnemyClass = HoriRightSmallIns.duplicate()
            get_tree().get_root().call_deferred("add_child", enemy2)
            enemy2.move_enemy(player.position)

Here is a code for Obstacle Script

extends Area2D

class_name EnemyClass

var move = false
var move_position = Vector2()
var screen_size
signal enemy_killed
onready var sprite = $Sprite

func _ready():
    screen_size = get_viewport_rect().size
    sprite.modulate = Globals.enemy_color

func _process(delta):
    if move and Globals.State == Globals.GameState.Running:
        position.y += Globals.speed * delta

func move_enemy(dest_position):
    #enemy starting position
    var randomPosition = Vector2()
    var random = RandomNumberGenerator.new()
    random.randomize()
    #Enemy moving towards player
    move_position = dest_position
    move = true

Enemy does not have any particle effect in it.

It may be due to the amount of elif in _on_MobTimer_timeout(). Try using a match statement so you basically use integers instead of "ls" "rs" strings. Other than that I can't see anything else that would cause lag.

Give some time, I will check and write my feedback.

Thanks, Some improvements are there when replacing elif with match statement, but still noticeable lag is there.

Have you tried the profiler? https://docs.godotengine.org/en/stable/tutorials/debug/debugger_panel.html?highlight=profiler#profiler

Start the profiler, get some enemies to spawn, then stop it. You can then scroll down the list of functions and see if maybe some of your functions take up more time than expected.

Can anyone give me best example for cloning and adding enemy node into scene tree. Because I tried loading all me enemy scenes and instancing those under the auto load class of GDScript. But jittery motion is still there?

Here is the video of my issue

Note : I am getting this issue only while running on android device.

Finally I have profiled my game and taken screen shot of it. Can you find out the cause of issue. Thanks in advance.

Screen shot here

The profiling result looks normal. Since it occurs only on Android, have you tried using GLES2 as a renderer?

Am using GLES3.

Have you tried using GLES2. You can select it in the top right of the editor.

Tried that also. Not working. Finally I found solution for the jittery problem. I have removed all floating point value assigned for properties like Collision2D,Texture Scalling, and for Visibility notifier, now everything works fine with int value. Seems if fast moving object assigned with floating point value(3.463) for Collision2D,Visibility notifier and texture makes jittery. Better use rounded int value(3).

Thanks for the discussion on my post. Finaly I wasted 3 days of time just for floating point value. But worth it.

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.