Jump to content

Skrakle

Members
  • Posts

    79
  • Joined

  • Last visited

Posts posted by Skrakle

  1. SetUserData((void*)script); wouldn't be setting your IScripts entity variable.

     

    I think you are able to view then entity position in the callback trigger because your callback function has the same name for it's parameter as your member variable ie. "entity" and when inside a function it'll use the function parameter if there is a name conflict.

     

    So when you do something like the below notice your function parameter is also named entity just like your member variable. Inside that function when you use the entity variable it's referring to the parameter 'entity' not your class member 'entity'. Inside your callbacks trying changing it to this->entity and I think it would fail.

     

    You might not even need that member variable 'entity' honestly. I always used it because I set the callbacks inside the base class instead of outside of it like you are doing. I wanted my code that looped over each entity to be clean of that stuff and have the class be self contained in what it does. If you were to do that then you'd have to also pass the entity into your child classes so you can pass it along to your base class.

     

    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:

    void SetEntity(Entity* entity) {
    ent = entity;  // i renamed the member for ent
    }
    

     

     

    And i'm setting it up like this:

    IScript* script = new PlayerScript();
    script->SetEntity(entities[0]);
    

     

    It's all working now, thanks for noticing that!

  2. 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.

  3. 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?

  4. 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!

  5. 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)
       {
       }
    
    };
    

  6. 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?

  7. 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.

  8. 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++?

  9. 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?

  10. 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!

     

    happy_dwarf.png

    • Upvote 2
  11. 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
    

     

     

    bone_name.jpg

  12. 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.

  13. 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");
    

  14. 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
    

  15. 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.

  16. 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?

  17. 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.

  18. 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!

  19. Perhaps i'm stupid, but why don't you use Character Controller huh.png ?

     

    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.

  20. 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.

×
×
  • Create New...