Jump to content

How do i get info about entity in script?


Andy Gilbert
 Share

Recommended Posts

We assume camera is a global variable declared like that in App.lua

it's global so you can access it from any other script :

 

 

camera = Camera:Create()

camera:SetRotation(35,0,0)

camera:Move(0,0,-30)

 

On your goblinAI script or characterAI script or other :

You can access your position character by calling the good function :

xpos=self.entity:GetPosition().x

zpos=self.entity:GetPosition().z

xpos=self.entity:GetPosition().x

 

camera:SetPosition(xpos,5,zpos-5)

 

Because camera was not delcared as self.camera or local.camera, it's a global variable so you can access it and change the position with some values of the character position.

 

Perhaps i don't understood what you really need ?

Stop toying and make games

Link to comment
Share on other sites

Okay so there are a handful of ways to access an entities information from Lua scripts.

 

1. If the script is attached to the entity you want to access.

 

In this case you just call self.entity and it refers to the entity that the script is attached to.

 

For example, in the player script (which is attached to the barbarian model) there is a call:

 


self.entity:SetInput(self.currentyrotation,move,0,0,false,self.maxAcceleration)

 

This part confused me when I first started Lua scripting: self.entity refers to the entity that it is attached to, which is the barbarian model. So in my mind it's like calling "Model:SetInput(...)"

 

If you had a script attached to a camera and you wanted to call a camera specific function "Set Range" the function call would be:

 

self.entity:SetRange(range.x,range.y)

 

this is because the entity that the script is attached to is a camera so the call is essentially camera:SetRange(...)

 

2. If the entity is declared in another Lua Script (And was not declared as local)

 

In App.lua context is created as

self.context=Context:Create(self.window,0)

 

to access this from another script you could call

App.context:GetWidth()

 

3. You want access to an entity that is in the editor and the script is not attached to.

 

The simplest way to do this is to declare an entity variable in your script and then select it in the editor.

 

For example in the camera class at the near the top of the script there is a variable "target" and it is declared as

 

Script.target = nil --Entity "Target"

 

By using "--Entity" tag after declaring the variable the editor will now have an entity field in the script tab.

post-5181-0-65154400-1362350327_thumb.png

 

You finally can drag and drop an entity from the scene tab to the entity field

post-5181-0-78708100-1362350365_thumb.png

 

4. Various other ways

 

World::ForEachEntityInAABBDo

World::ForEachVisibleEntityDo

 

For the specific example of a camera, I would go with option 2 and declare it in app.lua.

 

self.camera = Camera:Create()

 

then access it from other scripts as

 

App.camera

  • Upvote 1
Link to comment
Share on other sites

Wow, escellent stuff! And yes this stuff should be put in the docs somwhere, but also good thats its coming out like this in the forums for later searches! :)

 

But defo document it all, it will only get asked again...and again no doubt!

 

Thanks

Andy

The good news about computers is that they do what you tell them to do. The bad news is that they do what you tell them to do.

 

Leadwerks Game-Ready 3D Models:https://sellfy.com/gib3d

Link to comment
Share on other sites

By using "--Entity" tag after declaring the variable the editor will now have an entity field in the script tab.

 

This is one of the most usefull new features of LE3 for custom template scripts :)

(even if some other engines propose thats)

Stop toying and make games

Link to comment
Share on other sites

Could anyone explain the same principle for C++? I have entity's in the editor but am not sure how to reference these same entities from the API

THis is sort of a gray area right now. Originally I had one function overload for Map::Load that allowed you to pass a pointer to a callback function, that would get called for each entity loaded. However, when we decided to allow multiple system and object hooks, we saw this idea was not good enough, and that a system hook for loading maps should be used instead, and I just haven't done that yet. I will add this in the next build.

 

So you will just call System::AddHook(System::LoadMapEntityHook,myfunc) and then you can access each entity that gets loaded in a map. You can identify entities by name, or just have general load functions that process them in whichever way you like.

 

C++ tends to be very good when you have a system of entities that all behave a certain way. If you were making a tournament shooter or FPS game, C++ classes are very good for handling the AI. Lua tends to excel when you have a lot of interactions, especially if those interactions are one-time events that only get used in a single map. It's also great for rapid prototyping.

 

