| 04-08-2010, 05:46 PM | #1 |
I've been working on this Camera System where you adjust the camera's angle of attack, distance, and rotation by arrows/escape (esc changes between AOA and Distance). The Problem: It desync me all the time each time I test it on the multiplayer with a friend. It works in single player just fine. Can anyone help me with it, and try to keep it MPI as well. JASS:scope CameraSystem initializer Init //******************************************************** globals // CAMERA VALUES private constant integer ZoomMin = 300 // Minimum distance from unit private constant integer ZoomMax = 2300 // Maximum distance from unit //********************************************************************************************************************************** //********************************************************************************************************************************** private boolean array RightArrow private boolean array LeftArrow private boolean array UpArrow private boolean array DownArrow private boolean array Escape private real array Rotation private real array Zoom private real array AngleOfAttack private unit array ZUnit public boolean array CameraB endglobals // InitTrigger Condition - Checks if owning unit is TriggerPlayer and is HERO function InitTrigger_Cond takes nothing returns boolean return GetOwningPlayer(GetTriggerUnit()) == GetTriggerPlayer() and IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) endfunction // InitTrigger Actions - set the predefined values before the loop (Setting the default camera) function InitTrigger_Actions takes nothing returns nothing set ZUnit[GetPlayerId(GetTriggerPlayer())] = GetTriggerUnit() set Zoom[GetPlayerId(GetTriggerPlayer())] = 2000 set Rotation[GetPlayerId(GetTriggerPlayer())] = GetUnitFacing(ZUnit[GetPlayerId(GetTriggerPlayer())]) set AngleOfAttack[GetPlayerId(GetTriggerPlayer())] = -10 set Escape[GetPlayerId(GetTriggerPlayer())] = false set CameraB[GetPlayerId(GetTriggerPlayer())] = true endfunction // EscapeTrigger Actions function Escape_Actions takes nothing returns nothing if (Escape[GetPlayerId(GetTriggerPlayer())] == false) then set Escape[GetPlayerId(GetTriggerPlayer())] = true call DisplayTextToPlayer(GetTriggerPlayer(), 0, 0, "Angle of Attack") else set Escape[GetPlayerId(GetTriggerPlayer())] = false call DisplayTextToPlayer(GetTriggerPlayer(), 0, 0, "Zoom") endif endfunction // Actions - changes the value to true or false depending on player's action function RightPress_Actions takes nothing returns nothing set RightArrow[GetPlayerId(GetTriggerPlayer())] = true endfunction function LeftPress_Actions takes nothing returns nothing set LeftArrow[GetPlayerId(GetTriggerPlayer())] = true endfunction function UpPress_Actions takes nothing returns nothing set UpArrow[GetPlayerId(GetTriggerPlayer())] = true endfunction function DownPress_Actions takes nothing returns nothing set DownArrow[GetPlayerId(GetTriggerPlayer())] = true endfunction function RightRelease_Actions takes nothing returns nothing set RightArrow[GetPlayerId(GetTriggerPlayer())] = false endfunction function LeftRelease_Actions takes nothing returns nothing set LeftArrow[GetPlayerId(GetTriggerPlayer())] = false endfunction function UpRelease_Actions takes nothing returns nothing set UpArrow[GetPlayerId(GetTriggerPlayer())] = false endfunction function DownRelease_Actions takes nothing returns nothing set DownArrow[GetPlayerId(GetTriggerPlayer())] = false endfunction // Loop Actions - Loops and update the camera based on the previous actions function ApplyCam takes integer p returns nothing local real height = GetCameraField(CAMERA_FIELD_ZOFFSET) + GetLocationZ(GetUnitLoc(ZUnit[p])) - GetCameraTargetPositionZ() if (RightArrow[p] == true) then set Rotation[p] = Rotation[p]+10 endif if (LeftArrow[p] == true) then set Rotation[p] = Rotation[p]-10 endif if (UpArrow[p] == true) then if (Escape[p] == false) then set Zoom[p] = Zoom[p]-50 if (Zoom[p] < ZoomMin) then set Zoom[p] = Zoom[p]+50 endif elseif (Escape[p] == true) then set AngleOfAttack[p] = AngleOfAttack[p] - 5 if (AngleOfAttack[p] < -50) then set AngleOfAttack[p] = AngleOfAttack[p] + 5 endif endif endif if (DownArrow[p] == true) then if (Escape[p] == false) then set Zoom[p] = Zoom[p]+50 if (Zoom[p] > ZoomMax) then set Zoom[p] = Zoom[p]-50 endif elseif (Escape[p] == true) then set AngleOfAttack[p] = AngleOfAttack[p] + 5 if (AngleOfAttack[p] > 0) then set AngleOfAttack[p] = AngleOfAttack[p] - 5 endif endif endif if CameraB[p] == true then call SetCameraTargetController(ZUnit[p], 0, 0, true) call SetCameraField(CAMERA_FIELD_ROTATION, Rotation[p], 0.10) call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, Zoom[p], 0.10) call SetCameraField(CAMERA_FIELD_ZOFFSET, height, 0.10) call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, AngleOfAttack[p], 0.10) endif endfunction function Loop_Actions takes nothing returns nothing local integer p = GetPlayerId(GetLocalPlayer()) if ZUnit[p] != null then call ApplyCam(p) endif endfunction function Init takes nothing returns nothing local trigger InitTrigger = CreateTrigger() local trigger RightPressTrigger = CreateTrigger() local trigger LeftPressTrigger = CreateTrigger() local trigger UpPressTrigger = CreateTrigger() local trigger DownPressTrigger = CreateTrigger() local trigger RightReleaseTrigger = CreateTrigger() local trigger LeftReleaseTrigger = CreateTrigger() local trigger UpReleaseTrigger = CreateTrigger() local trigger DownReleaseTrigger = CreateTrigger() local trigger LoopTrigger = CreateTrigger() local trigger EscapeTrigger = CreateTrigger() local integer i = MinPlayers-1 loop exitwhen i > MaxPlayers-1 call TriggerRegisterPlayerUnitEvent(InitTrigger, Player(i), EVENT_PLAYER_UNIT_SELECTED, null) call TriggerRegisterPlayerEvent(RightPressTrigger, Player(i), EVENT_PLAYER_ARROW_RIGHT_DOWN) call TriggerRegisterPlayerEvent(LeftPressTrigger, Player(i), EVENT_PLAYER_ARROW_LEFT_DOWN) call TriggerRegisterPlayerEvent(UpPressTrigger, Player(i), EVENT_PLAYER_ARROW_UP_DOWN) call TriggerRegisterPlayerEvent(DownPressTrigger, Player(i), EVENT_PLAYER_ARROW_DOWN_DOWN) call TriggerRegisterPlayerEvent(RightReleaseTrigger, Player(i), EVENT_PLAYER_ARROW_RIGHT_UP) call TriggerRegisterPlayerEvent(LeftReleaseTrigger, Player(i), EVENT_PLAYER_ARROW_LEFT_UP) call TriggerRegisterPlayerEvent(UpReleaseTrigger, Player(i), EVENT_PLAYER_ARROW_UP_UP) call TriggerRegisterPlayerEvent(DownReleaseTrigger, Player(i), EVENT_PLAYER_ARROW_DOWN_UP) call TriggerRegisterPlayerEvent(EscapeTrigger, Player(i), EVENT_PLAYER_END_CINEMATIC) set i = i + 1 endloop // InitTrigger call TriggerAddCondition(InitTrigger, Filter(function InitTrigger_Cond)) call TriggerAddAction(InitTrigger, function InitTrigger_Actions) // Arrow Actions call TriggerAddAction(RightPressTrigger, function RightPress_Actions) call TriggerAddAction(LeftPressTrigger, function LeftPress_Actions) call TriggerAddAction(UpPressTrigger, function UpPress_Actions) call TriggerAddAction(DownPressTrigger, function DownPress_Actions) call TriggerAddAction(RightReleaseTrigger, function RightRelease_Actions) call TriggerAddAction(LeftReleaseTrigger, function LeftRelease_Actions) call TriggerAddAction(UpReleaseTrigger, function UpRelease_Actions) call TriggerAddAction(DownReleaseTrigger, function DownRelease_Actions) // LoopTrigger call TriggerRegisterTimerEvent(LoopTrigger, 0.10, true) call TriggerAddAction(LoopTrigger, function Loop_Actions) // EscapeTrigger call TriggerAddAction(EscapeTrigger, function Escape_Actions) endfunction endscope As for CameraB[] - It's in initialization trigger with initial false. I realize that my coding may seems messy but I have been working on this all day trying to fix this desync problem. It would be appreciated if you were able to provide some assistance. |
| 04-08-2010, 10:43 PM | #2 |
GetUnitLoc() creates a location, which you are creating locally (cause you are calling ApplyCam in a local player block. Instead, use a public constant location and move it to the position of the unit. This way you won't create the location locally. JASS:globals private location tempLoc = Location(0, 0) endglobals ... function ApplyCam takes integer p returns nothing local real height = GetCameraField(CAMERA_FIELD_ZOFFSET) - GetCameraTargetPositionZ() call MoveLocation(tempLoc, GetUnitX(ZUnit[p]), GetUnitY(ZUnit[p])) set height = height + GetLocationZ(tempLoc) if (RightArrow[p] == true) then ... Btw: Since you are keeping all the data for each camera local, you don't even have to use arrays for all of your variables. Edit: Like this: JASS:scope CameraSystem initializer Init //******************************************************** globals // CAMERA VALUES private constant integer ZoomMin = 300 // Minimum distance from unit private constant integer ZoomMax = 2300 // Maximum distance from unit //********************************************************************************************************************************** //********************************************************************************************************************************** // since we don't use arrays, we need to assign starting values so they are not uninitializer (causes a thread to terminate when reading uninitialized variables). // All these value are local (except ZUnit), so the values will be different for each player. Therefore, don't modify globals values/states based on these values. private boolean RightArrow = false private boolean LeftArrow = false private boolean UpArrow = false private boolean DownArrow = false private boolean Escape = false private real Rotation = 0 private real Zoom = 0 private real AngleOfAttack = 0 private unit array ZUnit // when dealing with handles we should work globally, since handles could be de-indexed at different times, causing desyncs. public boolean CameraB = false // we declare the strings globally so we can use them locally without desyncing the string table. private constant string TextAoA = "Angle of Attack" private constant string TextZoom = "Zoom" // again, a global location so we don't change handles locally private constant location tempLoc = Location(0, 0) endglobals // InitTrigger Condition - Checks if owning unit is TriggerPlayer and is HERO function InitTrigger_Cond takes nothing returns boolean return GetOwningPlayer(GetTriggerUnit()) == GetTriggerPlayer() and IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) endfunction // InitTrigger Actions - set the predefined values before the loop (Setting the default camera) function InitTrigger_Actions takes nothing returns nothing set ZUnit[GetPlayerId(GetTriggerPlayer())] = GetTriggerUnit() if GetLocalPlayer() == GetTriggerPlayer() then // local block set Zoom = 2000 set Rotation = GetUnitFacing(ZUnit[GetPlayerId(GetTriggerPlayer())]) set AngleOfAttack = -10 set Escape = false set CameraB = true endif endfunction // EscapeTrigger Actions function Escape_Actions takes nothing returns nothing if GetLocalPlayer() == GetTriggerPlayer() then if (Escape == false) then set Escape = true call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, TextAoA) else set Escape = false call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, TextZoom) endif endif endfunction // Actions - changes the value to true or false depending on player's action function RightPress_Actions takes nothing returns nothing if GetLocalPlayer() == GetTriggerPlayer() then set RightArrow = true endif endfunction function LeftPress_Actions takes nothing returns nothing if GetLocalPlayer() == GetTriggerPlayer() then set LeftArrow = true endif endfunction function UpPress_Actions takes nothing returns nothing if GetLocalPlayer() == GetTriggerPlayer() then set UpArrow = true endif endfunction function DownPress_Actions takes nothing returns nothing if GetLocalPlayer() == GetTriggerPlayer() then set DownArrow = true endif endfunction function RightRelease_Actions takes nothing returns nothing if GetLocalPlayer() == GetTriggerPlayer() then set RightArrow = false endif endfunction function LeftRelease_Actions takes nothing returns nothing if GetLocalPlayer() == GetTriggerPlayer() then set LeftArrow = false endif endfunction function UpRelease_Actions takes nothing returns nothing if GetLocalPlayer() == GetTriggerPlayer() then set UpArrow = false endif endfunction function DownRelease_Actions takes nothing returns nothing if GetLocalPlayer() == GetTriggerPlayer() then set DownArrow = false endif endfunction // Loop Actions - Loops and update the camera based on the previous actions function ApplyCam takes integer p returns nothing local real height = GetCameraField(CAMERA_FIELD_ZOFFSET) - GetCameraTargetPositionZ() call MoveLocation(tempLoc, GetUnitX(ZUnit[p]), GetUnitY(ZUnit[p])) set height = height + GetLocationZ(tempLoc) if (RightArrow == true) then set Rotation = Rotation+10 endif if (LeftArrow == true) then set Rotation = Rotation-10 endif if (UpArrow == true) then if (Escape == false) then set Zoom = Zoom-50 if (Zoom < ZoomMin) then set Zoom = Zoom+50 endif elseif (Escape == true) then set AngleOfAttack = AngleOfAttack - 5 if (AngleOfAttack < -50) then set AngleOfAttack = AngleOfAttack + 5 endif endif endif if (DownArrow == true) then if (Escape == false) then set Zoom = Zoom+50 if (Zoom > ZoomMax) then set Zoom = Zoom-50 endif elseif (Escape == true) then set AngleOfAttack = AngleOfAttack + 5 if (AngleOfAttack > 0) then set AngleOfAttack = AngleOfAttack - 5 endif endif endif if CameraB == true then call SetCameraTargetController(ZUnit[p], 0, 0, true) call SetCameraField(CAMERA_FIELD_ROTATION, Rotation, 0.10) call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, Zoom, 0.10) call SetCameraField(CAMERA_FIELD_ZOFFSET, height, 0.10) call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, AngleOfAttack, 0.10) endif endfunction function Loop_Actions takes nothing returns nothing local integer p = GetPlayerId(GetLocalPlayer()) if ZUnit[p] != null then call ApplyCam(p) endif endfunction function Init takes nothing returns nothing local trigger InitTrigger = CreateTrigger() local trigger RightPressTrigger = CreateTrigger() local trigger LeftPressTrigger = CreateTrigger() local trigger UpPressTrigger = CreateTrigger() local trigger DownPressTrigger = CreateTrigger() local trigger RightReleaseTrigger = CreateTrigger() local trigger LeftReleaseTrigger = CreateTrigger() local trigger UpReleaseTrigger = CreateTrigger() local trigger DownReleaseTrigger = CreateTrigger() local trigger LoopTrigger = CreateTrigger() local trigger EscapeTrigger = CreateTrigger() local integer i = MinPlayers-1 call BJDebugMsg("bah2") loop exitwhen i > MaxPlayers-1 call TriggerRegisterPlayerUnitEvent(InitTrigger, Player(i), EVENT_PLAYER_UNIT_SELECTED, null) call TriggerRegisterPlayerEvent(RightPressTrigger, Player(i), EVENT_PLAYER_ARROW_RIGHT_DOWN) call TriggerRegisterPlayerEvent(LeftPressTrigger, Player(i), EVENT_PLAYER_ARROW_LEFT_DOWN) call TriggerRegisterPlayerEvent(UpPressTrigger, Player(i), EVENT_PLAYER_ARROW_UP_DOWN) call TriggerRegisterPlayerEvent(DownPressTrigger, Player(i), EVENT_PLAYER_ARROW_DOWN_DOWN) call TriggerRegisterPlayerEvent(RightReleaseTrigger, Player(i), EVENT_PLAYER_ARROW_RIGHT_UP) call TriggerRegisterPlayerEvent(LeftReleaseTrigger, Player(i), EVENT_PLAYER_ARROW_LEFT_UP) call TriggerRegisterPlayerEvent(UpReleaseTrigger, Player(i), EVENT_PLAYER_ARROW_UP_UP) call TriggerRegisterPlayerEvent(DownReleaseTrigger, Player(i), EVENT_PLAYER_ARROW_DOWN_UP) call TriggerRegisterPlayerEvent(EscapeTrigger, Player(i), EVENT_PLAYER_END_CINEMATIC) set i = i + 1 endloop // InitTrigger call TriggerAddCondition(InitTrigger, Filter(function InitTrigger_Cond)) call TriggerAddAction(InitTrigger, function InitTrigger_Actions) // Arrow Actions call TriggerAddAction(RightPressTrigger, function RightPress_Actions) call TriggerAddAction(LeftPressTrigger, function LeftPress_Actions) call TriggerAddAction(UpPressTrigger, function UpPress_Actions) call TriggerAddAction(DownPressTrigger, function DownPress_Actions) call TriggerAddAction(RightReleaseTrigger, function RightRelease_Actions) call TriggerAddAction(LeftReleaseTrigger, function LeftRelease_Actions) call TriggerAddAction(UpReleaseTrigger, function UpRelease_Actions) call TriggerAddAction(DownReleaseTrigger, function DownRelease_Actions) // LoopTrigger call TriggerRegisterTimerEvent(LoopTrigger, 0.10, true) call TriggerAddAction(LoopTrigger, function Loop_Actions) // EscapeTrigger call TriggerAddAction(EscapeTrigger, function Escape_Actions) call BJDebugMsg("bah3") endfunction endscope This shouldn't cause any desyncs. |
