-
Posts
7,936 -
Joined
-
Last visited
Content Type
Blogs
Forums
Store
Gallery
Videos
Downloads
Everything posted by Rick
-
This is a tough one. I just took the 2 scripts you posted and made a test scene and it worked just fine. If your map has just the default stuff (models/textures that come with LE) then can you attach both maps and I can test it.
-
And that map exists in your maps folder for the current project you are in? Can you load that map in the editor and it doesn't give and error itself?
-
So you attached LoadLevel.lua to a csg that is of type Trigger? Then you filled out the Map parameter with a valid path/file to a map? What value did you give the Map parameter of the csg trigger you have LoadLevel.lua attached to
-
I should have some time tonight to plug away at it again. I want to try and get a little cutscene as a test going tonight as well. Stay tuned!
-
@cassius What fbx version and settings do you use to export fbx from UU3D? I've had issues with it. Can you show an example of the export dialog box that works for you?
-
Sorry, I updated my last post with what is probably wrong. I looked at your code on Steam.
-
Looking at your code from steam. Inside ShouldSwitchLevel() you have Map.Load() instead of Map:Load(). It's different because Map: passes a variable as the first parameter behind the scenes for you, while Map. does not, when calling functions.
-
You need to access it via the actual variable name (hud in this case) NOT it's label name "HUD". Lua is case sensitive. If you have Script.hud = nil --entity "HUD", then you access it's functions/variables with: self.hud.script:Function() self.hud.script.strength = 5 The part in "s is just a label name to show in the editor and not the name of the actual variable.
-
How do you know the player is chopping a tree then? The player needs to interact with the tree model and you need to know the thing the player is interacting with is a tree. Generally with this you'll do a raycast from the player toward the middle of the screen (if in first person). Then when it collides with an entity you can see how long the ray is to determine if you are close enough. But then you need to know what model it collided with somehow, so that model needs to identify itself. If trees have max wood count then each tree needs to hold this value. This is why a script attached and make it a prefab so you can easily just place them in the world, would probably be a decent way to go about that.
-
Because this is how "aggro" works, and it doesn't have to be each frame. A timer could make it look every 250ms or something. You don't need to drag the player in all of those things. Collision zones for example fire a collision event which passes the entity that collided with it. You use that to check if it's the player. Don't say I didn't warn you about the evil ways of globals
-
3dws is an older product that I believe Josh made. It's even more like Hammer than LE3 is. It has all csg options like carve/hallow/etc. It's why although LE3 doesn't have these features yet, some of us aren't worried because we know Josh has done it before. It's just more about priorities on Josh's time before they come to Leadwerks 3. 3dws didn't have any scripting attached like LE3 does though so people mostly just used it to build their level, then export it and bring it into LE 1/2.
-
I would agree that player could be setup this way. Although how your NPC's interact and "find" the player often doesn't require having to know the player object right away on startup. Darkness Awaits, along with many other game styles, finds the player via a bounding box check around the NPC (aggro range). If you have some kind of spawner(s) that makes NPC's (think L4D when horde is alerted), the spawner would only need to know about the player and pass that knowledge on to the NPC's it creates so it's assigning that information to a lot less entities in your scene. When you shoot at a zombie the "bullet" information can hold the "shooter" which would be the player and the zombies could be informed that way.
-
The install should be in your steam folder: E:\Steam\steamapps\common\Leadwerks Indie Edition\_CommonRedist\OpenAL\2.0.7.0 That should put it in your system folder then I believe. C:\Windows\System32\OpenAL32.dll
-
I find the same problem. I can't leave Leadwerks open and not doing anything with it (maybe minimized) for a long time or else it crashes when I try to go back to it. I just left it open over night and this morning I tried to move around in the perspective view and it was chopping and slow for a few seconds, then it crashed.
-
Yeah, that is another solution, but again it's going down the global path. You'll have to know/remember that App.lua is at a higher level than a loaded map, so when you load a new map from the same game session that variable that's pointing to "player" will no longer be valid (because you would have had to free the current world to load a new map) and you'll have to reassign it. I know it's easy to do and when your project is small it doesn't seem complicated, but this is really one of those things where you have to watch out for. The last thing you want is to get far in your game and have to restructure major parts because you start finding it confusing because you have global variables everywhere. When newer to programming it's one of those things that's hard to understand what the issue is with globals until you've experienced it themselves.
-
You can connect entities that have scripts attached to other entities. Let's say you have a HUD script that needs the Ammo count from the player. In the player script you can define a HUD parameter as entity: Script.HUD = nil --entity. Then drag and drop the HUD pivot that you have the HUD script attached to it. Now inside player you have access to all of the HUD scripts functionality via: self.HUD.script. You can call functions, assign variables, whatever. Another way to do it with flowgraphs, would be to fire an output each time the weapon is fired. Then in the player script have a GetAmmoCount()--arg, and in the HUD script have SetAmmo(count). Then you can link the Shoot or Fire output to the HUD's SetAmmo(), connecting the GetAmmoCount() arg function. If you aren't going to set the information with the boxes, then how will you get it? Well, you could load a file to get it. What file? Well that could be the information you hold in the input box. What file to open, read, and set a variable. Then you can still use the same GetText()--arg idea. There are no real need for globals. I'm trying to understand why you think you would need globals in the situations you mentioned. You can also loop through every entity that is loaded with: for x=0,App.world:CountEntities()-1 do local entity = App.world:GetEntity(x) if entity:GetKeyValue("type") == "player" then self.target = entity end end You could do this in the Start() function of a script to get entities that you care about and store them in a variable to use later. You'd have to set your own key inside said entities to identify them. However, this isn't that much different (and is slower) than just assigning things via the script parameters.
-
I joined a team once to make a game from GameDev. I can't even tell you how horrible of a nightmare their code was. Everything, I honestly mean that, was global. One giant switch statement to control the entire game. They would complain about some other developer who would say they need to fix this, but the reality is they were very new to programming, very determined, but very new, and globals were the easy route to take because you didn't have to think about designing how things would interact, but that's really what is meant by a good design. That's 1/2 the challenge to making good maintainable code. I would challenge anyone who uses globals on a regular basis to think about how they would remove those globals. Once you do that over and over again, then you won't go back.
-
Normally you would want to only loop over the entities to find the one you want in the Start() function of the scripts and then save it in a variable for later use. Looping over them in an update loop won't be the end of the world but slower. The way you avoid checking all entities to find the one you want is by connecting them in the editor via a script parameter , which you said you wanted to avoid.
-
If you do not want to drag a player entity into a field, then your other option is to loop over all loaded entities looking for the player inside your other script. Inside your start method: for x=0,App.world:CountEntities()-1 do local entity = App.world:GetEntity(x) if entity:GetKeyValue("type") == "player" then self.target = entity end end The reason this works is because the "type" key was set to "player" in the player script. You can do this for any loaded entity. Note that there is this sort of "hidden" dependency you are creating by doing this with this script. This requires that an entity in your scene has a key value "type" of "player". It may not look bad now with 1 thing, but if you do this enough your scripts and the indirect dependencies can be confusing for others, and maybe even yourself in a couple weeks. You could wrap this up in a nice function like FindEntityByName() where you would return a table of entities (because names don't have to be unique), or FindEntityByTag(), where it has a key of "tag" with a value (sort of like Unity does). The efficiency of this is not great though. Be sure to try and stick to this only in the Start() method as it loops over all entities in the world. Of if you bailed out once you found yours, you don't know how many iterations it will need to get to the one you need. Direct linking via the editor is faster.
-
What sort of skills do you bring to the table? Are you an artist? Do you have a game in mind?
-
While I think Shadmar is great and the things he provides this community are amazing, I would warn anyone, especially people maybe newer to programming, to try and avoid global variables. They will eventually make your program a nightmare to maintain. The code will eventually become a spaghetti mess of dependencies that almost nobody but yourself will be able to follow, and after a couple months even you won't be able to follow it. They are convenient, but deadly. The tight coupling that they can also introduce sucks. You can make an entire game without global variables which will yield many benefits. A google search as to why globals are bad will explain these.
-
CollisionScript (attach to some csg) Script.entered = false Script.exited = false Script.hadCollision = false Script.Text = "" --string function Script:GetText()--arg return self.Text end function Script:UpdatePhysics() if self.entered then if self.hadCollision == false then if self.exited == false then self.exited = true self.component:CallOutputs("OnExit") self.entered = false end end end self.hadCollision = false end function Script:Collision(entity, position, normal, speed) self.hadCollision = true self.component:CallOutputs("OnCollide") if self.entered == false then self.component:CallOutputs("OnEnter") self.entered = true self.exited = false end end DrawTextScript (attach to a pivot) Script.Text = "" --string function Script:SetText(text)--in self.Text = text end function Script:PostRender(context) context:DrawText(self.Text, 0, 0) end Bring both pivot and csg into the FLowgraph and you should see the outputs/inputs/args. Drag CollisionEnter to SetText, then drag GetText to the little dot on the line between CollisionEnter and SetText This was done off memory but it should work.
-
One way is to use flowgraphs. Make a new script file called something like TextCollision and copy the code from here: http://leadwerks.wikidot.com/wiki:collision-enter-exit Add a script level parameter called Text (Script.Text = "" --string). This makes it so you can reuse this script many times and display different text on each instance. Attach this to some csg brush and change it's physics to Trigger (and probably paint the invisible material on it). Create a function like: function Script:GetText()--arg return self.Text -- this is whatever you named your script level variable to store the text end Then place your pivot in your scene and make a script that does the drawing of the text to the screen (the thing is you could just have this collision script do the drawing if you wanted but if you don't for some reason this is another way). This script should have a function for setting the text that it should display defined like: function Script:SetText(text)--in self.text = text end function Script:PostRender(context) if self.text ~= "" then context:DrawText(fill this in) end end Open the Flowgraph from the menu bar. Drag in your csg brush and your pivot. Drag a line from the CollisionEnter output to the SetText input. You'll see a little dot in that line. That shows up because SetText() takes a parameter and this dot represents this parameter. Drag the GetText() (which had the --arg after it in the function def) to this dot in the middle. This is one way to pass variables around between objects when outputs raise inputs.
-
That sounds pretty tedious though. Most of the models I buy have LOD's to them. Being able to define what model files are what LOD in the model editor for a specific model seems easier to me. I would prefer this setup over naming conventions myself.
-
If you haven't seen this already here is a tutorials post I maintain that holds current tutorials and future tutorial ideas for anyone to create. http://www.leadwerks.com/werkspace/topic/8103-gameplay-tutorial-requests-here/