Demanding games should use a combination of C++ for the core classes, and then use Lua for simple interactions like doors, switches, events, etc. We use Lua for our examples because it's easier to demonstrate ideas without a lot of setup code, but if I were making Darkness Awaits unto a full game, I would probably move the Ai code to C++.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

In C++ am I able to just load a scene and then loop over all entities loaded like in LE2? If NOT then be sure to add a byte pointer to all hooks so that I can pass my C++ class pointer because all my stuff is in classes and these normal C function hooks are not and require global access to do anything inside unless I can pass in my object pointer.

 

Very often entities in a map are just stand in's and get replaced with other things in code. For example in my game I have entities for camera start menu, camera start fight 1, camera point at menu, player start 1, player start 2, player start 3 depending on which random 1-3 locations. So these just give me position & rotation and I load object classes and do other things with the information in C++.

Link to comment
Share on other sites

In Leadwerks 2, all entities were made the child of a scene pivot. The programmer was expected to unparent all the pivot's children after load, because to do otherwise would result in extreme rendering inefficiency. In Leadwerks 3, a hook should be used instead. I can see a good argument for adding an optional void* parameter, but it's too much to add right now.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

As long as you aren't forcing things to be global to do anything inside this hook then I'll be fine. Adding a byte* would aid in this as I can then pass my object pointer that loaded the map, to callback to, so it can hold the C++ objects I'm loading.

 

void MyMapLoader(Entity* e, byte* obj)
{
MenuState* menu = (MenuState*)obj;

obj->LoadMap(e);
}

class MenuState
{
private:
list<Actor*> _enemies;
public:
void LoadMap(Entity* e)
{
if(e->GetProperty("name") == "enemy_start_1")
_enemies.push_back(new Actor(e));
}

MenuState()
{
Scene::Load("mymap.map", (byte*)this);
}
};

 

 

I can see a good argument for adding an optional void* parameter, but it's too much to add right now.

 

*sigh* Dammit. Now I have to redesign parts of my game when I port it over so that I can have a global entry into this callback. Your engine is C++, having a standard C callback is not good design for C++ imo. Hope this is in soon because it's a pretty big requirement for C++'ers. We have to be able to load maps and access entities on the map. I'll get figuring out a good way to load maps from C++ objects and get entities in this callback back into my C++ object sad.png You will not derail me from my mission!

 

 

http://www.leadwerks.com/werkspace/page/documentation/_/command-reference/map/mapload-r510

Link to comment
Share on other sites

OK got a solution to hack around this (which will work for me and my FSM):

 



// called once for each entity in the map
void ForEachEntityInMapLoadedGameMenu(Entity* e)
{
  // pass along to the state instance that called the load
  MapLoader::GetInstance().GetCurrentState()->LoadMapEntity(e);
}

// global entry used just to store the current state trying to load the map and pass control back to a function of the state
class MapLoader
{
private:
  State* _currentState;
  MapLoader(){}
public:
  static MapLoader& GetInstance()
  {
     static MapLoader instance;

     return instance;
  }

  void SetCurrentState(State* state)
  {
     _currentState = state;
  }

  State* GetCurrentState()
  {
     return _currentState;
  }
};


class GameMenu : public State
{
private:
  // we idle animate the hero for the main menu
  Actor* _hero;
public:
  GameMenu()
  {
     // setup game menu's hook to load the map
     System::AddHook(System::LoadMapEntityHook, ForEachEntityInMapLoadedGameMenu);

     // setup this state as the current map loader
     MapLoader::GetInstance().SetCurrentState(this);

     // because of the hook added above the C callback will be called for each entity
     Map::LoadMap("mymap.map");
  }

  // called back 
  virtual void LoadMapEntity(Entity* e)
  {
     if(e->Properties("name") == "hero")
        _hero = new Actor(e);
  }
};

 

This should keep the global entry minimized and still pass control back to my state that loaded the map.

Link to comment
Share on other sites

If LoadMap could return an Entity (like in LE2) or had an second parameter with an entity list (std::vector, entity* ...) that would be really handy.

 

I dont like these C Callbacks and try to avoid them but sometimes you dont have a choice (WinAPI MessageHandler, LoadMap etc.).

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...