forked from LeenkxTeam/LNXSDK
		
	ObiNoWanKenobi - FirstPersonController Changes
This commit is contained in:
		@ -1,87 +1,243 @@
 | 
			
		||||
package leenkx.trait;
 | 
			
		||||
 | 
			
		||||
import iron.Trait;
 | 
			
		||||
import iron.math.Vec4;
 | 
			
		||||
import iron.system.Input;
 | 
			
		||||
import iron.object.Object;
 | 
			
		||||
import iron.object.CameraObject;
 | 
			
		||||
import leenkx.trait.physics.PhysicsWorld;
 | 
			
		||||
import leenkx.trait.internal.CameraController;
 | 
			
		||||
import leenkx.trait.physics.RigidBody;
 | 
			
		||||
import kha.FastFloat;
 | 
			
		||||
 | 
			
		||||
class FirstPersonController extends CameraController {
 | 
			
		||||
class FirstPersonController extends Trait {
 | 
			
		||||
 | 
			
		||||
#if (!lnx_physics)
 | 
			
		||||
	public function new() { super(); }
 | 
			
		||||
#else
 | 
			
		||||
    #if (!lnx_physics)
 | 
			
		||||
    public function new() { super(); }
 | 
			
		||||
    #else
 | 
			
		||||
 | 
			
		||||
	var head: Object;
 | 
			
		||||
	static inline var rotationSpeed = 2.0;
 | 
			
		||||
    @prop public var rotationSpeed:Float = 0.15;
 | 
			
		||||
    @prop public var maxPitch:Float = 2.2;
 | 
			
		||||
    @prop public var minPitch:Float = 0.5;
 | 
			
		||||
    @prop public var enableJump:Bool = true;
 | 
			
		||||
    @prop public var jumpForce:Float = 22.0;
 | 
			
		||||
    @prop public var moveSpeed:Float = 500.0;
 | 
			
		||||
 | 
			
		||||
	public function new() {
 | 
			
		||||
		super();
 | 
			
		||||
    @prop public var forwardKey:String = "w";
 | 
			
		||||
    @prop public var backwardKey:String = "s";
 | 
			
		||||
    @prop public var leftKey:String = "a";
 | 
			
		||||
    @prop public var rightKey:String = "d";
 | 
			
		||||
    @prop public var jumpKey:String = "space";
 | 
			
		||||
 | 
			
		||||
		iron.Scene.active.notifyOnInit(init);
 | 
			
		||||
	}
 | 
			
		||||
    @prop public var allowAirJump:Bool = false;
 | 
			
		||||
 | 
			
		||||
	function init() {
 | 
			
		||||
		head = object.getChildOfType(CameraObject);
 | 
			
		||||
    @prop public var canRun:Bool = true;
 | 
			
		||||
    @prop public var runKey:String = "shift";
 | 
			
		||||
    @prop public var runSpeed:Float = 1000.0;
 | 
			
		||||
 | 
			
		||||
		PhysicsWorld.active.notifyOnPreUpdate(preUpdate);
 | 
			
		||||
		notifyOnUpdate(update);
 | 
			
		||||
		notifyOnRemove(removed);
 | 
			
		||||
	}
 | 
			
		||||
    // Sistema de estamina
 | 
			
		||||
    @prop public var stamina:Bool = false;
 | 
			
		||||
    @prop public var staminaBase:Float = 75.0;
 | 
			
		||||
    @prop public var staRecoverPerSec:Float = 5.0;
 | 
			
		||||
    @prop public var staDecreasePerSec:Float = 5.0;
 | 
			
		||||
    @prop public var staRecoverTime:Float = 2.0;
 | 
			
		||||
    @prop public var staDecreasePerJump:Float = 5.0;
 | 
			
		||||
    @prop public var enableFatigue:Bool = false;
 | 
			
		||||
    @prop public var fatigueSpeed:Float = 0.5;  // the reduction of movement when fatigue is activated... 
 | 
			
		||||
    @prop public var fatigueThreshold:Float = 30.0; // Tiempo corriendo sin parar para la activacion // Time running non-stop for activation...
 | 
			
