Jump to content

Pi-Character v 0.1


Rick
 Share

Recommended Posts

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

Link to comment
Share on other sites

  • 2 weeks later...

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

AMD Phenom II x6 1100T - 16GB RAM - ATI 5870 HD - OCZ Vertex 2 60GB SSD

76561197984667096.png

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

AMD Phenom II x6 1100T - 16GB RAM - ATI 5870 HD - OCZ Vertex 2 60GB SSD

76561197984667096.png

Link to comment
Share on other sites

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.

AMD Phenom II x6 1100T - 16GB RAM - ATI 5870 HD - OCZ Vertex 2 60GB SSD

76561197984667096.png

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

  • 2 weeks later...

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.

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

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.

Windows 7 x64 - Q6700 @ 2.66GHz - 4GB RAM - 8800 GTX

ZBrush - Blender

Link to comment
Share on other sites

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.

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

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.

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

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.

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

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.

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

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.

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

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.

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

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.

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

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