-
Posts
79 -
Joined
-
Last visited
Content Type
Blogs
Forums
Store
Gallery
Videos
Posts posted by Skrakle
-
-
Yeah, what you have works, but you aren't setting your IScript entity member anywhere and I don't see where you are using it either. I think if you try to use it you'd get an error saying it was NULL.
You're right, entity does return NULL when first instantiated and SetUserData((void*)script); seems to set it as i'm able to view the entity position in the callback trigger.
-
The entity is in the parent class and parameter is passed in the PlayerScript constructor: PlayerScript() :IScript(entity) {} // default constructor
hmm, how do you create these objects? I assume like:
IScript* e;
e = new PlayerScript();
This would mean you aren't attaching any LE entity because inside PlayerScript ctor you are passing it's parent "entity" variable to it's parent (which entity will be null) and assigning it to itself (which again will be null). How are you ever getting the entity in question to that variable? This should compile but I would think it would give a run-time error.
Is this working for you? I know I've been out of the C++ game for some time but this seems strange.
In App::Start, after loading the entity, i use this:
IScript* script = new PlayerScript(); entities[0]->SetUserData((void*)script); entities[0]->AddHook(Entity::CollisionHook, (void*)CollisionHook);
I've tested the callbacks, they are being triggered. I'd like to know if when the app terminates, do i have to remove the hooks or LE does it automatically?
-
PlayerScript() :IScript(entity) {}
What is entity here? It's been awhile since I've worked heavily in C++ but I believe your PlayerScript ctor also needs the Entity entity in it's param list.
PlayerScript(Entity* entity) : IScript(entity)
{
}
The entity is in the parent class and parameter is passed in the PlayerScript constructor:
PlayerScript() :IScript(entity) {} // default constructor
You also have to make your functions in the base class "pure virtual". This is done by setting them to 0.
The function from the base-class should read:
virtual void Collision(Entity* entity, float* position, float* normal, float speed)=0;
For more info on the difference between virtual and pure virtual refer to http://stackoverflow.com/questions/1306778/c-virtual-pure-virtual-explained
That did it, i'll go read up on the link you provided, thanks a lot!
-
I removed virtual from the PlayerScript class like you suggested and left it in the parent and i'm still getting unresolved externals.
class IScript { protected: Entity* entity; public: IScript(Entity* e) { entity = e; } virtual void Collision(Entity* entity, float* position, float* normal, float speed); }; class PlayerScript : public IScript { public: PlayerScript() :IScript(entity) {} void Collision(Entity* entity, float* position, float* normal, float speed) { } };
-
I'm trying to use these classes to write my scripts:
#ifndef _ISCRIPT_H #define _ISCRIPT_H // derive your "script" classes from this interface to make it an "entity script" class IScript { protected: Entity* entity; public: IScript(Entity* e) { entity = e; } virtual void Collision(Entity* entity, float* position, float* normal, float speed); virtual void Draw(); virtual void DrawEach(Camera* camera); virtual void PostRender(Camera* camera); virtual void UpdateMatrix(); virtual void UpdatePhysics(); virtual void UpdateWorld(); }; // example "script" that you would have to make class PlayerScript : public IScript { public: PlayerScript() :IScript(entity) {} // default constructor virtual void Collision(Entity* entity, float* position, float* normal, float speed) { } virtual void Update() { } }; // define each global hook function here and the same idea applies to all. cast the user data on the entity // to IScript and if it's not NULL call that instance method void CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed) { IScript* script = (IScript*)entity0->GetUserData(); if (script != NULL) { script->Collision(entity1, position, normal, speed); } } void UpdateWorldHook(Entity* entity) { IScript* script = (IScript*)entity->GetUserData(); if (script != NULL) { script->UpdateWorld(); } } void UpdatePhysicsHook(Entity* entity) { IScript* script = (IScript*)entity->GetUserData(); if (script != NULL) { script->UpdatePhysics(); } } #endif
I'm getting multiple unresolved external errors: LNK2001: unresolved external symbol "public: virtual void __thiscall IScript::Collision(class Leadwerks::Entity *,float *,float *,float)" (?Collision@IScript@@UAEXPAVEntity@Leadwerks@@PAM1M@Z) C:\Users\Admin\Documents\Leadwerks\Projects\TestProject\Projects\Windows\App.obj TestProject
APP.CPP
#include "App.h" #include "IScript.h" using namespace Leadwerks; App::App() : window(NULL), context(NULL), world(NULL), camera(NULL) {} App::~App() { delete world; delete window; } bool App::Start() { window = Leadwerks::Window::Create("TestProject", 250, 0, 1024, 768); context = Context::Create(window); world = World::Create(); IScript* script = new PlayerScript(); }
What am i missing?
-
now you need to tell me how you want to compile dynamic c++ code for your entities.
I really think what you plan to do is possible in lua. But i just don´t know what your requirements etc. are. There where already some good examples like the class-like system in lua, the loadstring if you really want to generate dynamic functions etc.
What i meant by doing everything in c++ is doing the game entirely in c++. Here's an example of what i'm trying to do.
Let's say i have 100 characters in my map, one of them is controllable by the player. The remaining 99 doesn't need the code blocks where it scans for keys to move/jump around and the character that the player controls doesn't need code blocks for AI. During the game, if the player ends up controlling another character, it is when i would generate and set a new script (by string) with new generated code. That being said, i don't want to end up with 100's of lua files.
I have other alternatives, i just wondered if this was possible.
-
I'm aware of entity:SetScript but it won't help since i'm looking to generate dynamic lua code when loading entities. I'll probably just end up ditching lua and do everything in c++ instead.
Thanks for the replies!
-
You can try to use loadstring.
But it is very expensive since your code will basically be compiled at runtime and error handling will be a lot harder. So only do this if you really have to.
Additionally I am not sure if you really can attach a Start method to an entity with this.
f = loadstring("self.index = self.index - 1")
f()
Does this mean that once a script has been set to an entity, we can't change it for another at runtime?
Common Script
function Script:Start() self.myFunc = nil end function Script:UpdateWorld() -- call myFunc self.myFunc() end -- define somwhere else custom functionality to myFunc entity.script.myFunc = function() -- do whatever end entity1.script.myFunc = function() --do something different here end entity2.script.myFunc = function() --do something completely different here end
That would solve my issue, although i would need to set those functions from c++ which is why a SetScriptFromString method would be simpler in my case. How can i add/modify lua variables/functions from c++?
-
I'm looking for a way to set the entity script by sending a string rather than loading a lua file, something like:
entity::SetScriptWithString("function Script:Start()\nself.index=-1\nend");
I'm building a rpg and have lots of characters which will require customized functions in their script and will be generated in-game depending how the character is configured.
Is there some way to do that?
-
hmmm i think there is a mixup somewhere... you are loading the 'dwarfmale_run' model but you are trying to find the 'dwarfmale_stand_bone'. In the model you posted there are no 'stand_bones' - only 'run_bones'. I am able to find the 'run_bone' no problem...
You're absolutely right, I can't believe i didn't notice that!
Thanks for noticing!
- 2
-
I copy/pasted the bone name from the editor.
Dwarf model: Dwarf fbx Weapon Weapon
entity={}; function App:Start() entity[0]=LoadModel("Models/Characters/Dwarf/dwarfmale_run.mdl","Char","Randgard",0,0,5.73,0.02,1,Collision.Trigger,Entity.CharacterPhysics,""); entity[0]:SetScript("Scripts/NPCS/player_character.lua"); weapons[0]=LoadModel("Weapons/axe_1h_hatchet_a_01.mdl","Weapon","Axe",0,0,0,0.02,0,Collision.None,Entity.RigidBodyPhysics,""); local child=entity[0]:FindChild("dwarfmale_stand_bone_RFingerPinky"); if (child) then weapons[0]:SetParent(child); weapons[0]:SetMatrix(entity[0]:GetMatrix()) end end
-
Thanks for the video link but it didn't help because i really need to attach it to a specific bone so my sword will follow/rotate correctly when my character walks or takes a swing and i haven't seen anything bone related in the tutorial. I forgot to mention that i'm loading my models in lua instead of placing it in the editor. I did place one so i can find the bone names.
-
I'm trying to add a weapon at a specific bone on my character but finding the child using bone name returns nil. I've also tried several other names in the hierarchy.
local child=self.entity:FindChild("dwarfmale_stand_bone_RFingerPinky");
-
Detecting if a character is on the ground or in the air is easy by using entity:GetAirborne()
-
Yes, i attached the collision script on all of them using SetScript like you previously suggested
-
The problem was detecting which character touched the ground and in the Script:Collision function, there's only one entity parameter and i needed to identify the model that touched the terrain entity. Since i'm using an array for my characters, i only needed to set an index value on top of the script and it is set when a model is loaded.
Script.entityIndex=-1; Script.entityJumping=0; function Script:Start() end function Script:Collision(entity, position, normal, speed) if (entity:GetClass()==20) then self.entityJumping=0; end if (entity.type == "char") then --self.component:CallOutputs("Collision") end end
-
I have a collision script attached to several models and i'm trying to detect whether their on the ground or in the air. Problem is, when a collision scene is detected, i don't know which entity touched down.
function Script:Collision(entity, position, normal, speed) if (entity:GetClass()==20) then -- terrain -- can jump end end
Edit: I was able to figure out a way using a Script.entityIndex variable in the collision script for each entity.
-
That's awesome! Thanks AggrorJorn!
-
I've created a pivot, attached script CollisionTriggers.lua and i loaded it. Now i'm trying to attach it to the entity. I've tried this:
App.lua
entity[0]={}; entity[0]=LoadEntity("Models/Characters/Dwarf/dwarfmale_run.mdl",10,0,-20,0.05,1,Collision.Character,Entity.CharacterPhysics); local parent=entity[0]:GetParent(); if (parent~=nil) then Prefab:Load("Prefabs/collisions_generic.pfb") end
CollisionTriggers.lua
function Script:Start() self.enabled=true end function Script:Collision(entity, position, normal, speed) if self.enabled then self.component:CallOutputs("Collision") end end function Script:Enable()--in if self.enabled==false then self.enabled=true self:CallOutputs("Enable") end end function Script:Disable()--in if self.enabled then self.enabled=false self:CallOutputs("Disable") end end
parent returns nil... How do i attach it to the entity?
-
I'm loading my entities in lua in App:Start() and i need to set script files for them, is there a way to assign them in lua?
I've tried something like entity.Script="Scripts/Objects/Triggers/CollisionTrigger.lua" but no luck.
-
I mean creating your character in the editor :
- choosing character in physics tab
- using SetInput in your code
Because if you use PhysicsSetPosition then Collision.Character is useless , and you are not using character controller specific behaviour and navmesh navigation.
Why don't you use SetINput in your code and make a physic characters controller in the editor ?
I can post some TPS code if you need.
That did the trick and I was able to set everything up at runtime since i didn't want to add the characters from the editor.
Thanks a lot!
-
Oh i see, i'll give that a try and i would prefer setting this when the game starts in App:Start() ; is there a way to set it using code?
Thanks!
-
Perhaps i'm stupid, but why don't you use Character Controller ?
If you mean setting the collision types then yes, i've tried entity:SetCollisionType(Collision.Character) as well. Right now i'm not concerned about colliding with other objects/entities because i was planning on using AABB for them, it's moving on the terrain's surface that i'm having a hard time with.
-
Thanks but it's not working. Also, i find SetForce very unpractical to move something, my character moves too fast and it seems that a value below 100 won't move it at all. So right now i'm at a loss, i have very little experience with 3D which is why i bought this and i'm surprised that i haven't found a sample project with an example about how that's done.
[c++] Scripts via callback (Rick's example)
in Programming
Posted
Ahh i see what you mean now, i would've scratched my head at some point wondering why the iscript entity would be null. So i added this in the PlayerScript:
And i'm setting it up like this:
It's all working now, thanks for noticing that!