Jump to content


  • Content Count

  • Joined

  • Last visited

Blog Entries posted by tipforeveryone

  1. tipforeveryone
    I spent a whole week for learning UE4 with cpp, yep, UE4 is a great engine for sure, but I found out that my mind could not understand the way UE4 works easily. It is too complex and made me tired. Then I returned to my Leadwerks project and felt so familiar. Soooo... sweet, everything is simple as it is
    It felt like I have had a long trip to UE city then return to my hometown. I miss Leadwerks indeed.
    Last year, I thought I could only use Leadwerks with LUA and never touch its CPP side. But I tried my best, learned Cpp for 8 months. Now I am not a cpp pro but I am confident in using this language. At least I can rewrite my whole project in CPP instead. this 3-years project helped me to understand my potential and interest in gamedev.
    I wish Josh be successful in progress of making Turbo, a new hope for much better Leadwerks.
    To all people who are using Leadwerks and help me these years, love you.
  2. tipforeveryone
    II. Implement advanced actions
    Previous tutorial guided you to create your own FPS Character Controller with basic actions: Move, Look.
    This tutorial will help you add some advanced actions like Jump, Run, Crouch, and Lean
    *Note: Below steps will use code from previous tutorial (CharacterController.lua)
    1. Jump / Run / Crouch
    Firstly, build obtacle with space under it to test crouching, the space height shoud be at least 120cm (leadwerks editor will show you this height in other viewports) You can not crouch and pass space under 120cm, this was hardcoded

    Next, modify the code.
    Add new variables under --Character movement variables comment. Note that putting script variables at the top of script will allow you to modify character stat easier and faster than finding variables deep inside script's functions
    --Character movement variables Script.playerSpeed = 2 --higer = faster Script.playerRunSpeedMultipier = 2 --if this variable < 1, you can make slower movement Script.playerJumpForce = 7 --This defines how high you can jump Add new funtion to smooth movement of character components function Script:SmoothPosition(position,entity,rate) local smoothX = Math:Curve(position.x,entity:GetPosition().x,rate) local smoothY = Math:Curve(position.y,entity:GetPosition().y,rate) local smoothZ = Math:Curve(position.z,entity:GetPosition().z,rate) entity:SetPosition(smoothX,smoothY,smoothZ) end Replace code in Character_Movement() function by this code function Script:Character_Movement() local playerSpeed, playerJumpForce, playerCrouch --Press Space bar to Jump if window:KeyHit(Key.Space) then playerJumpForce = self.playerJumpForce else playerJumpForce = 0 end --Hold Ctrl key to Crouch if window:KeyDown(Key.ControlKey) then playerCrouch = true else if self.playerHeadBlocked then playerCrouch = true else playerCrouch = false end end --Hold Shift key + AWSD to Run if window:KeyDown(Key.Shift) then playerSpeed = self.playerSpeed * self.playerRunSpeedMultipier else playerSpeed = self.playerSpeed end local playerMove = ((window:KeyDown(Key.W) and 1 or 0) - (window:KeyDown(Key.S) and 1 or 0)) * playerSpeed local playerStrafe = ((window:KeyDown(Key.D)and 1 or 0) - (window:KeyDown(Key.A) and 1 or 0)) * playerSpeed --Using local playerSpeed varialbe instead of self.playerSpeed in the old code local playerTurn = self.playerNeck:GetRotation(true).y self.playerBase:SetInput(playerTurn,playerMove,playerStrafe,playerJumpForce,playerCrouch) end Replace code in Bind_Character_Components_Together() function too function Script:Bind_Character_Components_Together() --Must use this reposition process because playerBase is not playerNeck's parent, they are indipendent. local basePos = self.playerBase:GetPosition(true) local height if window:KeyDown(Key.ControlKey) then height = basePos.y + (self.playerHeight - self.neckLength) / 2 --You can adjust this variable to get desired crouch height for playerNeck (and playerEyes too) else if self.playerHeadBlocked then height = basePos.y + (self.playerHeight - self.neckLength) / 2 else height = basePos.y + self.playerHeight - self.neckLength end end self:SmoothPosition(Vec3(basePos.x,height,basePos.z),self.playerNeck,10) end Add a new function to script, this will keep player crouching if something block above character when release Ctrl key, prevent from being pushed around by obtacle when standing. function Script:Check_Head_Block() --We can use a raycast to check if something block character head when crouching local pickInfo = PickInfo() local point1 = self.playerNeck:GetPosition(true) local point2 = self.playerBase:GetPosition(true) + Vec3(0,self.playerHeight,0) if world:Pick(point1,point2,pickInfo,0.3,true) then self.playerHeadBlocked = true else self.playerHeadBlocked = false end end Update Script:UpdateWorld() function with new Check_Head_Block() function function Script:UpdateWorld() self:Bind_Character_Components_Together() self:Check_Head_Block() self:Character_Look() self:Character_Movement() end Now, you can crouch under obtacle, release Ctrl Key and you are still crouching. Continue moving for auto standing. 2. Leaning
    In Character_Movement() function, add this code after Crouching code
    --Hold Q/E to lean Left/Right local leanDistance = 0.025 --leanDistance should be < 0.025 or camera will pass through wall when you get too close if window:KeyDown(Key.Q) then self.playerEyes:Move(-leanDistance,-0.01,0) end if window:KeyDown(Key.E) then self.playerEyes:Move(leanDistance,-0.01,0) end And add this line at the bottom of Bind_Character_Components_Together() function self:SmoothPosition(Vec3(0,self.neckLength,0),self.playerEyes,10) You can lean now, so smooth. Final script file was attached to this entry. You can apply it to a pivot point (PlayerControl).
  3. tipforeveryone
    After 7 months learning Leadwerks Game Engine, I wanna show you guys my very first techdemo of my game

    1. Fully functional GUI created by myself:
    Menu are global for all maps
    Adjust ingame graphic and show the result directly, (include night time and night vision goggle test - thanks to shadmar's shader)
    Graphic settings can be saved to a config file for next time game starts
    Let you choose game language, language can be saved too (if I want)
    Scenarios selection (At this time, I only have one map)
    Camera following mouse movement effect
    Background music and sound effect for menu elements when not ingame
    Faded in/out map loading screen

    2. Custom FPS player controller
    Switch between FPS / TPS Mode
    Switch member to member in a squad (Squad managerment system)
    You can see your own shadow and some body parts in FPS Mode
    Can Walk / Sprint / Lean left / Lean right / Crouch
    Player Breath control (this can affect weapon shooting)

    3. Weapon system
    Simulate movement when player walking/running
    Can use attachments: flashlight, scope, suppressor (WIP), laser (WIP)
    Simulate gun fire modes: single shot, double shot (AN94), burst shot (MP5), Full Automatic
    Weapon safety ON/OFF
    Weapon block when close to wall, NPC
    Scope zoom level can be adjusted
    Gun managzine manager system (reload has no animation yet)
    Gun recoil control system
    Good gun shells ejection physic.

    4. AI System
    NPC look at player with limited angle of his neck :"D

    And many small features
  4. tipforeveryone
    This tutorial will help you to make something like this


    Step 1: Prepare scope model
    In 3D application, import your 3d scope model and adjust its pivot point. Make sure the pivot's position looks like image below. This step is extreme important! The position of pivot point is the position of Scope Camera Render Target
    If you use Blender, press Ctrl + A > Location / Scale / Rotation to reposition scope's pivot
    Example model file attached at the bottom of this entry

    Export this scope model to FBX in Leadwerks
    Step 2: Build scope's components
    According to above concept, we have 3 main components: Scope Camera, Scope Model, Scope Camera Render Target. We will create them, one by one using LUA
    First, import Scope Model to the scene > create a new Script > rename it to "Scope.lua" > apply script to Scope Model.
    Here is the code

    Script.scopePhysicalLength = 1 --This is actually the distance from Scope Camera to Scope Camera Render Target Script.scopeResolution = 512 --Scope render resolution, higer = better look = performance cost, 256 is fine Script.scopeFOV = 4 function Script:Start() --Create Scope Camera Render Target (SCRT) first self.scopeTexture = Texture:Create(self.scopeResolution,self.scopeResolution) self.scopeMaterial = Material:Create() self.scopeMaterial:SetShader("Shaders/Model/Diffuse.shader") self.scopeMaterial:SetColor(1,1,1,1) self.scopeMaterial:SetSortMode(true) --"SortMode = true" will eliminate the unwanted black shade in SCRT when render self.scopeMaterial:SetTexture(self.scopeTexture) self.scopeRenderTarget = Model:Cylinder(32) self.scopeRenderTarget:SetParent(self.entity) self.scopeRenderTarget:SetPosition(0,0,0) self.scopeRenderTarget:SetRotation(0,0,0) self.scopeRenderTarget:SetScale(0.065,0,0.065) --X and Z axis of scale should be adjusted to make sure SCRT is fit inside Scope Model self.scopeRenderTarget:SetMaterial(self.scopeMaterial) --Create Scope Camera self.scopeCamera = Camera:Create() self.scopeCamera:SetParent(self.entity) self.scopeCamera:SetPosition(0,self.scopePhysicalLength,0) self.scopeCamera:SetRotation(-90,0,0) self.scopeCamera:SetClearColor(1,1,1) self.scopeCamera:SetFOV(self.scopeFOV) --this FOV value should be smaller than 20 to make the zoom effect self.scopeCamera:SetRenderTarget(self.scopeTexture) --Create Scope Reticle self.scopeReticle = Model:Cylinder(32) self.scopeReticle:SetParent(self.entity) self.scopeReticle:SetPosition(0,-0.001,0) --make sure Reticle stays between main camera and CSRT self.scopeReticle:SetRotation(0,0,0) self.scopeReticle:SetScale(0.065,0,0.065) --This reticle should be the same size as SCRT local mtl = Material:Load("Materials/reticle.mat") self.scopeReticle:SetMaterial(mtl) end
    Step 3: Check the resuilt
    It should look like this

    Small tutorial: How to create your own reticle texture
    - Step 1: Use Photoshop or Gimp to create a PNG image of a reticle, it should look like this

    - Step 2: Save this file to Leadwerks Project Assets Folder (ie: Materials/reticle.png) it will be converted to reticle.tex automatically
    - Step 3: In Leadwerks, right click reticle.tex > Generate Material then config this material like image below

    That is how you got your own scope reticle
    *Tip: You can attach Scope Model to a Weapon Model and combine with iron sight feature in my previous tutorial
  5. tipforeveryone
    It should be great if you can create a game world which has exact real-life object's dimensions. If you are using Blender to make game props for Leadwerks, these are some simple steps to help you archive the dimension match up.
    Step 1:
    In Blender, go to Properties panel > Scene tab > Unit group Choose "Meters" from list. Make sure Length = Metric, Angle = Degree, Unit scale = 1 Step 2:
    This step is optional but can make you feel better with grid floor In 3D View, Press N to open Properties region > Display group Change Lines = 256, Scale = 0.1 From now on, you can adjust object's dimensions parameters in Properties region to match real-life dimensions, it will be the dimensions when you import models into Leadwerks. Don't for get to Apply Transformation for object model, it is important. Do this before adjust object's dimensions. In blender Use Ctrl + A > Location / Rotation & Scale
    Step 3: Fbx export
    Menu File > Export > Fbx Choose Version = FBX 7.4 binary Scale = 0.01
    Step 4: Adjust exported model in Leadwerks Game Editor
    Double click mdl file in Assets Explorer to open it in model editor. Menu Tools > Collapse. This make sure model local rotation is correct. Menu Files > Save. I attached my template .blend file below this post. It included a 1.7m height human model for better reference.
    Leadwerks Blender Scale.zip
  6. tipforeveryone
    (Note: English is not my native language)
    If you want to create a weapon that can use ironsight for aiming, this tutorial is for you.
    (requested by Jen)

    Step1: Suitable weapon model
    Make sure your weapon's pivot point is laying on weapon's line of sight in 3D application (I use Blender)
    and weapon's direction is heading to the positive global Y Axis, we will export this weapon as a fbx file into leadwerks to get mdl file.
    In blender, after adjusting weapon to its right position, you can use Ctrl + A > Location / Rotation / Scale to setup weapon pivot base.

    Step 2: Camera and weapon setup
    - In Leadwerks, put a camera into the scene
    - Create a new LUA file, name it "CameraControl.lua" then apply to created camera
    - I attached a sample weapon model in this blog, you can use it for your experiment (it was adjusted as step1, even the size of weapon). Put it in Models folder (Models/ak47.mdl)
    Here is the code:

    Script.norPos = Vec3(0.2,-0.2,0) --Weapon Normal Position, you can adjust this Vec3() to put weapon in right position Script.ironSightActive = false Script.ironSightAimingSpeed = 0.7 --this is the speed of aiming, higer = slower, 0.7 is kind of fast but I think it is ok Script.cameraNormalFOV = 80 Script.cameraIronSightFOV = 60 function Script:Start() --Load weapon model then attach it to camera self.weapon = Model:Load("Models/ak47.mdl") self.weapon:SetParent(self.entity) self.weapon:SetRotation(0,0,0) end function Script:UpdateWorld() self:IronSightChecker() --Toggle ironSight when press right mouse button if window:MouseHit(Key.RButton) then self:IronSightToggle() end end function Script:IronSightToggle() if self.ironSightActive then self.ironSightActive = false --Disactivate iron sight mode else self.ironSightActive = true --Activate iron sight mode end end function Script:IronSightChecker() if self.ironSightActive then self:MoveWeapon(0,0,0,self.ironSightAimingSpeed) self:CameraZoom(self.cameraIronSightFOV,self.ironSightAimingSpeed) else self:MoveWeapon(self.norPos.x,self.norPos.y,self.norPos.z,self.ironSightAimingSpeed) self:CameraZoom(self.cameraNormalFOV,self.ironSightAimingSpeed) end end function Script:MoveWeapon(xPos,yPos,zPos,speed) local model = self.weapon local newXPos = Math:Lerp(xPos,model:GetPosition().x,speed) local newYPos = Math:Lerp(yPos,model:GetPosition().y,speed) local newZPos = Math:Lerp(zPos,model:GetPosition().z,speed) model:SetPosition(newXPos ,newYPos ,newZPos ) end function Script:CameraZoom(level,speed) local camzoom = Math:Lerp(level,self.entity:GetFOV(),speed) self.entity:SetFOV(camzoom) end
    Step 3: Check the resuilt
    it should look like this

    *Tip: You can use shadmar's viewport shader to fix the weapon clipping (http://steamcommunity.com/sharedfiles/filedetails/?id=256268930)
    Hope this help!
  7. tipforeveryone
    Visit forum topic here: http://www.leadwerks.com/werkspace/topic/15171-record-cameraobject-path-movement-script
    - Record camera path movement by controlling camera itself, what you see is what you get  - Path information can be saved to sperated file for later use - Attach saved path file to any entity to playback recorded path - Camera movement can be adjusted for smooth and better path record - Great for cut scene or object with motion. Demo
    What I did in this demo:
    - Record the first path and save it to path1.lua - Record the second path and save it to path2.lua - Create a small box then attach each of saved path files - Attach path1.lua to Pivot, attach path2.lua to box, watch their combination How to use
    - Download and extract 2 lua files to anywhere in your project folder, example: Scripts/Recorder - Create a Pivot in your map then attach PlayerControl-PrototypeB.lua  to it - Create a lua file then choose it as" Record File" in Script tab of the pivot (This is required!) - Run the game - Press R to start/stop record - Press P to playback recorded path - Press Esc to exit - Create an entity, ex: a box. Attach ObjectPathMovement.lua to it - Choose saved record file (This is required!) - Run the game - Press J to start playback recorded path for the entity Other attributes explaination
    PlayerControl-PrototypeB.lua - Playback Start: Execute playback process right after the game start, using data from choosen record fil
    - Clean Screen: Hide all HUD elements while playback
    - Both Playback Start and Clean Screen are good for cutscene camera
    - Focus Object: Drag any entity which you want camera to point at while moving, this will ignore recorded rotation of camera.
    - Play Rotation: if this is false, entity will ignore recorded rotation
  8. tipforeveryone
    In Leadwerks FPS game, if you want to do something like Leaning, HeadBobbing, ThirdPersonView, modifing default FPSCharacterController to fit these needs is a painful task. But it is much easier when you make your own Character Controller (CC) then alter it.
    This tutorial series will guide you to:
    Create a CC which can: Move, Look around from scratch. Implement advanced actions: Lean, Jump, Run, Crouch I. Create a basic CC

    Step 1: Understand CC's components
    PlayerBase (Blue): Control Player Movement (Forward, Backward, Strafe Left/Right and Jump) PlayerNeck (Yellow): Control Player Mouse Look function. PlayerEyes (White): Yes, it is just a camera, will be controlled by PlayerNeck (its parent) CameraLead (Pink): Where the camera is pointed at (this is useful for Leaning process in later part of this series) For your curiousity
    - What is PlayerNeck for ? Why don't just apply MouseLook on Camera ?
    In reallife, when you look up / down, your neck will be static, only head moves around and your eyes are attached to your head so that they move too. This will help you to see your feet model if need.
    - Why CameraLead ?
    In reallife, you can keep your head straight and move your eyes to look around, right? CameraLead solve that. This is useful for Leaning and HeadBobbing process too.
    Step 2: Setup CC's components
    In Leadwerks Editor, create a large platform by using Primitive Box > Rename to "Ground" Create another box(es) for obtacle test. Create a new Pivot > rename to "CharacterController", put it above "Ground" Create new script > rename to "CharacterControl.lua > Apply it to "CharacterController" Pivot
    Here is the code
    --Character components variables Script.playerWeight = 10 --Adjustable, not really important, this variable affects how player interact to other physical objects Script.playerHeight = 1.7 Script.neckLength = 0.2 Script.leadDistance = 10 --Character movement variables Script.playerSpeed = 2 --higer = faster --Character look variables Script.camerarotation = Vec3() Script.playerFOV = 70 --Default player field of view Script.lookUpLimit = -70 Script.lookDownLimit = 80 --Adjust lookUpLimit and lookDownLimit for your experiment function Script:Setup_Character_Components() --Create Player Base self.playerBase = self.entity self.playerBase:SetMass(1) self.playerBase:SetCollisionType(Collision.Character) self.playerBase:SetPhysicsMode(Entity.CharacterPhysics) --Create Player Neck self.playerNeck = Pivot:Create() --Do not make playerBase become playerNeck's parent, it will be a infinitive loop for Mouse Look self.playerNeck:SetPosition(--default position for playerNeck self.playerBase:GetPosition(true).x, self.playerBase:GetPosition(true).y + self.playerHeight - self.neckLength, self.playerBase:GetPosition(true).z) --Create Player Camera self.playerEyes = Camera:Create() self.playerEyes:SetParent(self.playerNeck) self.playerEyes:SetFOV(self.playerFOV) self.playerEyes:SetPosition(Vec3(0,self.neckLength,0)) --Create Camera Lead, remember, this is good for Leaning action self.cameraLead = Pivot:Create() self.cameraLead:SetParent(self.playerNeck) self.cameraLead:SetPosition(0,0,self.leadDistance) end function Script:Character_Look() local sx = Math:Round(context:GetWidth()/2) local sy = Math:Round(context:GetHeight()/2) local mouseposition = window:GetMousePosition() local dx = mouseposition.x - sx local dy = mouseposition.y - sy --Limit Look up / Look down angle, the fact is you can not look up 90 degrees most of time.. ehehe just kidding self.camerarotation.x = Math:Clamp(self.camerarotation.x + dy,self.lookUpLimit,self.lookDownLimit) self.camerarotation.y = self.camerarotation.y + dx --Smooth camera rotation local neckRot = self.playerNeck:GetRotation() self.camerarotation.x = Math:Curve(self.camerarotation.x,neckRot.x,10) self.camerarotation.y = Math:Curve(self.camerarotation.y,neckRot.y,10) self.playerNeck:SetRotation(self.camerarotation) window:SetMousePosition(sx,sy,0) end function Script:Character_Movement() local playerMove = ((window:KeyDown(Key.W) and 1 or 0) - (window:KeyDown(Key.S) and 1 or 0)) * self.playerSpeed local playerStrafe = ((window:KeyDown(Key.D)and 1 or 0) - (window:KeyDown(Key.A) and 1 or 0)) * self.playerSpeed local playerTurn = self.playerNeck:GetRotation(true).y self.playerBase:SetInput(playerTurn,playerMove,playerStrafe,0,false) end function Script:Bind_Character_Components_Together() local basePos = self.playerBase:GetPosition(true) --Must use this reposition process because playerBase is not playerNeck's parent, they are indipendent. self.playerNeck:SetPosition(basePos.x,basePos.y + self.playerHeight - self.neckLength,basePos.z) end function Script:Start() self:Setup_Character_Components() end function Script:UpdateWorld() self:Bind_Character_Components_Together() self:Character_Look() self:Character_Movement() end Step 3: Check it out ! Press F6 to start. Now you can move around by using AWSD, look around by using mouse and movement is blocked by an obtacle. So basic, so pure
    Next tutorial about Lean, Jump, Run, Crouch coming soon!
  • Create New...