-
Posts
7,936 -
Joined
-
Last visited
Content Type
Blogs
Forums
Store
Gallery
Videos
Downloads
Everything posted by Rick
-
I think this shows how few people are actually reading the documentation. There are 2 kinds of people in this world. Those who read the directions and those who don't. Should those who don't be chastised or should they be presented the documentation in a different way. A way that seems like they aren't really even reading the directions, but they really are. Clearly I'm bias in thinking like this because I'm not a directions reader lol
-
I have the below code and when I'm looking at the App table it works just fine. It loops over the functions perfectly. However, when I put in the name of an entity script it bombs on lua_next() with access violation. What is different about the App table vs the entity script Tables that get created? Is there a way to get the instances of entity scripts from it's filename (if I recall the name of the lua file is what the table gets created with). I'm working with NoesisGUI and working on making a codebehind file that is in Lua. The plan is that we'll have load a xaml file from NoesisGUI. The base name of that xaml file will be the same name as a lua entity script file. The user will attach the script to a pivot and inside define their event functions. In the LE C++ project I'll get that entity script table and loop over all it's functions looking for a prefix that tells me it's a NoesisGUI event callback. The format will be: function Noesis_ControlNameInXamlFile_Event() end When I see a function start with Noesis I then get the control name and find that Noesis control, and then find the event name (Noesis has a way to get event delegates via it's string name) and bind the event to a generic C++ event. When Noesis calls this generic event inside of it I'll concat the Lua function name and call it for said Lua table. I'm packaging all this up into 1 nice and easy C++ library so users just have to call a few functions in their C++ LE project and everything is handled for them. However, not sure how to get lua entity script tables in C++. Anyone have any ideas? [EDIT] OK, decided to just make normal Lua "static classes" to handle this. But would still be interested to know if we can get entity script tables from C++.
-
I've noticed an issue when picking some models that the pick seems to go through the model in certain areas. In the example below if you run it'll be a model of a door and the picking is done each frame. It will display what is being picked in the top left of the screen (door01 or Nothing). Notice how if you move your mouse around the top right and bottom right the text will flash between "door01" and "Nothing". If you play with the scripts/camera.lua file and change the pick diameter to say .1 it's even more pronounced. The problem is that if you have a top down camera the bigger the diameter of the pick the more issues you have with it picking things you don't want. The precision of the pick becomes worse with a wider pick diameter, but with a smaller diameter the pick goes through models in certain areas. This is a problem in our game. Interestingly enough, if you cover the door with csg it works fine (but this is a hack to ask to do this). So something with model files the picking gets weird results based on diameter size. https://www.dropbox.com/s/wlaxubn7f07ivz6/PickingIssue.rar?dl=0
-
OK, yeah I was thinking custom collision type but wasn't sure if we were able to put collision types on shapes. Thanks.
-
If a mdl has the same name phy file it gets attached right? So I'm curious if we are able to set the collision type of both the mdl file and phy file separately or if you can't get to the phy entity file directly to give it it's own collision type. I ask because we have a situation where we dissolve the material on the mdl with a shader so it's not visible, but we want to pick through it when this happens (so ideally I set collision type to None), but also don't want controllers to fall through it. Since picking is done on the mesh and not the phy, can I have the phy collision type set to Scene but the mdl collision type set to None? If so how would I access the phy file on a mdl file in code?
-
why do you delete new_entity if != null? you created a new one in memory then you delete the memory.
-
so us the code where you make that object. both the header and source. also if all those vars are inside IScript you should pass them to the IScript ctor and set them there and not in the child ctor.
-
Not ideal, but it's something. Ideally a menu item is added for this and that is done by the editor for us. We select Custom Phys from the menu, we supply a mdl file, it automatically makes a phy file from that mdl file and gives the phy file the same name as the model opened in the model editor.
-
I know we have new ways of generating collision from the models, but are we able to supply our own collision mesh from a model like we used to be? This is really still needed as often you don't want the collision to match the visual model itself. Enabling legacy really isn't an option if that's the only option right now. The functionality to supply a physics file that was a mdl was already there. Please just add another item in the Physics menu that says Custom Physics and have it ask for the phy file to assign. Easy as pie and gives us more flexibility that we already used to have.
-
See I don't think level designers are as disposable as people making specific models or well segregated scripts. Those people can come and go at will but a level designer bringing all those assets together in a level and hooking up all the scripts is a much more broad job with a lot of responsibility. Anytime a person leaves that has a broad job with a lot of responsibility (in any career) things fall apart. This is why having a main programmer or a main artist opens yourself up for failure because now you've created 3 broad jobs with a lot of responsibility (level designer, artist, programmer). People aren't getting paid to do a community project so their attention span will be very small and they will leave. If you can minimize the broad with a lot of responsibility type of jobs, then your chance for success is greater. What keeps a person on a project they aren't getting paid for and it's not THEIR idea? Nothing. That's why the 1 person who has the broad job with lots of responsibility (level designer) needs to be very dedicated to the project and how do you do that? You make it the game they want to make. Something they are passionate about and people are generally only passionate about games they want to make and not other people's games. The "passion" at a real company comes in the form of a paycheck for the majority of the people
-
I'm working with Tj on a game (just 1 other person) and the biggest issue with LE is that the map can't be worked on by more than 1 person at a time (via source control). It's not text based so it can't be resolved by merging which is a pain (as far as I know). Considering that level design is a massive part of game development it really makes working in a team more difficult. Because of that I think the main person running the project would be better off being a level designer (vs any other skill) who is the only person designing the game level. You can have many artist's making models and committing them to the project at the same time and many programmers making little scripts and committing them to the project at the same time, but you can only have 1 level designer working on a level at a time and that's the point where the models and the scripts come together to make the game so it makes sense that the level designer is the project originator as artists and programmers can come and go at will and it won't be the end of the project, but if a level designer leaves then really you don't have much to show of the game. Doing a few polls to get the game figured out, at some level the project owner needs to be firm with decisions. Once the game idea is set you should be able to get a list of assets (art/sound/scripts) required to make the game. Make this list public and ask if anyone can do any of them. Ideally for the scripts you'd want very well defined self contained scripts that the level designer can hook up in the editor without much trouble. When I lead I went to the extreme of this and didn't tell anyone who was working on what. They all had their task and that was that. I treated it very much like a contract situation. Do your task and that's it. Don't worry about the end result. Don't worry about anything but doing your task. I'd say 75% of the people did this. The problem I had when running this is that I wasn't the level designer. The level designers left or weren't that interested in the project to really put some passion into the level design (which was probably too much to start with), and since I'm not a level designer I couldn't bring everything together well enough in a level. So basically, I think a successful community game is people contributing to a game that a true level designer wants to make. However, level designers may not be well project organizers so they wouldn't start up a community project to start with. So ideally a project organizer starts the community project, finds a level designer and asks them what kind of game they want to make. What kind of game will keep the level designer interested for the long haul as they fill out the assets from people coming and going.
-
Generally speaking with something like this your children would just be pass-thru's to get the variable to it's parent so it's parent can set the variable itself so you don't have to do it in each future child you create. PlayerScript(Entity* e) : IScript(e) { } IScript(Entity* e) : ent(e) { } Right now you only have a PlayerScript child and aren't doing much in IScript but you may in the future have more children of IScript and do more common things that all IScript children should have (this is the main idea behind having a base class right). If you wanted to take it even futher you can set the hooks inside IScript ctor even. IScript(Entity* e) :ent(e) { e->SetUserData((void*)this); e->AddHook(Entity::CollisionHook, (void*)CollisionHook); // etc } It's nice because now your IScript class is doing a job. It's job is to set the user data and hooks. So now you can easily reuse or release this class to the world and we/you don't have worry about setting the hooks anymore (or if you reuse it down the line you don't have to worry either) during entity looping. So think about the purpose of this class. It's to handle the hooks so you can derive your own child scripts from it. Therefore it should register against the hooks for us. Now I'm not saying you will release this but that's the mentality to have with object oriented programming. Pretend you will release it or at least that you will reuse it in other projects (because you probably will) and make it easy on us/your future self. Now your C hook functions could even be inside the IScript.cpp file (not part of the class but just inside the .cpp file itself so everything about this script assigning functionality is contained in 1 header and 1 source file). Now all you have to do for future projects or tell your future users of this class to just include IScript.h/cpp into our projects, derive our own script classes from it, and create instances of the object and that's it! The rest is encapsulated from the user of your class (user or your future self). You now have a nice self contained class doing it's job. Making our job easier
-
Model Editor Save Wipes All Map Instance Settings
Rick replied to tjheldna's topic in Leadwerks Engine Bug Reports
I agree. Just because a model gets updated (for some visual change) doesn't mean we would want all instances to have their settings reset. That doesn't make sense at all. If the editor is deleting all instances and then readding them back in because of the model update, then the editor needs to save off the original settings and reapply them to the new instances. -
That's one way to do it, but honestly if you kept the way you had the IScript ctor and just passed the entity to the PlayerScript() (and any other children of IScript) it would work as well. IScript* script = new PlayerScript(entities[0]); I'm shocked what you have even works. You said you added SetEntity() at the PlayerScript level but I think you must have meant at the IScript level since your script pointer is an IScript and wouldn't be able to see SetEntity() function as the PlayerScript level unless you casted script to PlayerScript which in your example code you didn't.
-
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.
-
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.
-
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.
-
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) { }
-
It can be named anything but it has nothing to do with whatever your player is named. Look at the Use function. It has a parameter called "person" (or "player"). That's what you are using inside the function. Something is calling this function and it's passing an object (most likely the player script) into it. When you are inside the function the variable name you use to access that object is whatever the parameter name is. That parameter could be named 'a' or 'i' for all we care. It's just a variable that allows you to access whatever was passed into that function when it was called. Use() is not an LE special function. It's being called (most likely from FPSPlayer.lua). Find out where it's being called from and see what is being passed in. Knowing about function parameters is fairly basic programming 101 stuff and has nothing to do specifically with LE. You might be better off in either taking a lesson from me or reading up on just Lua in general. This error is telling you that the weapons variable doesn't exist in the player variable object.
-
I guess I never really considered this a problem needing solving. Maybe because I'm just used to using LE for so many years but now that I see these functions it does seem like it would be easier to work with. Thanks for sharing.
-
Attempting to call a method of an entity from another entity
Rick replied to Raxe88's topic in Programming
The entity and a script attached to that entity are 2 different things. You can get either from both. entity.script or (inside the script) self.entity (note that when inside a script 'self' refers to the script itself NOT the entity) The collision callback is returning to you the entity NOT the script. So in order to call the script functions attached to the entity you need to access the script variable of the entity. entity.script:Respawn() Now entities do have functions (as you see in entity:SetPosition()) but those are C++ engine commands on the entity. The scripts are different than the built-in engine functions. This whole script thing is something that didn't exist in the early days of LE but something like SetPosition() has existed since day 1. Scripting functionality was added later after the core engine functions were already there. -
His calls person.weapons because person is what he called his function argument parameter. I think the assumption here is that the fpsplayer.lua is calling this scripts Use() function and passing itself into it. I don't use the FPSPlayer.lua script but does it have a weapons table in it? Now passing itself could be either that it passes 'self' or 'self.entity'. If it passes 'self' then it's the script itself and you can use script variables directly from the function parameter. If it's 'self.entity' then you'd have to use 'person.entity.script.variable' which would be silly that it does that. No real sense in passing self.entity to the Use function. You have to know what is calling these Use() functions and what they are passing in as the parameter, in order to debug this stuff.
-
My advice would be to make the simple "get me this I'll give you that" first
-
I think we need to look at what makes a character. - 3D Model - Attributes - Functionality Atributes and Functionality doesn't need to be part of the LE Script directly. They can be variables to a Lua class inside them. What this means is that you can create 1 script called Actor and have variables that control functionality. Functions are variables in Lua. That means you can assign functions to variables. So let's say you have 2 standalone functions: function AI_Think(actor) -- AI logic end function Player_Think(actor) -- user input end Now in your 1 Actor LE script you have a variable named something like self.update where for the player you set it to Player_Think and call self.update() inside UpdateWorld. function Script:Start() if player then self.update = Player_Think else self.update = AI_Think end end function Script:UpdateWorld() -- this will call the correct function based on what this actor is self.update(self) end Passing functions around to variables is basically like your lua code injection. This is why Lua is so powerful. Functions as variables opens the door to some interesting things
-
So remember that functions are just variables. So define these variables in a common script and then for each instance you can assign your custom function to that instances variable. 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