		||||
    @prop public var fatRecoveryThreshold:Float = 7.5; // Tiempo sin correr/saltar para salir de fatiga // Time without running/jumping to get rid of fatigue...
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
	var xVec = Vec4.xAxis();
 | 
			
		||||
	var zVec = Vec4.zAxis();
 | 
			
		||||
	function preUpdate() {
 | 
			
		||||
		if (Input.occupied || !body.ready) return;
 | 
			
		||||
    // Var Privadas 
 | 
			
		||||
    var head:CameraObject;
 | 
			
		||||
    var pitch:Float = 0.0;
 | 
			
		||||
    var body:RigidBody;
 | 
			
		||||
 | 
			
		||||
		var mouse = Input.getMouse();
 | 
			
		||||
		var kb = Input.getKeyboard();
 | 
			
		||||
    var moveForward:Bool = false;
 | 
			
		||||
    var moveBackward:Bool = false;
 | 
			
		||||
    var moveLeft:Bool = false;
 | 
			
		||||
    var moveRight:Bool = false;
 | 
			
		||||
    var isRunning:Bool = false;
 | 
			
		||||
 | 
			
		||||
		if (mouse.started() && !mouse.locked) mouse.lock();
 | 
			
		||||
		else if (kb.started("escape") && mouse.locked) mouse.unlock();
 | 
			
		||||
    var canJump:Bool = true;
 | 
			
		||||
    var staminaValue:Float = 0.0;
 | 
			
		||||
    var timeSinceStop:Float = 0.0;
 | 
			
		||||
 | 
			
		||||
		if (mouse.locked || mouse.down()) {
 | 
			
		||||
			head.transform.rotate(xVec, -mouse.movementY / 250 * rotationSpeed);
 | 
			
		||||
			transform.rotate(zVec, -mouse.movementX / 250 * rotationSpeed);
 | 
			
		||||
			body.syncTransform();
 | 
			
		||||
    var fatigueTimer:Float = 0.0;
 | 
			
		||||
    var fatigueCooldown:Float = 0.0;
 | 
			
		||||
    var isFatigueActive:Bool = false;
 | 
			
		||||
 | 
			
		||||
    public function new() {
 | 
			
		||||
        super();
 | 
			
		||||
        iron.Scene.active.notifyOnInit(init);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function init() {
 | 
			
		||||
        body = object.getTrait(RigidBody);
 | 
			
		||||
        head = object.getChildOfType(CameraObject);
 | 
			
		||||
        PhysicsWorld.active.notifyOnPreUpdate(preUpdate);
 | 
			
		||||
        notifyOnUpdate(update);
 | 
			
		||||
        notifyOnRemove(removed);
 | 
			
		||||
        staminaValue = staminaBase;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function removed() {
 | 
			
		||||
        PhysicsWorld.active.removePreUpdate(preUpdate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var zVec = Vec4.zAxis();
 | 
			
		||||
 | 
			
		||||
    function preUpdate() {
 | 
			
		||||
        if (Input.occupied || body == null) return;
 | 
			
		||||
        var mouse = Input.getMouse();
 | 
			
		||||
        var kb = Input.getKeyboard();
 | 
			
		||||
 | 
			
		||||
        if (mouse.started() && !mouse.locked)
 | 
			
		||||
            mouse.lock();
 | 
			
		||||
        else if (kb.started("escape") && mouse.locked)
 | 
			
		||||
            mouse.unlock();
 | 
			
		||||
 | 
			
		||||
        if (mouse.locked || mouse.down()) {
 | 
			
		||||
            var deltaTime:Float = iron.system.Time.delta;
 | 
			
		||||
            object.transform.rotate(zVec, -mouse.movementX * rotationSpeed * deltaTime);
 | 
			
		||||
            var deltaPitch:Float = -(mouse.movementY * rotationSpeed * deltaTime);
 | 
			
		||||
            pitch += deltaPitch;
 | 
			
		||||
            pitch = Math.max(minPitch, Math.min(maxPitch, pitch));
 | 
			
		||||
            head.transform.setRotation(pitch, 0.0, 0.0);
 | 
			
		||||
            body.syncTransform();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var dir:Vec4 = new Vec4();
 | 
			
		||||
 | 
			
		||||
    function isFatigued():Bool {
 | 
			
		||||
        return enableFatigue && isFatigueActive;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function update() {
 | 
			
		||||
        if (body == null) return;
 | 
			
		||||
        var deltaTime:Float = iron.system.Time.delta;
 | 
			
		||||
        var kb = Input.getKeyboard();
 | 
			
		||||
 | 
			
		||||
        moveForward = kb.down(forwardKey);
 | 
			
		||||
        moveBackward = kb.down(backwardKey);
 | 
			
		||||
        moveLeft = kb.down(leftKey);
 | 
			
		||||
        moveRight = kb.down(rightKey);
 | 
			
		||||
        var isMoving = moveForward || moveBackward || moveLeft || moveRight;
 | 
			
		||||
 | 
			
		||||
        var isGrounded:Bool = false;
 | 
			
		||||
        #if lnx_physics
 | 
			
		||||
        var vel = body.getLinearVelocity();
 | 
			
		||||
        if (Math.abs(vel.z) < 0.1) {
 | 
			
		||||
            isGrounded = true;
 | 
			
		||||
        }
 | 
			
		||||
        #end
 | 
			
		||||
 | 
			
		||||
        // Dejo establecido el salto para tener en cuenta la (enableFatigue) si es que es false/true....
 | 
			
		||||
		if (isGrounded && !isFatigued()) {
 | 
			
		||||
		    canJump = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
        // Saltar con estamina
 | 
			
		||||
        if (enableJump && kb.started(jumpKey) && canJump) {
 | 
			
		||||
            var jumpPower = jumpForce;
 | 
			
		||||
            // Disminuir el salto al 50% si la (stamina) esta por debajo o en el 20%.
 | 
			
		||||
            if (stamina) {
 | 
			
		||||
                if (staminaValue <= 0) {
 | 
			
		||||
                    jumpPower = 0;
 | 
			
		||||
                } else if (staminaValue <= staminaBase * 0.2) {
 | 
			
		||||
                    jumpPower *= 0.5;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
	function removed() {
 | 
			
		||||
		PhysicsWorld.active.removePreUpdate(preUpdate);
 | 
			
		||||
	}
 | 
			
		||||
                staminaValue -= staDecreasePerJump;
 | 
			
		||||
                if (staminaValue < 0.0) staminaValue = 0.0;
 | 
			
		||||
                timeSinceStop = 0.0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
	var dir = new Vec4();
 | 
			
		||||
	function update() {
 | 
			
		||||
		if (!body.ready) return;
 | 
			
		||||
            if (jumpPower > 0) {
 | 
			
		||||
                body.applyImpulse(new Vec4(0, 0, jumpPower));
 | 
			
		||||
                if (!allowAirJump) canJump = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		if (jump) {
 | 
			
		||||
			body.applyImpulse(new Vec4(0, 0, 16));
 | 
			
		||||
			jump = false;
 | 
			
		||||
        // Control de estamina y correr
 | 
			
		||||
        if (canRun && kb.down(runKey) && isMoving) {
 | 
			
		||||
            if (stamina) {
 | 
			
		||||
                if (staminaValue > 0.0) {
 | 
			
		||||
                    isRunning = true;
 | 
			
		||||
                    staminaValue -= staDecreasePerSec * deltaTime;
 | 
			
		||||
                    if (staminaValue < 0.0) staminaValue = 0.0;
 | 
			
		||||
                } else {
 | 
			
		||||
                    isRunning = false;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                isRunning = true;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            isRunning = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // (temporizadores aparte)
 | 
			
		||||
        if (isRunning) {
 | 
			
		||||
            timeSinceStop = 0.0;
 | 
			
		||||
            fatigueTimer += deltaTime;
 | 
			
		||||
            fatigueCooldown = 0.0;
 | 
			
		||||
        } else {
 | 
			
		||||
            timeSinceStop += deltaTime;
 | 
			
		||||
            fatigueCooldown += deltaTime;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Evitar correr y saltar al estar fatigado...
 | 
			
		||||
        if (isFatigued()) {
 | 
			
		||||
   			 isRunning = false;
 | 
			
		||||
   			 canJump = false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Move
 | 
			
		||||
		dir.set(0, 0, 0);
 | 
			
		||||
		if (moveForward) dir.add(transform.look());
 | 
			
		||||
		if (moveBackward) dir.add(transform.look().mult(-1));
 | 
			
		||||
		if (moveLeft) dir.add(transform.right().mult(-1));
 | 
			
		||||
		if (moveRight) dir.add(transform.right());
 | 
			
		||||
        // Activar fatiga despues de correr continuamente durante cierto umbral
 | 
			
		||||
        if (enableFatigue && fatigueTimer >= fatigueThreshold) {
 | 
			
		||||
            isFatigueActive = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		// Push down
 | 
			
		||||
		var btvec = body.getLinearVelocity();
 | 
			
		||||
		body.setLinearVelocity(0.0, 0.0, btvec.z - 1.0);
 | 
			
		||||
        // Eliminar la fatiga despues de recuperarse
 | 
			
		||||
        if (enableFatigue && isFatigueActive && fatigueCooldown >= fatRecoveryThreshold) {
 | 
			
		||||
            isFatigueActive = false;
 | 
			
		||||
            fatigueTimer = 0.0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		if (moveForward || moveBackward || moveLeft || moveRight) {
 | 
			
		||||
			var dirN = dir.normalize();
 | 
			
		||||
			dirN.mult(6);
 | 
			
		||||
			body.activate();
 | 
			
		||||
			body.setLinearVelocity(dirN.x, dirN.y, btvec.z - 1.0);
 | 
			
		||||
		}
 | 
			
		||||
        // Recuperar estamina si no esta corriendo
 | 
			
		||||
        if (stamina && !isRunning && staminaValue < staminaBase && !isFatigued()) {
 | 
			
		||||
            if (timeSinceStop >= staRecoverTime) {
 | 
			
		||||
                staminaValue += staRecoverPerSec * deltaTime;
 | 
			
		||||
                if (staminaValue > staminaBase) staminaValue = staminaBase;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		// Keep vertical
 | 
			
		||||
		body.setAngularFactor(0, 0, 0);
 | 
			
		||||
		camera.buildMatrix();
 | 
			
		||||
	}
 | 
			
		||||
#end
 | 
			
		||||
        // Movimiento ejes (local)
 | 
			
		||||
        dir.set(0, 0, 0);
 | 
			
		||||
        if (moveForward) dir.add(object.transform.look());
 | 
			
		||||
        if (moveBackward) dir.add(object.transform.look().mult(-1));
 | 
			
		||||
        if (moveLeft) dir.add(object.transform.right().mult(-1));
 | 
			
		||||
        if (moveRight) dir.add(object.transform.right());
 | 
			
		||||
 | 
			
		||||
        var btvec = body.getLinearVelocity();
 | 
			
		||||
        body.setLinearVelocity(0.0, 0.0, btvec.z - 1.0);
 | 
			
		||||
 | 
			
		||||
        if (isMoving) {
 | 
			
		||||
            var dirN = dir.normalize();
 | 
			
		||||
            var baseSpeed = moveSpeed;
 | 
			
		||||
            if (isRunning && moveForward) {
 | 
			
		||||
                baseSpeed = runSpeed;
 | 
			
		||||
            }
 | 
			
		||||
            var currentSpeed = isFatigued() ? baseSpeed * fatigueSpeed : baseSpeed;
 | 
			
		||||
            dirN.mult(currentSpeed * deltaTime);
 | 
			
		||||
            body.activate();
 | 
			
		||||
            body.setLinearVelocity(dirN.x, dirN.y, btvec.z - 1.0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        body.setAngularFactor(0, 0, 0);
 | 
			
		||||
        head.buildMatrix();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #end
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Stamina and fatigue system.....
 | 
			
		||||
		Reference in New Issue
	
	Block a user