AndrewBGS
Member
|
Object Parameters problems
I managed to reduce a lot of my problems to one issue;
Accessing the parameters used to create an object;
I want to store those parameters in order to use them later on to create an identical copy of the object.
Normally, I did this:
Game.ObjParamsPtr params;
void create(Game.ObjParams &obj)
{ params=&obj;
....
And this used to work. However, when the object is created from the code, not from the world, those parameters aren't correct anymore. Why? Where is the difference?
How should always get the correct parameters to re-create the object?
|
|
03-22-2014 07:01 PM |
|
Pixel Perfect
Member
|
RE: Object Parameters problems
Hi Andrew, when you say the parameters are not correct any more what exactly do you mean? Are the values corrupted or something?
I'm not exactly using the engine as its designed to be used so I'm not sure how helpful this might be but for what it is worth here is the code I use to spawn my NPCs when requested by the external AI engine.
I store the UIDs for my Model Objects against a type name and retrieve those at run time from my configuration manager. Ignore the EKI One commands as they are just interfacing with the external AI Engine as a data conduit, the Esenthel code starts from:
// Get the model UID and set the NPC object Type UID
Code:
void createEntityFromEKIMessage(const EKI_One::SystemMessage& message,
bool createAsAgent)
{
// Read requested entity configuration from message
const std::string& name = message.GetProperty<const std::string&>
(EKI_One::MessageTypes::CreateAgentProps::NAME.ID);
const std::string& type = message.GetProperty<const std::string&>
(EKI_One::MessageTypes::CreateAgentProps::TYPE.ID);
const EKI_One::Vector3d position = message.GetProperty<EKI_One::Vector3d>
(EKI_One::MessageTypes::CreateAgentProps::POSITION.ID);
const EKI_One::Vector3d facing = message.HasProperty
(EKI_One::Strings::HardcodedProperties::FACING) ?
message.GetProperty<EKI_One::Vector3d>
(EKI_One::Strings::HardcodedProperties::FACING) :
EKI_One::Vector3d::UNIT_X;
// Even pure AI entities are created via this mechanism so that the
// external application is in control of every entity created
// The isShared flag signals if this is a conventional or pure AI
// entity
const bool createGameEntity = message.GetProperty<bool>
(EKI_One::MessageTypes::CreateAgentProps::IS_SHARED.ID);
EKIDataSynchronizationChannel* newSyncCh = nullptr;
// Create a new game entity
if (createGameEntity)
{
// Get the model UID and set the NPC object Type UID
UID modelUID = configManager.getUIDData("npcModelList", type);
// Check we have a valid UID for the model
if(!modelUID.valid())
{
EKI_LOG("VS", EKI_One::Logger::INFO,
"createEntityFromEKIMessage: Unable to find the
model type " << type << " for NPC name: "
<< name,);
return;
}
// Get a pointer to the NPC model
Game::ObjParamsPtr obj=Game::Objs.ptrRequire(modelUID);
EKI_LOG("VS", EKI_One::Logger::INFO,
"createEntityFromEKIMessage: Creating NPC: " << name,);
// Create the new NPC object and return a pointer to it (This
// also adds it to the npcObjs collection
// by virtue of its type). Note the transformation of the z
// axis here
Game::Obj* myObj = Game::World.objCreateNear(*obj,
Matrix(obj->scale(), Vec(position.x,
position.y+1,-position.z)));
// We can cast the game object pointer to an npc pointer
m_pNPC = (npc*) myObj;
// Save the name
m_pNPC->setName(name);
// Create the AI engine data synchronization channel and add it
// to the sharedDataManager
newSyncCh = new EKIDataSynchronizationChannel(name, position,
facing , m_pNPC);
mSharedDataManager.Add(newSyncCh);
// Add the newly created NPC pointer to a map collection
m_mapNPCList.insert(std::pair<std::string,npc*>(name,m_pNPC));
}
// else the nullptr is passed which is exactly the necessary signal that
// this is an unshared, virtual entity
if (createAsAgent)
mAIEngine->CreateAgent(name, type, newSyncCh);
else
mAIEngine->CreateObject(name, type, newSyncCh);
}
|
|
03-22-2014 09:51 PM |
|
AndrewBGS
Member
|
RE: Object Parameters problems
I'm sorry, I think that might be a little too advanced for me, I don't seem able to understand too much :|.
I'm only using Esenthel, with c++. And all I wanted was an easy way to create another copy of an object; Why can't Greg give up that "no_copy_constructor" in his code...? :|
|
|
03-22-2014 10:36 PM |
|
Rubeus
Member
|
RE: Object Parameters problems
The reason for the "no_copy_constructor" is so you can take advantage of the enhance memory management features of the engine and it's containers, which I am finding very useful and under-appreciated.
You will have to post more code for anyone to be able to pinpoint the problem. It's very possible you are creating a pointer and it is getting deleted and you lose your data. Check your scopes and memory management. Also, remember some EE containers will change the memory addresses of the elements.
|
|
03-23-2014 12:15 AM |
|
Pixel Perfect
Member
|
RE: Object Parameters problems
I tend to agree with Rubeus on this one. We probably need to see more of your code.
However, if I understand what you've posted so far I suspect
Code:
Game.ObjParamsPtr params;
void create(Game.ObjParams &obj)
{ params=&obj;
....
implies you are copying the object params in the Create proc of your object class, which if this is the case will be updated for every instance of the object type placed in the level so you will end up with just a copy of the last one created and any parameters that were set against it.
What's more, if this objects has been subsequently deleted, you've maybe picked it up for example and added it to your inventory, then this pointer is probably no longer valid.
I'd have thought you would be better creating new objects in code from the original parent object as defined in the Editor.
i.e.
Code:
Game::ObjParamsPtr params=Game::Objs.ptrRequire(modelUID);
|
|
03-23-2014 01:38 AM |
|
AndrewBGS
Member
|
RE: Object Parameters problems
Rubeus, I still don't see why we aren't free to chose ourselves what to use; I found the EE memory containers very useful in most situations too, but in this particular one they impose too many constraints for it to be useful for me.
Pixel, I am in over my head with this issue already, and it boggles me how it only reproduces for manually created objects; However that last line of code sounds like what I'm looking for, but how can I get the model UID from within the model?
In the meantime, I'll try once again to adapt my code to using the esenthel containers and look more like the Tutorials..
|
|
03-23-2014 03:31 AM |
|
Pixel Perfect
Member
|
RE: Object Parameters problems
(03-23-2014 03:31 AM)AndrewBGS Wrote: ...
Pixel, I am in over my head with this issue already, and it boggles me how it only reproduces for manually created objects; However that last line of code sounds like what I'm looking for, but how can I get the model UID from within the model?
...
Go to your model object in the editor and right click and choose Properties. Click on the copy button next to the UID and paste into your code. This is a static ID which will never change.
I use a configuration system to pass all the critical UIDs for objects I want to create in code (along with lots of other configurable data) which I simply retrieve via a single call anywhere in my code but hard coding it in is quite acceptable!
Look at the tutorial:
14 Game Basics / 07 Dynamically Creating Objects
This will work if you already know what object type you are wanting to create. I can think of occasions where you might want to duplicate an object dynamically without knowing what it is beforehand so in this case you would have to know how to get the UID from an already existing instance. I seem to remember you can get the UID from the objectParams struct using the type() function. But again, this would only work if you have a valid objectParams struct at the time.
|
|
03-23-2014 09:44 AM |
|