saw792
Is known to say things. That is all.
- Reaction score
- 280
I am currently making a first person camera system that allows control over the camera with the mouse using trackables. It only seems to be working for Player 1 though... I suspect the mouse movements that Player 2 does actually moves the camera for Player 1 as well. It's quite a complicated set of code (two libraries), but I would appreciate if you could have a look through.
I can't say it wasn't expected either, but it does lag a fair bit. Optimization suggestions are definitely worthwhile. I am only using gamecache temporarily until I can find a better system to store the trackable data. I don't normally attach to anything other than timers, so this has been interesting. Partial credits of the trackable API to Kattana, I heavily modified his basic idea.
TrackableAPI:FirstPerson:To enable the system for a player you call EnableFirstPersonForPlayer().
I plan to submit this as a system once (if) it works well in multiplayer.
Thanks
I can't say it wasn't expected either, but it does lag a fair bit. Optimization suggestions are definitely worthwhile. I am only using gamecache temporarily until I can find a better system to store the trackable data. I don't normally attach to anything other than timers, so this has been interesting. Partial credits of the trackable API to Kattana, I heavily modified his basic idea.
TrackableAPI:
JASS:
library TrackableAPI
globals
private gamecache trackstore = InitGameCache("trackcache.w3v")
trigger TrackTrigger = CreateTrigger() //Trigger that has its action set in FirstPerson library
endglobals
function H2I takes handle h returns integer
return h
return 0
endfunction
private function SetTrackableX takes trackable t, real x returns real //Takes a trackable and saves its X, then returns the trackable
call StoreReal(trackstore, I2S(H2I(t)), "x", x)
return x
endfunction
private function SetTrackableY takes trackable t, real y returns real //Saves the Y
call StoreReal(trackstore, I2S(H2I(t)), "y", y)
return y
endfunction
private function SetTrackableZ takes trackable t, real z returns real //Saves the Z
call StoreReal(trackstore, I2S(H2I(t)), "z", z)
return z
endfunction
function GetTrackableX takes trackable t returns real //Returns the saved X coordinate of the trackable
return GetStoredReal(trackstore, I2S(H2I(t)), "x")
endfunction
function GetTrackableY takes trackable t returns real //Returns the Y
return GetStoredReal(trackstore, I2S(H2I(t)), "y")
endfunction
function GetTrackableZ takes trackable t returns real //Returns the Z
return GetStoredReal(trackstore, I2S(H2I(t)), "z")
endfunction
function CreateTrackableZ takes string path, real x, real y, real z, real face returns trackable
local destructable d = CreateDestructableZ( 039;OTip039;, x, y, z, 0.00, 1, 0 )
local trackable tr = CreateTrackable( path, x, y, face ) //Creates a trackable on top of the destructible, letting us set the Z height
call RemoveDestructable( d )
call SetTrackableX(tr, x) //Saves the X
call SetTrackableY(tr, y) //Saves the Y
call SetTrackableZ(tr, z) //Saves the Z
call TriggerRegisterTrackableTrackEvent(TrackTrigger, tr) //Adds a track event to global trigger
set d = null
return tr
endfunction
endlibrary
JASS:
library FirstPerson initializer Init requires TrackableAPI
private keyword Track //Allows us to use uninitialised struct
globals
integer FPCount = 0
Track array data
unit array dummy
endglobals
struct Track
private real x
private real y
private real z = 0
private integer increment = 0
private trackable array tracks[4000]
private integer maxcount = 0
static method create takes nothing returns Track //Loops through a rectangle, adding trackables at different heights in a grid
local Track t = Track.allocate()
loop
set t.y = -3000
set t.x = -3000
set t.z = t.z + 50
exitwhen t.z >=300
loop
exitwhen t.x >= 3000
set t.tracks[t.increment] = CreateTrackableZ("units\\human\\Peasant\\Peasant.mdx", t.x, t.y, t.z, 0)
set t.increment = t.increment + 1
set t.x = t.x + 300
endloop
loop
exitwhen t.y >= 3000
set t.tracks[t.increment] = CreateTrackableZ("units\\human\\Peasant\\Peasant.mdx", t.x, t.y, t.z, 0)
set t.increment = t.increment + 1
set t.y = t.y + 300
endloop
loop
exitwhen t.x <= -3000
set t.tracks[t.increment] = CreateTrackableZ("units\\human\\Peasant\\Peasant.mdx", t.x, t.y, t.z, 0)
set t.increment = t.increment + 1
set t.x = t.x - 300
endloop
loop
exitwhen t.y <= -3000
set t.tracks[t.increment] = CreateTrackableZ("units\\human\\Peasant\\Peasant.mdx", t.x, t.y, t.z, 0)
set t.increment = t.increment + 1
set t.y = t.y - 300
endloop
endloop
set t.maxcount = t.increment
return t
endmethod
method IsTrackInStruct takes trackable t returns boolean //Checks if a trackable is in the instance of the struct (in the array)
set .increment = 0
loop
exitwhen GetTriggeringTrackable() == .tracks[.increment] or .increment == .maxcount
set .increment = .increment + 1
endloop
if .increment == .maxcount then
return false
endif
return true
endmethod
endstruct
function EnableFirstPersonForPlayer takes player p returns nothing //Function called to enable the system
set dummy[GetPlayerId(p)] = CreateUnit(p, 039;h000039;, 0, 0, 0)
set data[FPCount] = Track.create() //Creates a Track instance based on player ID (creates the trackables unique to the player)
set FPCount = FPCount + 1
call EnableTrigger(TrackTrigger) //Enables detecting trigger
call FogEnableOff()
call FogMaskEnableOff()
if GetLocalPlayer() == p then //Sets camera fields for the player
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 100.00, 0)
call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, -2.00, 0)
call SetCameraField(CAMERA_FIELD_ZOFFSET, 180.00, 0)
call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, 10, 0)
call SetCameraTargetController(dummy[GetPlayerId(p)], 0, 0, false)
endif
endfunction
private function GetTrackOwner takes trackable t returns player //Loops through each Track instance to find which player 'owns' the trackable
local integer i = 0
loop
exitwhen data<i>.IsTrackInStruct(t) == true
set i = i + 1
endloop
return Player(i)
endfunction
private function Actions takes nothing returns nothing
local player p = GetTrackOwner(GetTriggeringTrackable()) //The player that triggered the trackable
local real x = GetTrackableX(GetTriggeringTrackable())
local real y = GetTrackableY(GetTriggeringTrackable())
local real z = GetTrackableZ(GetTriggeringTrackable())
local real x2 = GetUnitX(dummy[GetPlayerId(p)])
local real y2 = GetUnitY(dummy[GetPlayerId(p)])
local real z2 = 180
local real dx = x - x2
local real dy = y - y2
local real d = SquareRoot(dx * dx + dy * dy)
local real dz = z - z2
local real a = Atan2BJ(dz, d) //Raises or lowers camera angle of attack depending on mouse location
local real a2 = Atan2BJ(dy, dx) //Moves camera left or right depending on mouse location
if GetLocalPlayer() == p then
call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, a, 1)
call SetCameraField(CAMERA_FIELD_ROTATION, a2, 0.5)
endif
set p = null
endfunction
private function Init takes nothing returns nothing
call DisableTrigger(TrackTrigger)
call TriggerAddAction(TrackTrigger, function Actions)
endfunction
endlibrary</i>
I plan to submit this as a system once (if) it works well in multiplayer.
Thanks