• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Trigger] Locking camera to unit when player presses arrow (selection system)

Status
Not open for further replies.
Level 11
Joined
Oct 9, 2015
Messages
721
So what I'm trying to acomplish is when an unit enter the x region, the camera will be panned to the center of region and locked to the middle unit in the region, in this case the horse in the middle.

Then I set a boolean to true and if the player presses the left or right key while said boolean is true then I want the camera to be locked to the unit to the sides. The problem is I'm not being able to acomplish what I want. It's working in a really wierd way and I could't figure out a solution by myself.

Thanks in advice, help is much appreciated!

Here's an video with example, however I can only make it work one time.

https://www.youtube.com/watch?v=gCV0c_V1csc

Here are the triggers I've made so far:

  • Trigger 1
    • Events
      • Unit - A unit enters Region X <gen>
    • Conditions
    • Actions
      • Set NoCamera = True (this is the boolean)
      • Set HorseMiddle = True (this is a check to see if the camera is in the middle horse)
      • Camera - Pan camera for Player 1 (Red) to (Position of Horse Middle) over 0.50 seconds
      • Camera - Lock camera target for Player 1 (Red) to Horse Middle, offset by (0.00, 0.00) using Default rotation
  • Trigger 2
    • Events
      • Player - Player 1 (Red) Presses the Left Arrow key
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • NoCamera Equal to True
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • HorseLeft Equal to False
              • HorseMiddle Equal to True
              • HorseRight Equal to False
            • Then - Actions
              • Set HorseLeft = True
              • Set HorseMiddle = False
              • Set HorseRight = True
              • Camera - Lock camera target for Player 1 (Red) to Horse Left, offset by (0.00, 0.00) using The unit's rotation
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • HorseLeft Equal to True
              • HorseMiddle Equal to False
              • HorseRight Equal to False
            • Then - Actions
              • Set HorseLeft = False
              • Set HorseMiddle = False
              • Set HorseRight = True
              • Camera - Lock camera target for Player 1 (Red) to Horse Right, offset by (0.00, 0.00) using The unit's rotation
            • Else - Actions
        • Else - Actions
 
How about I give a bit of a different approach?

Intuitively, if you press right -> you'll go to HorseRight. If you press right again, typically it'll jump over to HorseLeft. Press right again, it'll go to HorseMiddle, etc.

Same for pressing the left arrow. To allow this panning, we can index the horsies:
attachment.php


Indexing is just assigning each "member" a number. In this case, I assigned HorseLeft the value of 0, HorseMiddle the value of 1, and HorseRight the value of 2. What does this do? It allows us to use arrays--and this will simplify things big time.

First, create a boolean array HorseCamera to represent HorseLeft/Middle/Right:

HorseCamera[0] ==> HorseLeft
HorseCamera[1] ==> HorseMiddle
HorseCamera[2] ==> HorseRight

Next, create an integer variable "CurrentHorse". This will indicate which horse we are currently viewing.

Finally, create a unit array "Horses". Assign Horses[0] to equal "Horse Left", Horses[1] to equal "Horse Middle", and Horses[2] to equal "Horse Right".

  • Trigger 1
    • Events
      • Unit - A unit enters Region X <gen>
    • Conditions
    • Actions
      • Set NoCamera = True (this is the boolean)
      • Set Horses[0] = Horse Left (you can assign these wherever you want)
      • Set Horses[1] = Horse Middle
      • Set Horses[2] = Horse Right
      • Set HorseCamera[0] = False
      • Set HorseCamera[1] = True
      • Set HorseCamera[2] = False
      • Set CurrentHorse = 1
      • Camera - Pan camera for Player 1 (Red) to (Position of Horse Middle) over 0.50 seconds
      • Camera - Lock camera target for Player 1 (Red) to Horse Middle, offset by (0.00, 0.00) using Default rotation
