Vehicle template: /vehicle_unit_controller.lua — code sample - Stingray Lua API Reference

Vehicle template: /vehicle_unit_controller.lua — code sample

Code

-- require 'core/appkit/lua/class'
-- require 'core/appkit/lua/component_manager'
local Util = require 'core/appkit/lua/util'
require 'core/appkit/lua/input_mapper'

Project.VehicleUnitController = Appkit.class(Project.VehicleUnitController)
local VehicleUnitController = Project.VehicleUnitController

local Keyboard = stingray.Keyboard
local Pad1 = stingray.Pad1
local Vector3 = stingray.Vector3

VehicleUnitController.speed_param_name = "CODE_Speed"

-- Add component support.
VehicleUnitController.manager = VehicleUnitController.manager or Appkit.ComponentManager()

-- Audio

local function startup_sound_play(self)
    if not stingray.Wwise then return end

    local wwise_world = stingray.Wwise.wwise_world(self.world)
    stingray.WwiseWorld.trigger_event(wwise_world, "sfx_taxi_start", self.unit)
end

local function startup_sound_stop(self)
    if not stingray.Wwise then return end

    local wwise_world = stingray.Wwise.wwise_world(self.world)
    stingray.WwiseWorld.trigger_event(wwise_world, "sfx_taxi_stop", self.unit)
end

local function drive_sound_play(self)
    if not stingray.Wwise then return end

    local wwise_world = stingray.Wwise.wwise_world(self.world)
    stingray.WwiseWorld.trigger_event(wwise_world, "sfx_taxi_drive_start", self.unit)
end

local function drive_sound_stop(self)
    if not stingray.Wwise then return end

    local wwise_world = stingray.Wwise.wwise_world(self.world)
    stingray.WwiseWorld.trigger_event(wwise_world, "sfx_taxi_drive_stop", self.unit)
end

local function init_audio(self)
    if not stingray.Wwise then return end

    stingray.Wwise.load_bank("content/audio/default") -- temporarily necessary for autoload mode to work
    local wwise_world = stingray.Wwise.wwise_world(self.world)
    self.source_id = stingray.WwiseWorld.make_manual_source(wwise_world, self.unit)

    startup_sound_play(self)
end

local function update_audio(self, forward_speed, input)
    if not stingray.Wwise then return end

    if (input.accelerate > 0 or input.deccelerate > 0) and (self.was_accelerating == false and self.was_deccelerating == false) then
        drive_sound_play(self)
    elseif input.deccelerate + input.accelerate == 0 and (self.was_accelerating == true or self.was_deccelerating == true) then
        drive_sound_stop(self)
    end

    local wwise_world = stingray.Wwise.wwise_world(self.world)
    stingray.WwiseWorld.set_source_parameter(wwise_world, self.source_id, "CODE_Speed", forward_speed)
    stingray.WwiseWorld.set_source_parameter(wwise_world, self.source_id, "CODE_Steer", input.steer)
end

local function shutdown_audio(self)
    if not stingray.Wwise then return end

    if self.was_accelerating == true or self.was_deccelerating == true then
        drive_sound_stop(self)
    end

    startup_sound_stop(self)
    local wwise_world = stingray.Wwise.wwise_world(self.world)
    stingray.WwiseWorld.destroy_manual_source(wwise_world, self.source_id)
end

-- 

function VehicleUnitController:on_level_shutdown()
    shutdown_audio(self)
end

function VehicleUnitController:init(entity, level, vehicle, unit, hud_controls)
    self.entity = entity
    self.world = stingray.Unit.world(unit)
    self.vehicle = vehicle
    self.unit = unit
    self.in_reverse = false
    self.is_enabled = true
    self.hud_controls = hud_controls

    self.last_pos = stingray.Vector3Box(stingray.Unit.local_position(self.unit, 1))
    self.was_accelerating = false
    self.was_deccelerating = false

    init_audio(self)

    VehicleUnitController.manager:add_component(entity, self, level)
end

function VehicleUnitController:set_enabled(enabled)
    self.is_enabled = enabled
end

function VehicleUnitController:update(dt)
    if not self.is_enabled then return end

    local input = {accelerate = 0, deccelerate = 0, steer = 0, handbrake = 0}
    local vehicle = self.vehicle
    local forward_speed = stingray.Vehicle.forward_speed(vehicle)
    if Util.is_pc() then
        input.accelerate = Keyboard.button(Keyboard.button_id("w"))
        input.deccelerate = Keyboard.button(Keyboard.button_id("s"))
        input.steer = Keyboard.button(Keyboard.button_id("a")) - Keyboard.button(Keyboard.button_id("d"))
        input.sprint = Keyboard.button(Keyboard.button_id("left shift"))
        input.handbrake = Keyboard.button(Keyboard.button_id("space"))
    end
    if Pad1 and Pad1.active() then
        local stick = Vector3.normalize(Pad1.axis(Pad1.axis_id("left")))
        input.accelerate = (input.accelerate ~= 0) and input.accelerate or ((stick.y > 0) and stick.y or 0)
        input.deccelerate = (input.deccelerate ~= 0) and input.deccelerate or ((stick.y < 0) and -stick.y or 0)
        input.steer = (input.steer ~= 0) and input.steer or -stick.x
        input.sprint = (input.sprint == true) or Pad1.button(Pad1.button_id(Appkit.Util.plat(nil, "left_trigger", nil, "l1" ))) > 0
        input.handbrake = (input.handbrake ~= 0) and input.handbrake or Pad1.button(Pad1.button_id(Appkit.Util.plat(nil, "right_trigger", nil, "r1" )))
    end
    if self.hud_controls ~= nil and (Util.use_touch()) then 
        input.accelerate = 0
        input.deccelerate = 0

        local motion = Appkit.input_mapper:get_motion_input()

        if motion.move.y > 0 then input.accelerate = 1 end
        if motion.move.y < 0 then input.deccelerate = 1 end
        input.steer =  -motion.pan.x
        if input.steer < -1 then input.steer = -1 end
        if input.steer > 1 then input.steer = 1 end
        input.sprint = 0 -- no sprint control on mobile.
        input.handbrake = self.hud_controls:check_powerbrake()
    end

    if self.in_reverse then
        stingray.Vehicle.set_accelerator(vehicle, input.deccelerate)
        stingray.Vehicle.set_wheeled_brake(vehicle, input.accelerate)

        if forward_speed > -1.0 and input.accelerate > 0.0 then
            stingray.Vehicle.set_gear(vehicle, 1)
            self.in_reverse = false
        end
    else
        stingray.Vehicle.set_accelerator(vehicle, input.accelerate)
        stingray.Vehicle.set_wheeled_brake(vehicle, input.deccelerate)  

        if forward_speed <= 0.0 and input.deccelerate > 0.0 then
            stingray.Vehicle.set_gear(vehicle,-1)
            self.in_reverse = true
        end
    end

    stingray.Vehicle.set_wheeled_steer(vehicle, input.steer)
    stingray.Vehicle.set_wheeled_handbrake(vehicle, input.handbrake)

    -- update speed
    local pos = stingray.Unit.local_position(self.unit, 1)
    local last_pos = self.last_pos:unbox()
    local speed = Vector3.length(pos - last_pos) / dt
    self.last_pos = stingray.Vector3Box(pos)

    update_audio(self, forward_speed, input)
    self.was_accelerating = input.accelerate > 0
    self.was_deccelerating = input.deccelerate > 0

    --stingray.World.update_unit(world, vehicle)
end

return VehicleUnitController