Thursday 14 April 2016

Unity - Top down Camera View



To this point i have become accustomed to the unity IDE, how to import assets in how to create a scene with a terrain/sky box/ simple objects.

The first challenge was making these objects interact and behave in certain ways inside the environment.

The first key thing to learn was how to apply certain components to a game object, which allows physics characteristics like "Rigidbody" to be added to a gameobject. In doing this, we can then set its box collider > material attribute as "Bouncy".

From here the next challenge was how to record & destroy what this cube bounced off of. In comes the need to learn to script.

Unity will allow you to work with JavaScript or with C# (there are more, but this is all myself and seemingly most other are concerned with). As i began learning some JS with my Aurellia/node attempt, i thought i would try to write all my beginner scripts in BOTH languages to see if i could get both working. (this is useful for when certain scripts are only available in 1 language, but you would rather convert it to another)

First i learned to display what objects were in contact, keep a count of how many a type of object was hit and then implementing the find and destroy method. Additionally, how to spawn a prefab object into the world given set time and how to apply a force in a particular direction upon a key press were integrated into this "game" -> the result was actually relatively fun!

I then built this to my android phone to see how it behaved. The result was not great, the keystrokes i had assigned (space) were not converted in the build, and there was no camera movement ability (part of me hoped this would be automatic)

So now challenge is to set my camera up to be a suitable view (RTS style, like mentioned in previous posts) and be responsive to touch gestures. This will also include some getting use to setting up events for touches.

So far I have tried building my own script for the camera. Realising do not yet know enough, i went to find some examples out there. So far from searching the unity forums, stackoverflow, youtube etc, i have found a number of scripts that seem relevant. Problem is: the ones that work, barely work in the right way, and the rest just plain don't work, Further understanding is needed before I can get these scripts working, and then learn enough from them to build my own.

It SEEMS the main problem i am having with my scripts not working is "nullReferenceException: Object reference not set to an instance of an object" in my update() with the common aspect being Camera is mentioned.

private Camera _camera;

void Start () {
//retrieveing pricate variables
_camera = Camera.main;
}

void Update () {
//checked if we want to Update zoom sensitivity
if (updateZoomSensitivity) {
//set move sensitiy x&y to orthographics size / 5 (arbitary number)
moveSensitivityX = _camera.orthographicSize / 5.0f;
moveSensitivityY = _camera.orthographicSize / 5.0f;
}

**or**

Camera cam;

void Awake()
{
cam = Camera.main;
}
void Update ()
{
if (Input.touchCount == 0) {
oldTouchPositions [0] = null;
oldTouchPositions [1] = null;
} else if (Input.touchCount == 1) {
if (oldTouchPositions [0] == null || oldTouchPositions [1] != null) {
oldTouchPositions [0] = Input.GetTouch (0).position;
oldTouchPositions [1] = null;
} else {
Vector2 newTouchPosition = Input.GetTouch (0).position;

cam.transform.position += cam.transform.TransformDirection ((Vector3)((oldTouchPositions [0] - newTouchPosition) * cam.GetComponent<Camera> ().orthographicSize / cam.GetComponent<Camera> ().pixelHeight * 2f));

oldTouchPositions [0] = newTouchPosition;
}
}
}



** Update** this was fixed by simply ensuring the camera object the script was attached to was the MainCamera.

The script i am currently using, which seems to give the best results with an orthographic view is:

using UnityEngine;
using System.Collections;

public class COCcam : MonoBehaviour {

public float moveSensitivityX = 1.0f;
public float moveSensitivityY = 1.0f;
public bool updateZoomSensitivity= true;
public float orthoZoomSpeed = 0.05f;

public float minZoom = 1.0f;
public float maxZoom = 20.0f;
public bool invertMoveX = false;
public bool invertMoveY = false;
private Camera _camera;

void Start () {
//retrieveing private variables
_camera = Camera.main;
}

void Update () {
//checked if we want to Update zoom sensitivity
if (updateZoomSensitivity) {
//set move sensitiy x&y to orthographics size / 5 (arbitary number)
moveSensitivityX = _camera.orthographicSize / 5.0f;
moveSensitivityY = _camera.orthographicSize / 5.0f;
}

//get touches that are on screen
Touch[] touches = Input.touches;

if (touches.Length > 0) {

//single touch(move)
if (touches.Length == 1) {

if (touches [0].phase == TouchPhase.Moved) {   //returns phase of current touch
//obtains delta pos of touch -> difference between touch position of the current/previous frame
Vector2 delta = Input.touches[0].deltaPosition;

//variables for position x / y
float positionX = delta.x * moveSensitivityX * Time.deltaTime;
//check if we are inverting, as per public bools.
//if invertmoveX is true then it will equal the same. IF not, it'll equal posX * -1, inverting it.
positionX = invertMoveX ? positionX : positionX * -1;
float positionY = delta.y * moveSensitivityY * Time.deltaTime;
positionY = invertMoveY ? positionY : positionY * -1;

//set camera's tranform position to = new vector 3 at position x, y, z
_camera.transform.position += new Vector3 (positionX, positionY, 0);
}
}

//double touch (zoom)
if (touches.Length == 2) {

Touch touchOne = touches [0];
Touch touchTwo = touches [1];

//to get the posiiton from the PREVIOUS touch in the previous frame.
//subtract touch pos from touch delta
Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;
Vector2 touchTwoPrevPos = touchTwo.position - touchTwo.deltaPosition;

//FIND MAGNITUDE OF PREVIOUS TOUCH VS CURRENT TOUCHES
float prevTouchDeltaMag = (touchOnePrevPos - touchTwoPrevPos).magnitude;
//now the current touch dleta magnitude
float touchDeltaMag = (touchOne.position - touchTwo.position).magnitude;
//difference between
float deltaMagDiff = prevTouchDeltaMag - touchDeltaMag;

//set cam's ortho size -> the delta mag * public variable at top.
_camera.orthographicSize += deltaMagDiff * orthoZoomSpeed;
//clamp values between min/max zoom defined at top.
_camera.orthographicSize = Mathf.Clamp(_camera.orthographicSize, minZoom, maxZoom);
}
}
} //close update
} //close class



(deeper tutorials into any of the above can follow if there is enough interest!)


No comments:

Post a Comment