Jump to content

Josh

Staff
  • Posts

    22,895
  • Joined

  • Last visited

Everything posted by Josh

  1. Josh

    Relay

    Visually, with arguments, yes. Then you have a bunch of abstract game logic scripts that move platforms around, open and close doors, perform logic, turn lights on and off, etc. So to make something like a Mario 64 level, you drop in some pre-coded AI , make some moving platforms with the flowgraph, and execute a script that makes a little guy run around. There's your game. Select the File>Publish menu item, package it up, and submit to Steam, the App store, or upload it here. And if you need to modify code at any time, you can always drill down to the script level or even C++ code. So it's super easy and visual without crippling it. flachdrache, your example could be done in script like this: function actor:Update() if onfire==true then health = health - 1 if health < 1 then self:Explode() end end end function actor:Explode() local emitter = CreateEmitter() --do stuff to make an explosion delete self end I don't know if you would want to make flowgraphs for reusable behavior like that. I see it as a per-scene visual script that controls gameplay logic. Remember in the original Unreal Tournament, there is one map that has a room with a weapon inside, and there's a button outside the door that will seal the room and incinerate anyone in it? That's a good example of what I have in mind.
  2. Josh

    Relay

    Ladies and gentlemen, here's the money shot. Arguments can be added to the link between actors. In the example below, activating the button will call the platform's MoveTo() function, passing the Marker's property member and the Constant's value member to it. The platform script will then use that position as the target it is moving towards, and move to it until it reaches that point, at the given speed. And that is my idea for how gameplay will be made in Leadwerks Engine 3. The code side of this is actually working. I can set up outputs, arguments, and actor scripts can provide either members or functions that return a value for the arguments. This is only possible because of the flexibility of Lua. It is very adaptable with differing numbers of function parameters and return values, so you can adjust these nodes without worrying about perfectly matching argument types and count.
  3. I don't know about their business plan. I can't even figure out how much anything would cost.
  4. Josh

    Relay

    And here's what a flowgraph for the above sequence would look like:
  5. This will reset everything. The shocks bounce a bit, but I don't know if that is an issue: require("Scripts/constants/keycodes") require("Scripts/linkedlist") require("Scripts/filesystem") require("scripts/math/math") require("scripts/constants/engine_const") FlushKeys() HideMouse() local camera = fw.main.camera chassis=LoadModel("abstract::vehicle_viperscout.gmf") carobject=objecttable[chassis] car=carobject.vehicle if car==nil then Notify("Vehicle object not found.",1) chassis:Free() return end chassis:SetPosition(TFormPoint(Vec3(0,-1,10),fw.main.camera,nil)) chassis:SetRotationf(0,camera.rotation.y+180.0,0) --Variables local dx=0.0 local dy=0.0 local camerapitch=camera.rotation.x local camerayaw=camera.rotation.y local move=0.0 local strafe=0.0 local steering = 0.0 local torque = 0.0 local steerlimit = 30.0 local steerrate = 2.0 local steerangle=0.0 MoveMouse(Round(GraphicsWidth()/2),Round(GraphicsHeight()/2)) while KeyHit(KEY_ESCAPE)==0 do --Camera look gx=Round(GraphicsWidth()/2) gy=Round(GraphicsHeight()/2) dx=Curve((MouseX()-gx)/4.0,dx,3.0/AppSpeed()) dy=Curve((MouseY()-gy)/4.0,dy,3.0/AppSpeed()) MoveMouse(gx,gy) camerapitch=camerapitch+dy camerayaw=camerayaw-dx camerapitch=math.min(camerapitch,90) camerapitch=math.max(camerapitch,-90) fw.main.camera:SetRotationf(camerapitch,camerayaw,0,1) local tirespeed=-(KeyDown(KEY_UP)-KeyDown(KEY_DOWN))*2.0 car:AddTireTorque(tirespeed,0) car:AddTireTorque(tirespeed,1) car:AddTireTorque(tirespeed,2) car:AddTireTorque(tirespeed,3) steermode=0 if KeyDown(KEY_RIGHT)==1 then steermode=steermode-1 end if KeyDown(KEY_LEFT)==1 then steermode=steermode+1 end if steermode==1 then steerangle=steerangle+4.0*AppSpeed() elseif steermode==-1 then steerangle=steerangle-4.0*AppSpeed() else if steerangle>0 then steerangle=steerangle-4.0*AppSpeed() if steerangle<0.0 then steerangle=0.0 end else steerangle=steerangle+4.0*AppSpeed() if steerangle>0.0 then steerangle=0.0 end end end steerangle=Clamp(steerangle,-25,25) car:SetSteerAngle(steerangle,0) car:SetSteerAngle(steerangle,1) fw:Update() local campos=TFormPoint(Vec3(0,1,0),chassis,nil) fw.main.camera:SetPosition(campos) fw.main.camera:Move(Vec3(0,0,-10)) local t=TFormVector(Vec3(0,0,1),camera,chassis) a=-math.deg(math.atan2(t.x,t.z))+180.0 carobject.turret:SetRotationf(0,CurveAngle(a,carobject.turret.rotation.y,10.0/AppSpeed()),0) chassis:Hide() local pick = LinePick(campos,camera.position,0.5,COLLISION_PROP) chassis:Show() if pick~=nil then camera:SetPosition(pick.position) end if(KeyHit(KEY_SPACE)==1) then chassis:SetPosition(Vec3(0,0,0)) chassis:SetVelocity(Vec3(0,0,0)) chassis:SetOmega(Vec3(0,0,0)) end fw:Render() Flip(0) end chassis:Free() chassis=nil camera=nil ShowMouse()
  6. Josh

    Relay

    Here's a C++ example that makes a button open a door after a delay. I don't recommend setting these relationships up in code, but it does show what's going on under the hood: //Create the button Model* buttonmodel = LoadModel("button.mdl"); Actor* button = LoadActor("button.lua",buttonmodel); //Create a relay. Since no entity is defined, it will just create a pivot Actor* relay = LoadActor("relay.lua"); //Create the door Model* doormodel = LoadModel("door.mdl"); Actor* door = LoadActor("door.lua",doormodel); //Set outputs new Output(button,"Activate",relay,"Activate"); new Output(relay,"Activate",door,"Open"); //Set the delay relay->SetInt("delay",5000); //And now to set off the sequence: button->CallOutputs("Activate");
  7. Josh

    Relay

    I actually have this working in an example. This is just a relay that accepts an input and sends it after a pause: function actor:Start() self.delay = 3000 self.queuedevents = {} end function actor:Activate() self:AddEvent("Activate") end function actor:Deactivate() self:AddEvent("Deactivate") end function actor:Enable() self:AddEvent("Enable") end function actor:Disable() self:AddEvent("Disable") end function actor:AddEvent(name) local event = {} event.name = name event.time = AppTime() + self.delay table.insert(self.queuedevents,event) end function actor:Update() local n,event,t t=AppTime() for n,event in pairs(self.queuedevents) do if t>event.time then self:CallOutputs(event.name) self.queuedevents[n]=nil end end end
  8. What page are you looking at? The last news item is May 17, 2011.
  9. Does setting the velocity like that work, or do the wheels make it immediately pick up speed again?
  10. Has anyone created and animated a character from scratch with Mixamo?
  11. You are requesting two contradictory things at once. Are you asking for a Leadwerks modeling and animation program, or an export plugin for an existing program? Or are you just saying you feel overwhelmed by the array of existing modeling programs, and want some solution to making animated characters?
  12. Now I've actually got a LoadScript() command, and a script and an actor are NOT the same thing! Load and run a script: script = LoadScript("mygame.lua"); script->Run(); script->Run(); script->Run(); Attach a script to an entity: script = LoadScript("Mover.lua"); actor = new Actor(entity,script); actor->SetVec3("turnspeed",0,1,0); The script must have a Main() function to be run, and it must contain actor:whatever() functions to attach it to an entity. It's complicated, but the script loads all the actor functions into a table, and then the functions get copied to each actor. That way the engine isn't calling DoString() each time and creating a bunch of unique functions in the virtual machine. So if you have an actor script that is attached to 100 different entities, there is only one set of shared functions, but the actor userdata is not shared, so each one can have different values. It also means you can load a script once and run it multiple times, and that will be faster than executing a file each time, because the parsing step will be skipped.
  13. Are you asking for a modeling and animation program made by Leadwerks that integrates into the engine better?
  14. Josh

    Small Victories

    Two issues in the art pipeline were giving me some doubt. I stopped working on them a couple weeks ago, and I'm glad I did because the solutions became clear to me. Shader FilesFirst, there is the matter of shaders. A shader can actually consist of half a dozen files:bumpmapped.opengl3.vert bumpmapped.opengl3.frag bumpmapped.opengl4.vert bumpmapped.opengl4.vert bumpmapped.opengles.vert bumpmapped.opengles.vert I originally thought the .shd extension would be good for shaders, in keeping with our extension naming scheme, but there's actually no information an .shd file even needs to contain! I also considered creating a simple format that would pack all the shader strings into a single file, and display the different ones for whatever graphics driver was in use at the time, but that approach reeked of future confusion. I'd like to still be able to open .vert and .frag files in Notepad++ or another text editor. I came up with the idea to use a .shd file that contains all these shader files, but instead of packing them into a file format, the .shd file will just be a renamed .pak. That way you can easily extract the original text files, but shaders can be distributed and loaded as a single file. Material TexturesI've been working with a system that uses texture names defined in the shader file. It works and it's really cool, but I think I have something even cooler. Instead of requiring a shader to define texture unit names, it would be less confusing to just decide on a fixed naming scheme and stick with it, something like this:texture0 - Diffuse texture1 - Normal texture2 - Specular texture3 - Reflection texture4 - Emission texture5 - Height And in C++ you would have constants like this: #define TEXTURE_DIFFUSE 0 #define TEXTURE_NORMAL 1 ... If you want to create a bumpmapped material, you can simply assign textures 0 and 1, and the material will choose a shader with the assumption those are supposed to be the diffuse and normal map. If the current surface being rendered contains bone weights, an animated version of the shader will be used. If a shader is explicitly defined, that of course will override the material's automatic selection. This way, all you have to do is drag a few textures onto a material, and 95% of the time no shader will even have to be explicitly defined. This is similar to the materials system in 3ds max. The programmer in me screams that this makes no sense, since texture units are completely arbitrary, but from a usage standpoint it makes sense, since the exceptions to this paradigm probably make up less than 5% of the materials in any scene. Now for custom shaders, you might end up with a situation where you are dragging a texture into the "reflection" slot, when it's really going to be used to indicate team colors or something, but it's still far simpler to say "set the reflection texture with...". Everyone knows what you mean, textures can be set in code without having to look up the slot number in the shader, and there's no ambiguity. Anyways, that's just two small design problems overcome that I thought I would share with you. I think the texture issue really demonstrates the difference between engineering and product design. http://www.youtube.com/watch?v=5U6Hzjz5220
  15. Please use the bug tracker. There's no way I can remember different forum posts throughout the site.
  16. Josh

    Huge bug-report

    Please use the bug tracker. There's no way I can remember different forum posts throughout the site.
  17. Has anyone used this? It makes big promises. Does it work well?: http://www.mixamo.com/
  18. I'm not clear on what this request is actually asking about.
  19. Josh

    Multimap

    I've never used the std::multimap before, and have use for it now. Here's the class: class Actor : public Object { public: std::multimap<std::string,Output> outputs; }; I need to add an object into the map, without removing other objects that use the same key: void Actor::AddOutput(Actor* target,const std::string& outputname, const std::string& inputname) { Output out; out.target = target; out.functionname = inputname; outputs.insert(pair<std::string,Output>(outputname,out));???????????? } And I want to iterate through all objects for a given key: void Actor::CallOutputs(const std::string& name) { /*Output out; out = (outputs.find(name))->Second out.Call();???????*/ } Anyone know how to do this?
  20. I am still interested in doing this as a standalone visual tool for shaders, but I agree with Brent's take on using it for game logic. A non-programmer still is going to have no idea how to do anything with it, and a programmer will be similarly perplexed, Now, Rick has been working on something like this, and I think it;s really cool and look forward to seeing what he implements. If he created some tool and sold it to users, that could be really interesting. The consumer in me is intrigued. But I don't want to gamble my engine on this approach, because it's a niche.
  21. Josh

    ColorOscillate

    Now it's getting cool: teapot = LoadModel("models/teapot.mdl"); Actor* actor; actor = teapot->AttachScript("ColorOscillate.lua"); actor->SetFloat("speed",4.0); actor = teapot->AttachScript("Mover.lua"); actor->SetVec3("turnspeed",Vec3(0,1,0)); actor->SetBool("global",true);
  22. Josh

    LE.NET

    C# is not officially supported at this time.
  23. I presume the reason for this would be to attach multiple entities to the same actor, in which case there would be no per-entity values in the script. The script would only have values shared across all entities it was attached to. Can you think of a situation where this would be useful? I mean, you could use this so you could just control the values of one actor and have it affect all the entities it is attached to, but it would be very limited because it would only allow shared variables in the script.
  24. Okay, now I have an Actor C++ class that gets created when a script is attached to an entity. You can set and get values on the Actor itself: Actor* actor[2]; Model* teapot = LoadModel("teapot.mdl"); actor[0] = teapot->AttachScript("ColorOscillate.lua"); actor[1] = teapot->AttachScript("PointAt.lua"); actor[1]->SetObject("target",camera);
×
×
  • Create New...