Let’s Make a 4X Space Game with Unity – Part 8 Camera Control 2

Hi guys and welcome to part 8. In the last part we added a panning system so we could move the camera around with WASD. In this part we will talk about

  1. How we clamp that movement
  2. Add the ability to zoom the camera in and out using the mouse wheel.

1. How we Clamp Our Movement

Currently when we pan around our galaxy or solar system we can keep panning in any direction forever. This is bad because we could easily get lost. To solve this we need a way to clamp the camera so it stays in a defined area. But how do we do this?

In the CameraControl script add a new method called ClampCameraPan. Make it void and don’t pass it anything. We need to declare a Vector3 equal to the current position of the Pan Object. Call this position.

part008pic001
Setting Up ClampCameraPan

Now we need to clamp the X and Z values in position to our upper and lower limits. But what are these limits? Well in our galaxy view the upper limit will be our maximumRadius and the lower limit will be -maximumRadius. In our solar system view it will be the maximum solar system size which at the moment is 50 (The maximum planet count is 10 in my example code and the current distance between planets is set at 5). But how does the game know what view we are in?

Well at the moment there isn’t anything definitive which tells the game what view it is in. Let’s change that. Open up the Galaxy script and declare a public bool called galaxyView with get and set functions. In the CreateGalaxy method before we create the stars set galaxyView to true.

Part008pic002.JPG
Declaring galaxyView
Part008pic004.JPG
Setting galaxyView to True

Open the SolarSystem script and in the CreateSolarSystem method set galaxyView to false.

Part008pic003.JPG
Setting galaxyView to False.

Now we have a simple way the game can check it is in the galaxy view or not.

Back in the CameraController script add an if statement to our ClampCameraPan method. The condition will be if galaxyView is equal to true.

Part008pic005.JPG
If Statement in ClampCameraPan

Now we use the Mathf.Clamp to set the X and Z values in position. As this is if the galaxyView is true the clamp limits will be + and – the maximumRadius . 

Part008pic006.JPG
Galaxy View Clamping

Add an else statement and this time clamp the X and Z to -50 and 50 (if you had a different number of max planets to me change your number to 5 * the max number you chose).

Part008pic007.JPG
Solar System View Clamping

Finally set the position of the Pan Object to position.

Note: We have to set the X and Z numbers in position because Unity does not allow editing of the single elements of the transform.position directly.

Part008pic008.JPG
Setting Position

Call ClampCameraPan at the end of ChangePosition.

Part008pic009.JPG
Calling ClampCameraPan

Press play and move the camera around. It should now be clamped to the edges of our galaxy/solar systems. Exactly what we want!

2. Zooming In and Out

Before we start organizing how the camera zooms in and out lets sort out exactly where our camera objects will be in space at the start of the game. We will be editing the ResetCamera method to do this.

The Pan Object will start at (0,0,0) with no rotation. We already have this in our ResetCamera method so lets move down the hierarchy to the Rotation Object. This will be responsible for our camera rotation as we zoom in and out. We now need to make a decision on whether we start with the camera zoomed as far out as possible or zoomed in as far as possible. This will have an effect on the angle we start at.

Let’s start fully zoomed in. At the top of the CameraController class declare two new floats. Call them zoomedInAngle and zoomedOutAngle. Make them public so we can edit them in the inspector. Give zoomedInAngle a default value of 45 and zoomedOutAngle a default value of 90. Also add a float called zoomLevel and set it equal to 0 (don’t make this one public).

Part008pic010.JPG
Angles and zoomLevel

In ResetCamera we need to set zoomLevel back to 0 and then set the X rotation of the Rotation Object to zoomedInAngle.

Part008pic011.JPG
Changing Rotation

 

Now we need to position our Zoom Object. This will only ever move in Z and its Z position will always be negative due to the orientation of all the objects. Declare two new floats at the top of the class called maxZoom and minZoom. Make the default value for maxZoom 200 and the default for minZoom 20. 

part008pic012
minZoom and maxZoom

In the ResetCamera method set the Z position of the Zoom Object to negative minZoom.

Part008pic013.JPG
ResetCamera Complete

ResetCamera is now complete, the last thing we need to do before we start the zoom in and out is to set the Main Camera position and rotation to (0,0,0) in the inspector.

Part008pic014.JPG
Main Camera Position and Rotation

Press play and see how the new camera looks to you. Feel free to edit the minZoom and the zoomedInAngle if you don’t like them.

Right lets start zooming in and out. Add a new method to CameraController called ChangeZoom. Make it void and don’t pass it anything. The input name for the mouse wheel in Unity is “Mouse ScrollWheel” and like the ChangePosition method we only move the camera if the Mouse ScrollWheel input doesn’t equal zero.

Part008pic015.JPG
Only Move with an Input

There are two ways we could set this up. We could have it so that when the player pushes the mouse wheel forwards the camera zooms in. When they pull it backwards the camera zooms out. This would be my preference, however I know some people prefer the opposite way around and so we are going to add the ability to inverse the zoom. At the top of the Class declare a new public bool called inverseZoom and set it equal to false. Then back in ChangeZoom embed another if statement into our first one with an else after it. The If will have the condition inverseZoom is false.

In the if make zoomLevel equal to Mathf.Clamp01(zoomLevel – Input.GetAxis(“Mouse ScrollWheel”)) and in the else change the – to a +.

Part008pic016.JPG
Inverses

This treats our zoomLevel as a linear value between 0 and 1 where 0 is fully zoomed in and 1 is fully zoomed out.

After the else statement declare a new float called zoom. This will be the Z value in our Zoom Object position so we need to use Mathf.Lerp with the first value (a) –minZoom and the second (b) –maxZoom; The final value (t) will be our zoomLevel (remember the max and min zoom values should be negative because the Zoom Object’s Z position is always negative).

Now we simply set the Zoom Object’s local Z position to zoom (using Transform.localPosition) and call ChangeZoom in the Update method. Call it before the ChangePosition method. The reason we call this before changing the position will become clear in the next part.

Part008pic017.JPG
zoom and Setting Zoom Object’s position
Part008pic018.JPG
Calling ChangeZoom

Press play and try it out. Feel free to edit the public values in the inspector and don’t forget if you prefer you can inverse the zoom controls :). Notice though as you zoom out the speed of the camera panning does not remain constant.

I think this is a good time to stop so in the next part we will finish the camera controls by adding rotation to the camera as it zooms and fixing this issue of panning speed as we zoom in and out.

scripts_for_part_8 (zip file)

Part 9 Camera Controls 3

 

 

 

Advertisements

One thought on “Let’s Make a 4X Space Game with Unity – Part 8 Camera Control 2

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s