So... how does this help us? Well, when a player presses the left arrow, we can just decrement CurrentHorse. If CurrentHorse is 0, we can just set it to 2. When the player presses the right arrow, we can just increment it. Again, if it is equal to 2, then we can just set it to wrap-around back to 0. The beauty is the simplicity:
  • Trigger 2
    • Events
      • Player - Player 1 (Red) presses the Left Arrow Key
    • Conditions
      • (NoCamera Equal to True)
    • Actions
      • If (All conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • CurrentHorse Equal to 0
        • Then - Actions
          • Set HorseCamera[0] = False
          • Set CurrentHorse = 2
        • Else - Actions
          • Set HorseCamera[CurrentHorse] = False
          • Set CurrentHorse = (CurrentHorse - 1)
      • Camera - Lock camera target for Player 1 (Red) to Horses[CurrentHorse], offset by (0.00, 0.00) using Default rotation
      • Set HorseCamera[CurrentHorse] = True
Similarly, we can make a trigger for the right arrow!
  • Trigger 3
    • Events
      • Player - Player 1 (Red) presses the Right Arrow Key
    • Conditions
      • (NoCamera Equal to True)
    • Actions
      • If (All conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • CurrentHorse Equal to 2
        • Then - Actions
          • Set HorseCamera[2] = False
          • Set CurrentHorse = 0
        • Else - Actions
          • Set HorseCamera[CurrentHorse] = False
          • Set CurrentHorse = (CurrentHorse + 1)
      • Camera - Lock camera target for Player 1 (Red) to Horses[CurrentHorse], offset by (0.00, 0.00) using Default rotation
      • Set HorseCamera[CurrentHorse] = True
In case you are still lost about the wrap around and the indexing. Just observe the following diagram. It models what should happen when we press the right arrow. Hopefully it'll clear things up. Feel free to ask questions if it is still unclear:
attachment.php
 

Attachments

  • Horses.png
    Horses.png
    12.4 KB · Views: 180
  • WrapAround.png
    WrapAround.png
    16.8 KB · Views: 184
Level 14
Joined
Nov 30, 2013
Messages
926
What is an multi-dimensional array, what does it do and how can I make it?

Thanks in advice for your aid!

Something like this.
Code:
set x[1][4] = (Last created unit)

Although that doesn't exists in the WE or JNGP, you can try this.
Code:
set x[(First Index * MaxAmount) + Second Index] = null

set x[(Player's Id * Total number of Cameras) + Camera's Index]

If you set the MaxAmount into 13 for example, you can set the Second Index between 0 and 12.

Also beware of the Array's limit.
 
Level 14
Joined
Nov 30, 2013
Messages
926
What are " * " ? I don't have any clue of how to set variables this way :(

" * " = Multiplication
" + " = Addition

What else could it be difficult? :csmile:

For example,

Code:
set x[(0 * 2) + 2] = x[2]

set x[(12 * 8) + 3] = x[99]

//If you do this
set x[(0 * 2) + 2) = x[2]
set x[(1 * 2) + 0) = x[2] // It will messed it up.

You can do this in Arithmetics way.
If you're still confused at this, let me know.
 
As bear mentioned, we can add a "player dimension" to all of our variables:

  • CurrentHorse -> Make this an integer array. We will index it like so: CurrentHorse[Player number of <Player>]
  • HorseCamera -> Our current implementation has 3 slots (0, 1, and 2) used for one player. If we extend this to multiplayer, we'll want to have 3 slots per player. It will look something like:
    • HorseCamera[((Player number of <Player>) x 3) + 0]
    • HorseCamera[((Player number of <Player>) x 3) + 1]
    • HorseCamera[((Player number of <Player>) x 3) + 2]
    Notice that the only thing that is changing is the offset (+ 0), (+ 1), and (+ 2).
  • Horses -> This can stay the way it is since we are using the same three horses for all players. However, if you wanted different horses for different players, you would have to update it in similar fashion.

Using the information above, let's try to squeeze this into our triggers. For simplicity, I've created an integer variable named "PlayerIndex" that will make things look nicer:
  • Trigger 1
    • Events
      • Unit - A unit enters Region X <gen>
    • Conditions
    • Actions
      • Set NoCamera = True (this is the boolean)
      • Set Horses[0] = Horse Left (you can assign these wherever you want)
      • Set Horses[1] = Horse Middle
      • Set Horses[2] = Horse Right
      • Set PlayerIndex = (Player number of (Owner of (Triggering unit)) x 3)
      • Set HorseCamera[PlayerIndex + 0] = False
      • Set HorseCamera[PlayerIndex + 1] = True
      • Set HorseCamera[PlayerIndex + 2] = False
      • Set CurrentHorse = 1
      • Camera - Pan camera for (Owner of (Triggering unit)) to (Position of Horse Middle) over 0.50 seconds
      • Camera - Lock camera target for (Owner of (Triggering unit)) to Horse Middle, offset by (0.00, 0.00) using Default rotation
  • Trigger 2
    • Events
      • Player - Player 1 (Red) presses the Left Arrow Key
      • Player - Player 2 (Blue) presses the Left Arrow Key
      • Player - Player 3 (Teal) presses the Left Arrow Key
      • ... repeat for all players in your map ...
    • Conditions
      • (NoCamera Equal to True)
    • Actions
      • Set PlayerNumber = (Player number of (Triggering player))
      • Set PlayerIndex = (PlayerNumber x 3)
      • If (All conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • CurrentHorse[PlayerNumber] Equal to 0
        • Then - Actions
          • Set HorseCamera[PlayerIndex + 0] = False
          • Set CurrentHorse[PlayerNumber] = 2
        • Else - Actions
          • Set HorseCamera[PlayerIndex + CurrentHorse[PlayerNumber]] = False
          • Set CurrentHorse[PlayerNumber] = (CurrentHorse[PlayerNumber] - 1)
      • Camera - Lock camera target for (Triggering player) to Horses[CurrentHorse[PlayerNumber]], offset by (0.00, 0.00) using Default rotation
      • Set HorseCamera[PlayerIndex + CurrentHorse[PlayerNumber]] = True
  • Trigger 3
    • Events
      • Player - Player 1 (Red) presses the Left Arrow Key
      • Player - Player 2 (Blue) presses the Left Arrow Key
      • Player - Player 3 (Teal) presses the Left Arrow Key
      • ... repeat for all players in your map ...
    • Conditions
      • (NoCamera Equal to True)
    • Actions
      • Set PlayerNumber = (Player number of (Triggering player))
      • Set PlayerIndex = (PlayerNumber x 3)
      • If (All conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • CurrentHorse[PlayerNumber] Equal to 2
        • Then - Actions
          • Set HorseCamera[PlayerIndex + 2] = False
          • Set CurrentHorse[PlayerNumber] = 0
        • Else - Actions
          • Set HorseCamera[PlayerIndex + CurrentHorse[PlayerNumber]] = False
          • Set CurrentHorse[PlayerNumber] = (CurrentHorse[PlayerNumber] + 1)
      • Camera - Lock camera target for (Triggering player) to Horses[CurrentHorse[PlayerNumber]], offset by (0.00, 0.00) using Default rotation
      • Set HorseCamera[PlayerIndex + CurrentHorse[PlayerNumber]] = True
It is still kinda ugly. But it gets the job done. I might've made some errors as I was writing it up--let me know if there are any issues.
 
Level 11
Joined
Oct 9, 2015
Messages
721
I've fixed it by seting Player Number for owner of triggering unit then set Current Horse[Player Number]

It's working really fine, I still didn't tested it um multiplayer however I think this is it. I had a question, how can I make it to be usable by two different teams? I mean the other team will have it's own three horses inside their own base. That means it would be another three different horses from the ones used by the first team and in different places.
 
Level 14
Joined
Nov 30, 2013
Messages
926
You can do something like this I guess.
  • Set Horse[(0 * 3) + 0] = Horse Left (Team 1)
  • Set Horse[(0 * 3) + 1] = Horse Mid (Team 1)
  • Set Horse[(0 * 3) + 2] = Horse Right (Team 1)
  • Set Horse[(1 * 3) + 0] = Horse Left (Team 2)
  • Set Horse[(1 * 3) + 1] = Horse Mid (Team 2)
  • Set Horse[(1 * 3) + 2] = Horse Right (Team 2)
Which is formatted like this
  • Set Horse[Player's Team * Number of Cameras + Chosen Camera]
 
Level 11
Joined
Oct 9, 2015
Messages
721
Something like this?

  • Set Horses[((0 x 3) + 0)] = Riderless Horse 0043 <gen>
that menas the left horse for the first team (team 0) ?

EDIT: How can I fit it in the other triggers? the camera for the second team is showing the horses from the first :(

PS: Thanks for all advices and for your precious time!
 
Level 14
Joined
Nov 30, 2013
Messages
926
EDIT: How can I fit it in the other triggers? the camera for the second team is showing the horses from the first :(

You must identify which Triggering Player's team is.
Example, if it triggered by Player 1, which is belong to Team 1, then
  • Set PlayerTeam = 0 -> Set Zero if the Triggering Player is belong to Team 1 or One if belong to Team 2
  • Camera - Lock camera target for (Triggering player) to Horses[(PlayerTeam * 3) + CurrentHorse[PlayerNumber]], offset by (0.00, 0.00) using Default rotation
Try it. I haven't really much tested that one. :l
 
Last edited:
Level 11
Joined
Oct 9, 2015
Messages
721
It worked really nicely! Thanks a lot for all the advices! I have one last question: how can I pan the camera to the horses instead of locking? because the "lock" function looks really robotic as it changes the camera instantly.

Thanks a lot in advice!

PS: The system is working fine, I thing this is it, the "pan" function can be considered optional!
 
Status
Not open for further replies.
Top