VicToMeyeZR
-
Posts
570 -
Joined
-
Last visited
Content Type
Blogs
Forums
Store
Gallery
Videos
Posts posted by VicToMeyeZR
-
-
Not if josh, puts that in his core.
lol.
I will try that also.
-
Very good idea. +1 from me
-
ok. I had to add a little to the class.lua file to get this to work.
Name the XML file the same as your GMF model file.
change to Class.lua
--Creates a class from a model reference object function CreateClass(modelreference) local class={} local super={} class.instances={} classtable[modelreference]=class class.modelreference=modelreference class.name=string.lower(StripAll(modelreference.path)) classnametable[class.name]=class Print("Creating class "..class.name) super.class=class
CHANGE TO:
--Creates a class from a model reference object function CreateClass(modelreference) local class={} local super={} class.instances={} classtable[modelreference]=class class.modelreference=modelreference class.name=string.lower(StripAll(modelreference.path)) class.path=string.lower(StripExt(modelreference.path)) classnametable[class.name]=class classnametable[class.path]=class.path Print("Creating class "..class.name) super.class=class
Then change the top of my file from :
local obj,err = XmlParser:ParseXmlFile("Models/characters/Cyber/character_visor_full.xml")
CHANGE TO:
local obj,err = XmlParser:ParseXmlFile(class.path..".xml")
-
Thanks, I was looking at that.
-
Yeah, that gives me the name, but not the path.
-
hmm, I think the issue is that the settings dialog will be the same for them all though. The InitDialog() runs the same for all instances. So if you wanted to have a character that had a different animation name than another character you couldn't.
I guess I was thinking that the xml file would describe animations for that given instance of the character thingoid instead of being a file that describes how the settings dialog box should look. In this case I get the fact that it wouldn't be the easiest because instead of settings in the dialog box they need to edit an xml file, BUT, follow me on my journey of thinking just now, I wonder if we could have the properties from the editor shell out to a custom exe that we create that makes editing the xml file easier. It could be a small little properties window that is more flexible in adding animations to the xml file. The result would be the xml file that the user selects into the editor settings dialog.
[edit]
Then in the setkey method, when the xml file gets selected, you parse it out and store the information in a lua table variable to that object.
I'm curious to hear where you are going with this more though.
Yeah, my thinking in this, and of course it will progress, is that no matter WHAT animations the character has, this character file will work for EVERY character/NPC.
You make the XML file based of that model, and as soon as you post each one in the editor, the properties fields are set.
If I could find out how to automatically pull the XML file name based off the model instance, then the file WOULD be fully automated.
the model lua file, and the model file name match, so if there was a way to tell the script the the XML file is the same, sure would help out a bunch. (*hint)
I will post a video, so you can see.
-
ok. My character script. This way I won't have to change much with it.
XML FILE:
<?xml version="1.0" encoding="utf-8"?> <animations> <start> <idle value="Idle Start Frame">460</idle> <run value="Run Start Frame">1155</run> </start> <end> <idle value="Idle End Frame">850</idle> <run value="Run End Frame">1195</run> </end> </animations>
MODEL LUA FILE:
require("scripts/class") require("scripts/XML/XML") local class=CreateClass(...) local obj,err = XmlParser:ParseXmlFile("Models/characters/Cyber/character_visor_full.xml") function class:InitDialog(grid) self.super:InitDialog(grid) group = grid:AddGroup("Animations") //This adds a property field based off the XML file data structure. This file MUST meet the data structure set by my post, or you will have to modify this script if (not err) then for i,xmlNode in pairs(obj.ChildNodes) do if(xmlNode.Name=="start") then for i,subXmlNode in pairs(xmlNode.ChildNodes) do if(subXmlNode.Name) then group:AddProperty(subXmlNode.Name.."_start", PROPERTY_INTEGER, "", ""..subXmlNode.Attributes.value.."") end end end end for i,xmlNode in pairs(obj.ChildNodes) do if(xmlNode.Name=="end") then for i,subXmlNode in pairs(xmlNode.ChildNodes) do if(subXmlNode.Name) then group:AddProperty(subXmlNode.Name.."_end", PROPERTY_INTEGER, "", ""..subXmlNode.Attributes.value.."") end end end end end group:Expand(1) end
-
Here is a Lua only Parser.
test.xml
<?xml version="1.0" encoding="utf-8"?> <animations> <start> <idle value="infiltrator">460</idle> <run value="infiltrator">1155</run> </start> <end> <idle value="infiltrator">850</idle> <run value="infiltrator">1195</run> </end> </animations>
xml.lua
XmlParser = {}; function XmlParser:ToXmlString(value) value = string.gsub (value, "&", "&"); -- '&' -> "&" value = string.gsub (value, "<", "<"); -- '<' -> "<" value = string.gsub (value, ">", ">"); -- '>' -> ">" --value = string.gsub (value, "'", "'"); -- '\'' -> "'" value = string.gsub (value, "\"", """); -- '"' -> """ -- replace non printable char -> " " value = string.gsub(value, "([^%w%&%;%p%\t% ])", function (c) return string.format("%X;", string.byte(c)) --return string.format("%02X;", string.byte(c)) --return string.format("%02d;", string.byte(c)) end); return value; end function XmlParser:FromXmlString(value) value = string.gsub(value, "([%x]+)%;", function(h) return string.char(tonumber(h,16)) end); value = string.gsub(value, "([0-9]+)%;", function(h) return string.char(tonumber(h,10)) end); value = string.gsub (value, """, "\""); value = string.gsub (value, "'", "'"); value = string.gsub (value, ">", ">"); value = string.gsub (value, "<", "<"); value = string.gsub (value, "&", "&"); return value; end function XmlParser:ParseArgs(s) local arg = {} string.gsub(s, "(%w+)=([\"'])(.-)%2", function (w, _, a) arg[w] = self:FromXmlString(a); end) return arg end function XmlParser:ParseXmlText(xmlText) local stack = {} local top = {Name=nil,Value=nil,Attributes={},ChildNodes={}} table.insert(stack, top) local ni,c,label,xarg, empty local i, j = 1, 1 while true do ni,j,c,label,xarg, empty = string.find(xmlText, "<(%/?)([%w:]+)(.-)(%/?)>", i) if not ni then break end local text = string.sub(xmlText, i, ni-1); if not string.find(text, "^%s*$") then top.Value=(top.Value or "")..self:FromXmlString(text); end if empty == "/" then -- empty element tag table.insert(top.ChildNodes, {Name=label,Value=nil,Attributes=self:ParseArgs(xarg),ChildNodes={}}) elseif c == "" then -- start tag top = {Name=label, Value=nil, Attributes=self:ParseArgs(xarg), ChildNodes={}} table.insert(stack, top) -- new level --log("openTag ="..top.Name); else -- end tag local toclose = table.remove(stack) -- remove top --log("closeTag="..toclose.Name); top = stack[#stack] if #stack < 1 then error("XmlParser: nothing to close with "..label) end if toclose.Name ~= label then error("XmlParser: trying to close "..toclose.Name.." with "..label) end table.insert(top.ChildNodes, toclose) end i = j+1 end local text = string.sub(xmlText, i); if not string.find(text, "^%s*$") then stack[#stack].Value=(stack[#stack].Value or "")..self:FromXmlString(text); end if #stack > 1 then error("XmlParser: unclosed "..stack[stack.n].Name) end return stack[1].ChildNodes[1]; end function XmlParser:ParseXmlFile(xmlFileName) local hFile,err = io.open(xmlFileName,"r"); if (not err) then local xmlText=hFile:read("*a"); -- read file content io.close(hFile); return self:ParseXmlText(xmlText),nil; else return nil,err; end end
Run this file:
require("Scripts/XML/xml") local obj,err = XmlParser:ParseXmlFile("Scripts/test.xml") if(not err) then for i,xmlNode in pairs(obj.ChildNodes) do if(xmlNode.Name=="start") then for i,subXmlNode in pairs(xmlNode.ChildNodes) do if(subXmlNode.Name) then Notify(subXmlNode.Name.." value=\""..subXmlNode.Attributes.value.."\""); if(subXmlNode.Value) then Notify(" Content=\""..subXmlNode.Value.."\""); end end end end end else Notify("ERROR: "..err); end
It will return:
idle value="infiltrator" content="460" run value="infiltrator" content="1155"
With this I can have it run a dynamic menu for the object, as well as pass the deafult values based on the XML file information.
I will post the scrip to run this part as soon as I have it.
-
ahh. Ok. I wasn't thinking about that.
-
Yes I will.
I already posted the XML lib for use so I will start on the scripting for it.
-
I haven't done a lot of testing with this, but it will parse the XML data exactly like we were talking.
-
File Name: LuaXML.zip
File Submitter: VicToMeyeZR
File Submitted: 18 Jan 2010
File Category: Lua Scripts
Place to 2 DLL files in your root SDK folder. Place the core LUA file anywhere you want in the scripts folder.
Go to town.
LuaXML
- a module that maps between Lua and XML without much ado
version 1.7.2, 2009-09-06 by Gerald Franz, www.viremo.de
LuaXML provides a minimal set of functions for the processing of XML data in Lua. It offers a
very simple and natural mapping between the XML data format and Lua tables, which
allows one to parse XML data just using Lua's normal table access and iteration
methods: Substatements and text content is represented as array data having
numerical keys, attributes and tags use string keys. This representation makes
sure that the structure of XML data is exactly preserved in a read/write cycle.
Since version 1.7, LuaXML consists of a well-optimized portable ISO-standard C file
and a small Lua file. It is published under the same liberal licensing conditions as Lua
itself (see below). It has been successfully compiled and used under Linux, various
flavours of MS Windows, and MacOS X.
Example
-- import the LuaXML module
require("LuaXML")
-- load XML data from file "test.xml" into local table xfile
local xfile = xml.load("test.xml")
-- search for substatement having the tag "scene"
local xscene = xfile:find("scene")
-- if this substatement is found...
if xscene ~= nil then
-- ...print it to screen
print(xscene)
-- print attribute id and first substatement
print( xscene.id, xscene[1] )
-- set attribute id
xscene["id"] = "newId"
end
-- create a new XML object and set its tag to "root"
local x = xml.new("root")
-- append a new subordinate XML object, set its tag to "child", and its content to 123
x:append("child")[1] = 123
print(x)
Documentation
LuaXML consists of the following functions:
require("LuaXML")
imports the LuaXML module.
LuaXML consists of a lua file (LuaXML.lua) and normally a shared library (.dll/.so), although a static linking is possible as well. Both parts are imported by this call provided that they are found in Lua's package search path.
function xml.new(arg)
creates a new LuaXML object.
* param arg (optional), (1) a table to be converted to be converted to a LuaXML object, or (2) the tag of the new LuaXML object
Note that it is not mandatory to use this function in order to treat a Lua table as LuaXML object. Setting the metatable just allows the usage of a more object-oriented syntax (e.g., xmlvar:str() instead of xml.str(xmlvar) ). XML objects created by xml.load() or xml.eval() automatically offer the object-oriented syntax.
* Returns new LuaXML object
function xml.append(var,tag)
appends a new subordinate LuaXML object to an existing one, optionally sets tag.
* param var the parent LuaXML object
* param tag (optional) the tag of the appended LuaXML object
* Returns appended LuaXML object or nil in case of error
function xml.load(filename)
loads XML data from a file and returns it as table
* param filename the name and path of the file to be loaded
* Returns a Lua table containing the xml data in case of success or nil.
function xml.save(var,filename)
saves a Lua var as XML file.
* param var, the variable to be saved, normally a table
* param filename the filename to be used. An existing file of the same name gets overwritten.
function xml.eval(xmlstring)
converts an XML string to a Lua table
* param xmlstring the string to be converted
* Returns a Lua table containing the xml data in case of success or nil.
function xml.tag(var, tag)
sets or returns tag of a LuaXML object. This method is just "syntactic sugar" (using a typical Lua term)
that allows the writing of clearer code. LuaXML stores the tag value of an XML statement at table
index 0, hence it can be simply accessed or altered by var[0] or var[xml.TAG] (the latter is just a
symbolic name for the value 0). However, writing var:tag() for access or var:tag("newTag") for altering
may be more self explanatory.
* param var, the variable whose tag should be accessed, a LuaXML object
* param tag (optional) the new tag to be set.
* Returns the current tag as string
function xml.str(var, indent, tag)
converts any Lua var to an xml string.
* param var, the variable to be converted, normally a table
* param indent (optional) the current level of indentation for pretty output. Mainly for internal use.
* param tag (optional) the tag to be used for a table without tag. Mainly for internal use.
* Returns an XML string in case of success or nil.
function xml.find(var, tag, attributeKey,attributeValue)
recursively parses a Lua table for a substatement fitting to the provided tag and attribute
* param var, the table to be searched in.
* param tag (optional) the xml tag to be found.
* param attributeKey (optional) the exact attribute to be found.
* param attributeValue (optional) the attribute value to be found.
* Returns the first (sub-)table which matches the search condition or nil.
function xml.registerCode(decoded,encoded)
registers a custom code for the conversion between non-standard characters and XML character entities
* param decoded the character (sequence) to be used within Lua.
* param encoded the character entity to be used in XML.
* By default, only the most basic entities are known to LuaXML (” & < > ').
ANSI codes above 127 are directly converted to the XML character codes
of the same number. If more character codes are needed, they can be
registered using this function.
-
oo.. sweet. I like your train of thought.
Good idea.
-
--EDIT- not all 3dws users are LE users and vice versa...
3dws could still be sold as a stand alone...
Was talking about also integrating it to LE, and raise the price of LE.
-
I am wondering about the controller you use Rick..
(specifically the height and such)
Do you really have he have the controller move the model?
Can you pull the model height in real time, and move it with out a controller?
specifically this line:
object.controller:SetPosition(Vec3(pos.x, pos.y + (object.height/2), pos.z))
Your moving the controller by half the distance of the height. Can you pull the model height in real time and move it with out the controller by half its real height?
hope that makes sense.
-
It can. RIght now its only setup for idle animation, so if you never enter anything other than the idle(which can be any frames) then it will only do that animation
-
I'm excited to see what you come up with man!
Me to.
I really like Lua. mostly because I am a scripter, not a programmer. lol
-
The longer one gives an error (I fixed what was wrong with it as suggested). An empty box pops up and wants me to hit OK. I'll have to dissect that and see if I can make it work.
That was a debug so I could see if my value of framestart or frameend was being set...
I you find the Notify() and put a -- in front of it, and change this line:
function object:GetKey(key,value) if key=="idle_start" then return self.idle_start elseif key=="idle_end" then return self.idle_start
to :
function object:GetKey(key,value) if key=="idle_start" then return self.idle_start elseif key=="idle_end" then return self.idle_end
It will work.
Then you can double click in the character in the objects window, and set your frame start and ends for each function.
Right now, all the guy does is idle animate, and yes its a dexsoft model, so theirs do work, just requires little fix with the textures.
When I get the controller to work with this, I will post it again for everyone to play with if they want.
-
Thats what I thought 2 days ago. It really is easy, well easier than I thought at first.
I do still have a lot to add to it, and I plan to integrate Rick's character scripts in a way to control the character better.
-
lol... oops
Hence the reason it crashes. End and start time are both the same.
-
Can someone give me an idea what I got wrong here.
I can put the model in the editor, but as soon as I set the values for the idle animation I get Exception violation, and it crashes.
Thanks
require("scripts/class") local class=CreateClass(...) function class:InitDialog(grid) self.super:InitDialog(grid) 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:AddProperty("strafeleft_begin", PROPERTY_INTEGER, "Left Start Frame") group:AddProperty("strafeleft_end", PROPERTY_INTEGER, "Left End Frame") group:AddProperty("straferight_begin", PROPERTY_INTEGER, "Right Start Frame") group:AddProperty("straferight_end", PROPERTY_INTEGER, "Right End Frame") group:Expand(1) end function class:CreateObject(model) local object = self.super:CreateObject(model) object.model = model object.framestart = tonumber(object:GetKey("idle_start")) object.frameend = tonumber(object:GetKey("idle_end")) Notify(object.framestart) function object:SetKey(key,value) if key=="idle_start" then self.idle_start = tonumber(value) elseif key=="idle_end" then self.idle_end = tonumber(value) elseif key=="walk_start" then self.walk_start = tonumber(value) elseif key=="walk_end" then self.walk_end = tonumber(value) elseif key=="run_start" then self.run_start = tonumber(value) elseif key=="run_end" then self.run_end = tonumber(value) elseif key=="jump_start" then self.jump_start = tonumber(value) elseif key=="jump_end" then self.jump_end = tonumber(value) elseif key=="crouch_start" then self.crouch_start = tonumber(value) elseif key=="crouch_end" then self.crouch_end = tonumber(value) elseif key=="strafeleft_start" then self.strafeleft_start = tonumber(value) elseif key=="strafeleft_end" then self.strafeleft_end = tonumber(value) elseif key=="straferight_start" then self.straferight_start = tonumber(value) elseif key=="straferight_end" then self.straferight_end = tonumber(value) else return self.super:SetKey(key,value) end return 1 end function object:GetKey(key,value) if key=="idle_start" then return self.idle_start elseif key=="idle_end" then return self.idle_start elseif key=="walk_start" then return self.walk_start elseif key=="walk_end" then return self.walk_end elseif key=="run_start" then return self.run_start elseif key=="run_end" then return self.run_end elseif key=="jump_start" then return self.jump_start elseif key=="jump_end" then return self.jump_end elseif key=="crouch_start" then return self.crouch_start elseif key=="crouch_end" then return self.crouch_end elseif key=="strafeleft_start" then return self.strafeleft_start elseif key=="strafeleft_end" then return self.strafeleft_end elseif key=="straferight_start" then return self.straferight_start elseif key=="straferight_end" then return self.straferight_end else return self.super:GetKey(key,value) end return value end function object:StartAnimations(movement) object.framestart = object:GetKey(movement .. "_start") return object.framestart end function object:EndAnimations(movement) object.frameend = object:GetKey(movement .. "_end") return object.frameend 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,normal,force,speed) end function object:ReceiveMessage(message,extra) if message=="forward" then --[[ elseif message=="reverse" then elseif message=="mleft" then elseif message=="mright" then elseif message=="tleft" then elseif message=="tright" then elseif message=="crouch" then elseif message=="jump" then elseif message=="attack" then ]]-- else self.super:ReceiveMessage(message,extra) end end function object:Render() object.framestart = object:StartAnimations("idle") object.frameend = object:EndAnimations("idle") if object.frameend ~= nil and object.frameend ~= 0 or object.framestart ~= nil then object.frame = math.fmod(AppTime()/35, object.framestart - object.frameend) + object.framestart Animate(object.model, object.frame, 0.5, 0, true) end end function object:Free(model) self.super:Free() end end function class:Free() self.super:Free() end
-
cool.. Sounds good to me.
-
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.
-
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
Lua only XML parser
in Programming
Posted
ahh. ok.
Thats it. I just needed to look a little deeper. I was trying modelreference but couldn't get anything from it, but class is the table I needed.
local test = string.lower(StripExt(class.modelreference.path))
Thanks Rick