Rick Posted January 1, 2010 Share Posted January 1, 2010 File Name: Pi-Character v 0.1 File Submitter: Rick File Submitted: 01 Jan 2010 File Category: Lua Scripts Very early version of my character objects. Place it in your scene and go to the settings and give it a model. It creates a character controller and receives some messages to help it move. This works in conjunction with Pi-CharacterKeyboardControls. Click here to download this file Quote Link to comment Share on other sites More sharing options...
VicToMeyeZR Posted January 16, 2010 Share Posted January 16, 2010 Hey. Rick, I thought I would help a little with this. require("scripts/class") require("Scripts/hooks") local class=CreateClass(...) function class:InitDialog(grid) self.super:InitDialog(grid) group = grid:AddGroup("Character") group:AddProperty("model", PROPERTY_FILE, "GMF Files (*.gmf):gmf", "", "Model Files") group:AddProperty("controller_height", PROPERTY_FLOAT, "Controller Height") group:AddProperty("controller_radius", PROPERTY_FLOAT, "Controller Radius") group:AddProperty("controller_step_height", PROPERTY_FLOAT, "Controller Step Height") group:AddProperty("controller_max_slope", PROPERTY_FLOAT, "Controller Max Slope") group = grid:AddGroup("Animations") group:AddProperty("idle_start", PROPERTY_INTEGER, "Idle Start Frame") group:AddProperty("idle_end", PROPERTY_INTEGER, "Idle End Frame") group:AddProperty("walk_start", PROPERTY_INTEGER, "Walk Start Frame") group:AddProperty("walk_end", PROPERTY_INTEGER, "Walk End Frame") group:AddProperty("run_start", PROPERTY_INTEGER, "Run Start Frame") group:AddProperty("run_end", PROPERTY_INTEGER, "Run End Frame") group:AddProperty("jump_start", PROPERTY_INTEGER, "Jump Start Frame") group:AddProperty("jump_end", PROPERTY_INTEGER, "Jump End Frame") group:AddProperty("crouch_start", PROPERTY_INTEGER, "Crouch Start Frame") group:AddProperty("crouch_start", PROPERTY_INTEGER, "Crouch End Frame") group:Expand(1) end function class:CreateObject(model) local object=self.super:CreateObject(model) object.model = model object.height = tonumber(object:GetKey("controller_height", "1.8")) local radius = tonumber(object:GetKey("controller_radius", "0.4")) local step = tonumber(object:GetKey("controller_step_height", "0.5")) local slope = tonumber(object:GetKey("controller_max_slope", "45.0")) object.oneTime = false object.controller = CreateController(object.height, radius, step, slope) object.controller:SetMass(1.0) EntityType(object.controller, 1) -- set the position of the controller to the editor object local pos = object.model:GetPosition() object.controller:SetPosition(Vec3(pos.x, pos.y + (object.height/2), pos.z)) object.characterModel = nil object.move = 0 object.strafe = 0 object.rotate = 0 object.jump = 0 object.moveSpeed = 2 object.strafeSpeed = 2 object.framestart = 0 object.frameend = 0 function object:StartAnimations(movement) object.framestart = self.model:GetKey(movement .. "_start") return object.framestart end function object:EndAnimations(movement) object.frameend = self.model:GetKey(movement .. "_end") return object.frameend end function object:SetKey(key,value) if key=="model" then local pos = self.model:GetPosition() self.characterModel = LoadModel("abstract::"..value) self.characterModel:SetPosition(Vec3(pos.x, pos.y, pos.z)) else return self.super:SetKey(key,value) end return 1 end function object:GetKey(key,value) if key=="" then else return self.super:GetKey(key,value) end return value end function object:Update() if object.frameend ~= 0 then object:StartAnimations("idle") object:EndAnimations("idle") else object.framestart = 0 object.frameend = 100 end if self.characterModel ~= nil then if object.frameend ~= 0 then object.frame = math.fmod(AppTime()/35, object.frameend-object.framestart)+object.framestart Animate(self.characterModel, object.frame, 1.0, 0, true) end end if GetGlobalString("mode") == "GAME_MODE" then if self.characterModel ~= nil then if object.oneTime == false then object.oneTime = true object.controller:SetPosition(object.model:GetPosition()) end self.controller:Update(self.rotation, self.move, self.strafe, self.jump, 5000, 10) self.jump = 0 -- reset -- the character model must follow the controller -- for the 3rd person camera to work we must also move the object model, which is stupid self.model:SetPosition(Vec3(object.controller.position.x, object.controller.position.y - (object.height/2), object.controller.position.z)) self.characterModel:SetPosition(Vec3(object.controller.position.x, object.controller.position.y - (object.height/2), object.controller.position.z)) end else -- constantly update the controller to the object in the editor local pos = object.model:GetPosition() object.controller:SetPosition(Vec3(pos.x, pos.y + (object.height/2), pos.z)) -- make the model follow if self.characterModel ~= nil then self.characterModel:SetPosition(Vec3(pos.x, pos.y, pos.z)) end end end function object:UpdateMatrix() end --[[ function object:LockKeys(model) self.super:LockKeys() end ]]-- --[[ function object:UnlockKeys(model) self.super:UnlockKeys() end ]]-- --[[ function object:UpdateMatrix() end ]]-- --[[ function object:Reset() end ]]-- --[[ function object:SetTarget(target,index) end ]]-- --[[ function object:Collision(entity,position,normasl,force,speed) end ]]-- function object:ReceiveMessage(message,extra) if message == "move" then object.move = tonumber(extra) * self.moveSpeed object:GetAnimations("walk") elseif message == "jump" and object.controller:IsAirborne() == 0 then object.jump = tonumber(extra) object:GetAnimations("jump") elseif message == "strafe" then object.strafe = tonumber(extra) * self.strafeSpeed else self.super:ReceiveMessage(message,extra) end end function object:Free(model) object.controller:Free() if object.characterModel ~= nil then object.characterModel:Free() end --Notify("Inside free") self.super:Free() end end --[[ function class:Free() self.super:Free() end ]]-- What this does so far; Add's the fields in the property to add the animation frames for input. Debugs to check if inputs are 0, will not crash "Unhandled Exception" Deafults to idle frames. Needed: Way to check what the message recieved from key board controller for movement animation Let me know what you think Quote AMD Phenom II x6 1100T - 16GB RAM - ATI 5870 HD - OCZ Vertex 2 60GB SSD Link to comment Share on other sites More sharing options...
Rick Posted January 16, 2010 Author Share Posted January 16, 2010 I love it!! About time someone gets in on this stuff. I'll put it in the next version. So the needed yet: "Way to check what the message recieved from key board controller for movement animation" Wouldn't the ReceiveMessage() part be doing this already? I see you added the animation part in the ReceiveMessage(). So what more is there to do? Also, I really need to figure out if I can make dynamic property fields. Would be really cool if we didn't have to hardcode the settings but could add new animations at will just from the properties window. But that can wait for now. Quote Link to comment Share on other sites More sharing options...
VicToMeyeZR Posted January 16, 2010 Share Posted January 16, 2010 I haven't tested that part yet... I am trying to debug it so it won't crash all the time, so it means adding alot of if then checks, because if the start frame and end frame ever end up both being 0, it will crash the editor Quote AMD Phenom II x6 1100T - 16GB RAM - ATI 5870 HD - OCZ Vertex 2 60GB SSD Link to comment Share on other sites More sharing options...
VicToMeyeZR Posted January 16, 2010 Share Posted January 16, 2010 ok. revised for your next version. require("scripts/class") require("Scripts/hooks") local class=CreateClass(...) function class:InitDialog(grid) self.super:InitDialog(grid) group = grid:AddGroup("Character") group:AddProperty("model", PROPERTY_FILE, "GMF Files (*.gmf):gmf", "", "Model Files") group:AddProperty("controller_height", PROPERTY_FLOAT, "Controller Height") group:AddProperty("controller_radius", PROPERTY_FLOAT, "Controller Radius") group:AddProperty("controller_step_height", PROPERTY_FLOAT, "Controller Step Height") group:AddProperty("controller_max_slope", PROPERTY_FLOAT, "Controller Max Slope") group = grid:AddGroup("Animations") group:AddProperty("idle_start", PROPERTY_INTEGER, "Idle Start Frame") group:AddProperty("idle_end", PROPERTY_INTEGER, "Idle End Frame") group:AddProperty("walk_start", PROPERTY_INTEGER, "Walk Start Frame") group:AddProperty("walk_end", PROPERTY_INTEGER, "Walk End Frame") group:AddProperty("run_start", PROPERTY_INTEGER, "Run Start Frame") group:AddProperty("run_end", PROPERTY_INTEGER, "Run End Frame") group:AddProperty("jump_start", PROPERTY_INTEGER, "Jump Start Frame") group:AddProperty("jump_end", PROPERTY_INTEGER, "Jump End Frame") group:AddProperty("crouch_start", PROPERTY_INTEGER, "Crouch Start Frame") group:AddProperty("crouch_start", PROPERTY_INTEGER, "Crouch End Frame") group:Expand(1) end function class:CreateObject(model) local object=self.super:CreateObject(model) object.model = model object.height = tonumber(object:GetKey("controller_height", "1.8")) local radius = tonumber(object:GetKey("controller_radius", "0.4")) local step = tonumber(object:GetKey("controller_step_height", "0.5")) local slope = tonumber(object:GetKey("controller_max_slope", "45.0")) object.oneTime = false object.controller = CreateController(object.height, radius, step, slope) object.controller:SetMass(1.0) EntityType(object.controller, 1) -- set the position of the controller to the editor object local pos = object.model:GetPosition() object.controller:SetPosition(Vec3(pos.x, pos.y + (object.height/2), pos.z)) object.characterModel = nil object.move = 0 object.strafe = 0 object.rotate = 0 object.jump = 0 object.moveSpeed = 2 object.strafeSpeed = 2 object.framestart = 0 object.frameend = 0 function object:StartAnimations(movement) object.framestart = self.model:GetKey(movement .. "_start") return object.framestart end function object:EndAnimations(movement) object.frameend = self.model:GetKey(movement .. "_end") return object.frameend end function object:SetKey(key,value) if key=="model" then local pos = self.model:GetPosition() self.characterModel = LoadModel("abstract::"..value) self.characterModel:SetPosition(Vec3(pos.x, pos.y, pos.z)) else return self.super:SetKey(key,value) end return 1 end function object:GetKey(key,value) if key=="" then else return self.super:GetKey(key,value) end return value end function object:Update() if object.move == 0 then if object.frameend ~= 0 then object:StartAnimations("idle") object:EndAnimations("idle") else object.framestart = 0 object.frameend = 100 end end if self.characterModel ~= nil then if object.frameend ~= 0 then object.frame = math.fmod(AppTime()/35, object.frameend-object.framestart)+object.framestart Animate(self.characterModel, object.frame, 1.0, 0, true) end end if GetGlobalString("mode") == "GAME_MODE" then if self.characterModel ~= nil then if object.oneTime == false then object.oneTime = true object.controller:SetPosition(object.model:GetPosition()) end self.controller:Update(self.rotation, self.move, self.strafe, self.jump, 5000, 10) self.jump = 0 -- reset -- the character model must follow the controller -- for the 3rd person camera to work we must also move the object model, which is stupid self.model:SetPosition(Vec3(object.controller.position.x, object.controller.position.y - (object.height/2), object.controller.position.z)) self.characterModel:SetPosition(Vec3(object.controller.position.x, object.controller.position.y - (object.height/2), object.controller.position.z)) end else -- constantly update the controller to the object in the editor local pos = object.model:GetPosition() object.controller:SetPosition(Vec3(pos.x, pos.y + (object.height/2), pos.z)) -- make the model follow if self.characterModel ~= nil then self.characterModel:SetPosition(Vec3(pos.x, pos.y, pos.z)) end end end function object:UpdateMatrix() end --[[ function object:LockKeys(model) self.super:LockKeys() end ]]-- --[[ function object:UnlockKeys(model) self.super:UnlockKeys() end ]]-- --[[ function object:UpdateMatrix() end ]]-- --[[ function object:Reset() end ]]-- --[[ function object:SetTarget(target,index) end ]]-- --[[ function object:Collision(entity,position,normasl,force,speed) end ]]-- function object:ReceiveMessage(message,extra) if message == "move" then object.move = tonumber(extra) * self.moveSpeed object:StartAnimations("walk") object:EndAnimations("walk") elseif message == "jump" and object.controller:IsAirborne() == 0 then object.jump = tonumber(extra) elseif message == "strafe" then object.strafe = tonumber(extra) * self.strafeSpeed else self.super:ReceiveMessage(message,extra) end end function object:Free(model) object.controller:Free() if object.characterModel ~= nil then object.characterModel:Free() end --Notify("Inside free") self.super:Free() end end --[[ function class:Free() self.super:Free() end ]]-- Checked Animations per movement, and they do work. BUG: Animation frames for idle, MUST be set prior to loading the character mesh. Quote AMD Phenom II x6 1100T - 16GB RAM - ATI 5870 HD - OCZ Vertex 2 60GB SSD Link to comment Share on other sites More sharing options...
Rick Posted January 16, 2010 Author Share Posted January 16, 2010 I am trying to debug it so it won't crash all the time, so it means adding alot of if then checks Welcome to Thingoid programming lol. I also have an idea that I'm going to test out for the oneTime stuff I do. Basically sometimes I need to run stuff that is kind of like init code when running in game mode. What I can do is add a function object:Initialization(). Then in the main lua file loop through all objects in the objecttable table and if it has that function call it. That should help clean some of that oneTime stuff. I don't like how I did that. Also, I'm about to release 5 more Thingoids. Pi-Cube Pi-Body Pi-Fixed Joint Pi-Pivot Pi-MoveTo With these 5 Thingoids I'm able to move the cube between 6 pivots and have it still have physics. Just cleaning some code up. Quote Link to comment Share on other sites More sharing options...
VicToMeyeZR Posted January 16, 2010 Share Posted January 16, 2010 cool.. Sounds good to me. Quote AMD Phenom II x6 1100T - 16GB RAM - ATI 5870 HD - OCZ Vertex 2 60GB SSD Link to comment Share on other sites More sharing options...
ZeroByte Posted January 25, 2010 Share Posted January 25, 2010 Hi Rick, great job on these Thingoids, but i have a question. I can get this to work in the Editor, but how do i get it to work in my c++ app? Example, if i drag the Windmill into my map, then run my c++ app, i can see it spinning and squeaking, but the character i setup in the Editor doesn't move, just in the Editor.. Thank's for any tips, sorry if this is a dumb question. Quote Win 7 64, LE 2.31, Liquid Cooled I7-960 @ 4.00GHz, 6GB DDR3 Ram @ 1600mhz, BFG GTX295, Sound Blaster X-FI. Link to comment Share on other sites More sharing options...
Niosop Posted January 25, 2010 Share Posted January 25, 2010 I think it's because it's set up to only work in game mode, and it doesn't know that you're in game mode when running from C++. This is the relevant line: if GetGlobalString("mode") == "GAME_MODE" then I believe by calling SetGlobalString in your C++ code and setting mode to "GAME_MODE" it might start working. I don't see the documentation for SetGlobalString in the wiki, so not sure of the syntax, but shouldn't be too hard to figure out. If that works for you please post back to let others know. Quote Windows 7 x64 - Q6700 @ 2.66GHz - 4GB RAM - 8800 GTX ZBrush - Blender Link to comment Share on other sites More sharing options...
ZeroByte Posted January 25, 2010 Share Posted January 25, 2010 Thank's Niosop, i think your right, i tried adding these lines SetGlobalString("mode", "DESIGN_MODE"); SetGlobalString("quit", "false"); to my c++ app, it compiled ok but didn't make it work when it was executed. I'll keep trying stuff, thank's again. Quote Win 7 64, LE 2.31, Liquid Cooled I7-960 @ 4.00GHz, 6GB DDR3 Ram @ 1600mhz, BFG GTX295, Sound Blaster X-FI. Link to comment Share on other sites More sharing options...
ZeroByte Posted January 25, 2010 Share Posted January 25, 2010 Ok i put SetGlobalString("mode", "DESIGN_MODE"); by mistake, changed it to SetGlobalString("mode", "GAME_MODE"); but when that is executed, the character just disappears, still trying. Quote Win 7 64, LE 2.31, Liquid Cooled I7-960 @ 4.00GHz, 6GB DDR3 Ram @ 1600mhz, BFG GTX295, Sound Blaster X-FI. Link to comment Share on other sites More sharing options...
ZeroByte Posted January 25, 2010 Share Posted January 25, 2010 Ok, i attatched the Pi-ThirdPersonCamera to my Pi-Character with Pi-CharacterKeyboardControls in the editor, and when i run this code from my c++ app, if (LEO::Keyboard::I****(KEY_G)) { SetGlobalString("mode", "GAME_MODE"); SetGlobalString("quit", "false"); } it switches to the third person cam on my character. So, i think i'm on the right track, just have to find why my character controller is falling through the terrain. Quote Win 7 64, LE 2.31, Liquid Cooled I7-960 @ 4.00GHz, 6GB DDR3 Ram @ 1600mhz, BFG GTX295, Sound Blaster X-FI. Link to comment Share on other sites More sharing options...
ZeroByte Posted January 25, 2010 Share Posted January 25, 2010 Also, if i run this code, if (LEO::Keyboard::I****(KEY_Q)) { SetGlobalString("mode", "DESIGN_MODE"); SetGlobalString("quit", "true"); } it switches back to my other character controller. Quote Win 7 64, LE 2.31, Liquid Cooled I7-960 @ 4.00GHz, 6GB DDR3 Ram @ 1600mhz, BFG GTX295, Sound Blaster X-FI. Link to comment Share on other sites More sharing options...
Rick Posted January 25, 2010 Author Share Posted January 25, 2010 It might be the entity type of the character controller? Or maybe place the character a little higher from the ground to see if that helps. Quote Link to comment Share on other sites More sharing options...
ZeroByte Posted January 25, 2010 Share Posted January 25, 2010 Hi Rick, thank's for trying to help, i tried your suggestions, still falls through terrain, it work's fine in the editor though. So, i guess it's cause i'm trying to get it to run from my c++ app. There must be a way to run game scripts from c++, but Josh commented these functions out in c++ headers. //inline TScript LoadScript(str filename) //{ // return leLoadScript(filename); //} //inline void RunScript(TScript script, BP funcname, BP object) //{ // leRunScript(script, funcname, object); //} //inline void FreeScript(TScript script) //{ // leFreeScript(script); //} Are the thingoids just meant to run with Lua only ? Well thank's again for your help. Quote Win 7 64, LE 2.31, Liquid Cooled I7-960 @ 4.00GHz, 6GB DDR3 Ram @ 1600mhz, BFG GTX295, Sound Blaster X-FI. Link to comment Share on other sites More sharing options...
Rick Posted January 25, 2010 Author Share Posted January 25, 2010 Are you assigning an entity type to the terrain? I'm not sure how you do that because in the editor it's done for you. Maybe look at that. Can you get other models collide with the terrain when running from your C++ app? Quote Link to comment Share on other sites More sharing options...
ZeroByte Posted January 26, 2010 Share Posted January 26, 2010 I was assigning an entity type to the terrain, now that you mentioned the editor does it, i removed this line EntityType(scene,2); and my character controller in my c++ app still work's fine just using this line of code LEO::Collisions::Set(1,1,SLIDINGCOLLISION); Yes, other models collide with my terrain in my c++ app. I'll keep testing different settings, i'm new to Lua scripting, but i can see it's a great addition to LWE. Quote Win 7 64, LE 2.31, Liquid Cooled I7-960 @ 4.00GHz, 6GB DDR3 Ram @ 1600mhz, BFG GTX295, Sound Blaster X-FI. Link to comment Share on other sites More sharing options...
Rick Posted January 26, 2010 Author Share Posted January 26, 2010 If you provide the C++ source I could help test it out to see what's going on. Quote Link to comment Share on other sites More sharing options...
ZeroByte Posted January 29, 2010 Share Posted January 29, 2010 Hey Rick, haven't had time for LE lately, here is my c++ source: http://66.244.240.14/ link should be working. i removed engine.cpp, layer.cpp, leo.cpp, mathlib.cpp, renderer.cpp. Also deleted, engine.dll, jointlibrary.dll, newton.dll, shaders.pak. Just ignore the xbox 360 gamepad input code, it's set to mouse input anyway. I noticed if i attach a Pi-ThirdPersonCamera to the monster truck, it doesn't fall through the terrain. Just the character, so it must be something stupid i'm doing wrong, or i'm not using c++ properly with Lua. I didn't include my map, it's just a flat surface, with Pi-ThirdPersonCamera, Pi-CharacterKeyboardControls, and character, or monster truck. Anyway thank's for your help, sorry took so long to post back. Quote Win 7 64, LE 2.31, Liquid Cooled I7-960 @ 4.00GHz, 6GB DDR3 Ram @ 1600mhz, BFG GTX295, Sound Blaster X-FI. Link to comment Share on other sites More sharing options...
Recommended Posts
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.