Can not access global table from inside the coroutine

0

I tested with Lumberyard 1.8.0.1 and 1.9.0.1

When I comment out the --System.Log in coroutine, I always get the following error.

[Warning] [Script Error] Wrong parameter type. Function System.Log() expect parameter 1 of type String (Provided type String)

It seems, I cannot access any global table for both system provided or custom made in my Gem.

Is there any workaround for this matter? Thank you in advance.

    -- Scripts/main.lua
function OnInit()
local i = 0
System.Log("main.lua:OnInit before " .. i)
local co = coroutine.create(
function(f)
i = i + 1
-- System.Log("main.lua:OnInit in co " .. i) -- Error if comment out
end
)
coroutine.resume( co, co )
System.Log("main.lua:OnInit after " .. i)
end
asked 7 years ago223 views
8 Answers
0
Accepted Answer

Hi @REDACTEDUSER

Sorry for the delay. Are you using the component entity system or the legacy entity system? It looks like legacy, but I want to make sure. We're looking into the issue and will get back to you.

answered 7 years ago
0

Hi @REDACTEDUSER

Thank you for the reply.

Yes, I'm porting legacy system that built with CE2 and my main point of this issue is timing.

I would like to call the initialization process in my custom global table which implemented in C++ right after the system launched and before load the level.

In my old system, I used "Scripts/main.lua" for the initialization.

Please correct me if I was wrong, but my understanding of component system is that only working after level loaded and entity spawned.

And, I could not find the way to access the component system from the "Scripts/main.lua".

Please address me right method in Lumberyad to access the lua component before load the level.

Regards.

answered 7 years ago
0

Hi @REDACTEDUSER

answered 7 years ago
0

Hi @REDACTEDUSER

Here's an Gem that has an example of instantiating a dynamic slice that has a Lua file with a coroutine and loads a UI canvas before any level is loaded. Hopefully this will help you see what was not working.

4963-loadleveluigem.zip|attachment (23.4 KB)loadleveluigem.zip

By default it loads the auto_load.dynamic slice file in the dev/gems/LoadLevelUI/assets/slices folder, but you can change that in code or through the advanced properties for your project.

REMOVEDUPLOAD

answered 7 years ago
0

Hi @REDACTEDUSER

I updated my code to use the AssetDatabase and AssetCatalogRequestBus then working fine now.

Thank you very much.

        AZStd::string m_dynamicSlicePath = "slices/slicetest.dynamicslice";
AZ::Data::AssetId m_dynamicSliceAssetId;
void instantiateSlice()
{
AZ::Data::AssetCatalogRequestBus::BroadcastResult(m_dynamicSliceAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, m_dynamicSlicePath.c_str(), azrtti_typeid<AZ::DynamicPrefabAsset>(), true);
if (!m_dynamicSliceAssetId.IsValid())
{
return;
}
AZ::Data::Asset<AZ::Data::AssetData> asset = AZ::Data::AssetDatabase::Instance().GetAsset<AZ::DynamicPrefabAsset>(m_dynamicSliceAssetId);
AzFramework::SliceInstantiationTicket ticket;
AZ::Transform transform = AZ::Transform::Identity();
AzFramework::GameEntityContextRequestBus::BroadcastResult(ticket, &AzFramework::GameEntityContextRequestBus::Events::InstantiateDynamicSlice, asset, transform, nullptr);
AzFramework::SliceInstantiationResultBus::Handler::BusConnect(ticket);
}
answered 7 years ago
0

Hi @Soeda,

When I tested this in a component entity Lua script it ran OK, though I had to change System.Log to Debug.Log. Here is the full component entity script I tested:

	local test_coroutine = {
Properties = {
Debug = true
}
}
function test_coroutine:OnActivate()
local i = 0
Debug.Log("test_coroutine.lua:OnInit before " .. i)
local co = coroutine.create(
function(f)
i = i + 1
Debug.Log("test_coroutine.lua:OnInit in co " .. i)
end
)
coroutine.resume( co, co )
Debug.Log("test_coroutine.lua:OnInit after " .. i)
end
return test_coroutine

This printed out

test_coroutine.lua:OnInit before 0
test_coroutine.lua:OnInit in co 1
test_coroutine.lua:OnInit after 1
answered 7 years ago
0

Hi @Soeda,

The legacy Lua uses a different Lua context from the component entity Lua system so they can't talk to each other. The Lua script system is created and initialized before a level is loaded so you should be able to use it early on.

If you want to run Lua before a level is loaded then you will need to write some C++ to either create an entity with a Lua component, or spawn a dynamic slice that has an entity with a Lua component on it (recommended). Here's a link to the doc page that talks about creating and spawning dynamic slices in the editor and C++ http://docs.aws.amazon.com/lumberyard/latest/developerguide/dynamic-slices.html

I recommend creating a Gem using the Project Configurator (http://docs.aws.amazon.com/lumberyard/latest/userguide/gems-system-gems.html) that has a system component that does this in it's Activate method or make your system component an ISystemEventListener so you can listen for the ESYSTEM_EVENT_GAME_POST_INIT_DONE system event if your Lua logic needs the legacy game framework to be finished setting up.

answered 7 years ago
0

Hi @petrocket

or spawn a dynamic slice that has an entity with a Lua component on it (recommended).

Could you elaborate more on this?

As you suggested above, I tried to load the dynamicslice from Gem but so far no luck.

So, what is the correct way to load the dynamicslice from C++?

Do you have any example besides SpawnerComponent.cpp ?

Here is a part of my code.

        void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam) override
{
switch (event)
{
case ESYSTEM_EVENT_GAME_POST_INIT_DONE:
instantiateSlice();
break;
}
}
AZ::PrefabAssetHandler ph;
AZ::Data::Asset<AZ::DynamicPrefabAsset> dynamicSlice;
const AZ::Data::AssetFilterCB assetLoadFilterCB;
void instantiateSlice()
{
dynamicSlice.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom()));
ph.LoadAssetData(dynamicSlice, "slices/slicetest.dynamicslice", assetLoadFilterCB);
AzFramework::SliceInstantiationTicket ticket;
AZ::Transform transform = AZ::Transform::Identity();
EBUS_EVENT_RESULT(ticket, AzFramework::GameEntityContextRequestBus, InstantiateDynamicSlice, dynamicSlice, transform, nullptr);
}

I also share the zip file that contains all of my test data includes level, Gem, slice file and lua script for your reference.

https://www.dropbox.com/s/9g4n17l7yb95exn/dev.zip?dl=0

The slice file with Lua script working fine with SpawnerComponent from the editor or launcher, but failed to instantiate from my Gem.

Thank you in advance.

answered 7 years ago

This post is closed: Adding new answers, comments, and votes is disabled.