AtomicGameEngine / AtomicGameEngine

The Atomic Game Engine is a multi-platform 2D and 3D engine with a consistent API in C++, C#, JavaScript, and TypeScript

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[AtomicNET] Game fixed updating pauses when creating nodes

Alan-FGR opened this issue · comments

commented

I've found a pretty serious showstopping bug; consider the following SSCCE:

using AtomicEngine;

public class Game : AppDelegate
{
    public static Input input;
    private Scene scene;
    
    public override void Start()
    {
        input = GetSubsystem<Input>();

        scene = new Scene();
        scene.CreateComponent<Octree>();
        
        var camNode = scene.CreateChild("cameraNode");
        camNode.Position = new Vector3(0,0,-5);
        GetSubsystem<Renderer>().SetViewport(0, new Viewport(scene, camNode.CreateComponent<Camera>()));

        var physicsWorld2D = scene.CreateComponent<PhysicsWorld2D>();
        physicsWorld2D.Gravity = Vector2.UnitY*-0.1f;
        
        var node = scene.CreateChild("node");
        node.CreateComponent<RigidBody2D>().BodyType = BodyType2D.BT_DYNAMIC;
        
        SubscribeToEvent<UpdateEvent>(MyUpdate);

        physicsWorld2D.DrawCenterOfMass = true;
        var dbgr = scene.CreateComponent<DebugRenderer>();
        SubscribeToEvent<PostRenderUpdateEvent>(e => physicsWorld2D.DrawDebugGeometry(dbgr, false));
    }

    private void MyUpdate(UpdateEvent eventdata)
    {
        if (input.GetMouseButtonDown(Constants.MOUSEB_LEFT))
        {
            scene.CreateChild();
        }
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        Application.Run<Game>(args);
    }
}

When you click the mouse a new node will be created each frame, however, note how the object 'freezes' on screen, i.e.: while you're holding the mouse, gravity won't affect the object. I've tried doing other stuff when the mouse is pressed to see if the same would happen, but it didn't.
PS: I found this issue in a 2D shooter I was trying to make: each bullet fired would pause the game for that frame.

commented

@darrylryan suggested that the Input could be the culprit, but that's not true, here you go:

    int ticks = 0;
    private void MyUpdate(UpdateEvent eventdata)
    {
        ticks++;
        if (ticks>500)
        {
            scene.CreateChild();
        }
    }

just sit back and watch the world burn :trollface:

commented

Any input on this? When you do the same as above from C++, it works as it's supposed to:

static Input* input;
Scene* scene;
DebugRenderer* dbgr;
PhysicsWorld2D* physicsWorld2D;

void Game::Start()
{
    input = GetSubsystem<Input>();

    scene = new Scene(context_);
    scene->CreateComponent<Octree>();
        
    auto camNode = scene->CreateChild("cameraNode");
    camNode->SetPosition(Vector3(0,0,-5));
    GetSubsystem<Renderer>()->SetViewport(0, new Viewport(context_, scene, camNode->CreateComponent<Camera>()));

    physicsWorld2D = scene->CreateComponent<PhysicsWorld2D>();
    physicsWorld2D->SetGravity(Vector2::UP*-0.1f);
        
    auto node = scene->CreateChild("node");
    node->CreateComponent<RigidBody2D>()->SetBodyType(BT_DYNAMIC);
        
    SubscribeToEvent(E_UPDATE, ATOMIC_HANDLER(Game, MyUpdate));

    physicsWorld2D->SetDrawCenterOfMass(true);
    dbgr = scene->CreateComponent<DebugRenderer>();
    SubscribeToEvent(E_POSTRENDERUPDATE, ATOMIC_HANDLER(Game, MyPostRenderUpdate));
}

void Game::MyUpdate(StringHash eventType, VariantMap& eventData)
{
    if (input->GetMouseButtonDown(MOUSEB_LEFT))
    {
        scene->CreateChild();
    }
}

void Game::MyPostRenderUpdate(StringHash eventType, VariantMap& eventData)
{
    physicsWorld2D->DrawDebugGeometry(dbgr, false);
}

Somehow when you created nodes in C#, it blocks the subsequent fixed stepping :(... this is a pretty serious showstopping bug 😖

@Alan-FGR we haven't run into this. I think it may be because of the specific nature of the products we build. We don't create any new nodes after our initial load process, We also don't use input at all outside of debug, but then you've determined that's not really a factor.

commented

Update:
UrhoSharp doesn't have this problem:

using Urho;
using Urho.Urho2D;

class MySample : Application {
    protected override void Start ()
    {
        Scene scene = new Scene();
        scene.CreateComponent<Octree>();
        
        var camNode = scene.CreateChild("cameraNode");
        camNode.Position = new Vector3(0,0,-5);
        var cam = camNode.CreateComponent<Camera>();
        Viewport viewport = new Viewport(CurrentContext, scene, cam, null);
        Renderer.SetViewport(0, viewport);
        
        var physicsWorld2D = scene.CreateComponent<PhysicsWorld2D>();
        physicsWorld2D.Gravity = Vector2.UnitY*-0.1f;
        
        var node = scene.CreateChild("node");
        node.CreateComponent<RigidBody2D>().BodyType = BodyType2D.Dynamic;

        Update += args =>
        {
            if (Input.GetMouseButtonDown(MouseButton.Left))
            {
                var b = scene.CreateChild().CreateComponent<RigidBody2D>();
                b.BodyType = BodyType2D.Dynamic;
                b.SetLinearVelocity(Vector2.UnitX);
            }
        };

        physicsWorld2D.DrawCenterOfMass = true;
        var dbgr = scene.CreateComponent<DebugRenderer>();
        Engine.PostRenderUpdate += args =>
        {
            physicsWorld2D.DrawDebugGeometry(dbgr, false);
        };
    }

    public MySample(ApplicationOptions options) : base(options){}
}


namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            new MySample(new ApplicationOptions(".")).Run();
        }
    }
}