Why can't I zoom my Unity2D Orthographic game? - unity3d

I've watched several videos and read posts that indicate I should be able to zoom the camera view during my game by changing the Size parameter for the MainCamera (Unity 2D game, orthographic projection). Doing so zooms the Scene View in and out, but nothing I change anywhere in the Inspector changes the Game view.
Can anyone advise? Thanks.

The orthographic size defines the viewing volume of the camera and it will only zoom on the elements rendered by it. It looks like you are trying to zoom on a Canvas, but UI elements are rendered on top of the whole scene.
In order to zoom in and out you can either:
set the Canvas Render Mode to World Space and then place it in front of the camera
use a script that lets you zoom in on a canvas, have a look here: Pinch zoom on UI
public class PinchZoom : MonoBehaviour
{
public Canvas canvas; // The canvas
public float zoomSpeed = 0.5f; // The rate of change of the canvas scale factor
void Update()
{
// If there are two touches on the device...
if (Input.touchCount == 2)
{
// Store both touches.
Touch touchZero = Input.GetTouch(0);
Touch touchOne = Input.GetTouch(1);
// Find the position in the previous frame of each touch.
Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition;
Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;
// Find the magnitude of the vector (the distance) between the touches in each frame.
float prevTouchDeltaMag = (touchZeroPrevPos - touchOnePrevPos).magnitude;
float touchDeltaMag = (touchZero.position - touchOne.position).magnitude;
// Find the difference in the distances between each frame.
float deltaMagnitudeDiff = prevTouchDeltaMag - touchDeltaMag;
// ... change the canvas size based on the change in distance between the touches.
canvas.scaleFactor -= deltaMagnitudeDiff * zoomSpeed;
// Make sure the canvas size never drops below 0.1
canvas.scaleFactor = Mathf.Max(canvas.scaleFactor, 0.1f);
}
}
}
I hope this will help you!

Related

Canvas rotating when I change it to worldSpace, Unity

I've got a canvas that changes from Overlay to worldSpace when an event occurs, but when it changes to Overlay from worldSpace, the rotation of the canvas is changed, which I don't want it to be.
Images:
As you can see in the order that the images are, it starts with no rotation in worldSpace, then the event occurs changes it to overlay and the rotation is now 140, after the event and I'm back in worldSpace, it is still 140 degrees.
I don't know what is wrong with this. Please help if you can
This happens because, internally, the Canvas is being transformed into camera space when set to Overlay. That's how it renders. Your solution would be to cache the transform before changing the Render Mode.
Something like this, given a component:
using UnityEngine;
[RequireComponent(typeof(Canvas))]
public class CanvasRenderModeSwitcher : MonoBehaviour
{
private Canvas canvas;
private Vector3 position;
private Vector3 scale;
private Quaternion rotation;
private void OnEnable()
{
canvas = GetComponent<Canvas>();
}
public void SetRenderMode(RenderMode renderMode)
{
if (renderMode == RenderMode.WorldSpace)
{
// Set the render mode before values are reset.
canvas.renderMode = renderMode;
// Restore the values.
transform.position = position;
transform.rotation = rotation;
transform.localScale = scale;
}
else
{
// Cache the values.
position = transform.position;
rotation = transform.rotation;
scale = transform.localScale;
// Set the render mode after values are cached.
canvas.renderMode = renderMode;
}
}
}

How can I stop getting mouse position of UI Elements in Unity2D?

I'm making a mobile game where there is a simple circle with a handle attached to it, it can be controlled and can be rotated with mouse position, I'm using below code for handle control.
public class Controller : MonoBehaviour
{
private float m_force = 0.04f;
// amount of force for the player (circle and handle both)
public GameObject firePoint; // It is the tip of the handle which will shoot bullets
public float senstivity = 1f;
// senstivity control
public void ControlSenstivity(float index)
{
senstivity = index;
}
void Update()
{
//Get the Screen positions of the object
Vector2 positionOnScreen = Camera.main.WorldToViewportPoint(transform.position) ;
//Get the Screen position of the mouse
Vector2 mouseOnScreen = Camera.main.ScreenToViewportPoint(Input.mousePosition) ;
//Get the angle between the two points
float angle = AngleBetweenTwoPoints(positionOnScreen, mouseOnScreen) ;
// it will control the rotation of player (circle and handle both)
transform.rotation = Quaternion.Euler(new Vector3(0f, 0f, angle) * senstivity);
}
float AngleBetweenTwoPoints(Vector3 a, Vector3 b)
{
return Mathf.Atan2(a.y - b.y, a.x - b.x) * Mathf.Rad2Deg ;
}
// Below function for adding force to the player (both the circle and the handle), this function I added for mobile input whenever the button is pressed
public void AddForce()
{
transform.Translate(-firePoint.transform.localPosition.x, 0, 0 * m_force);
}
}
In this mobile game the user can rotate the player by dragging on the screen and can move the player by exerting force in the opposite direction of fire point whenever the add force button is pressed but the problem is that whenever I press the button the player takes Input.mousePosition of that button position and get rotated towards the button, that's why it will always move in one direction that is opposite of button. I wanted to know what can I do to not get Input.mousePosition of button which is in the canvas and can originally get position only of camera space. Any response will be appreciated, Thanks in advance!
You can use EventSystem.IsPointerOverGameObject. This method will check if your pointer(mouse/joystick) is on any of the UI elements.
Add if condition before getting mouse position.
// This will ignore all UI game objects
if (!EventSystem.current.IsPointerOverGameObject())
{
//Get the Screen positions of the object
Vector2 positionOnScreen = Camera.main.WorldToViewportPoint(transform.position);
}

Maintain proportion of a sprite in Unity

I added a sprite with a PNG image to a 16:9 scene in Unity. When I view the scene on the iPad (4:3 aspect ratio) it appears distorted. How can I make the sprite maintain it's proportion?
The image on the iPad:
On the computer (in Unity):
Here are my settings.
I tried using this script for the camera but it didn't work it just enlarges the character and it was still distorted. (source):
using UnityEngine;
public class PixelPerfectCamera : MonoBehaviour {
public float pixelsToUnits = 100;
private Camera camera;
void Awake () {
camera = Camera.main;
}
void Update () {
camera.orthographicSize = Screen.height / pixelsToUnits / 2;
}
}
I am using the sprite in a 2D scene using Unity 5.
You can use preserve aspect option of the image.
You are using the sprite on a UI/Image which requires a rect transform component resulting it resize according to screen. Use sprite renderer on empty object.
One way to create this is using menu:
GameObject->2D Object->Sprite
Hope this helps

Get touch location on screen for perspective Camera

As the title of the question goes, I am trying to get the touch location on screen for perspective Camera.
Pretty much when I click a button my character has the ability to "teleport" or change it's location/transform to the same area of my finger with the Z axis hard coded.
Now I stress "Perspective Camera" because when the camera is Orthographic the following works fine.
if (canTeleport == true) {
if (Input.GetMouseButtonDown (0)) {
//fingerPos = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position);
// fingerPos = Camera.main.ScreenToWorldPoint(Input.mousePosition); //Desktop
// transform.position = fingerPos;
// Debug.Log (transform.position);
//Needed for Mouse
//fingerPos = Input.mousePosition;
//Needed for Finger
fingerPos = Input.GetTouch(0).position;
//Oth Camera
fingerPos.z = -36.1f;
fingerPos = Camera.main.ScreenToWorldPoint (fingerPos);
//Pers Camera
// Vector3 screenPosition= new Vector3(0,0,0);
//fingerPos = GetWorldPositionOnPlane(screenPosition, -36.1f);
fingerPos.z = -36.1f;
transform.position = fingerPos;
Debug.Log (transform.position);
canTeleport = false;
}
}
But when in perspective it does not, I understand 2D and 3D space is different but only thing that should matter is the Z axis and i'm hard codding the Z axis so im not sure why it does not work.
any help offered will be appreciated.
thank you.
Update
The circle area is where I touched and as you can see my sprite went to the location on the canvas not in the game world.

How to Display WebcamTexture as Full Screen on Android Portrait Mode?

I am trying to display full screen Webcamtexture on android Portrait mode.
but when i am building and testing it on my device its rotated and videoRotationAngle is 90
I am using RawImage as a texture. I have seen on some post that you have to rotate the transform and get the right angle. But the problem is that if I rotate RawImage UI it will no longer full screen view.
var camImage:UnityEngine.UI.RawImage;
var baseRotation:Quaternion;
var webcamTexture:WebCamTexture;
var rotation:UnityEngine.UI.Text;
function Start () {
webcamTexture = new WebCamTexture(Screen.width,Screen.height);
camImage.texture=webcamTexture;
camImage.material.mainTexture = webcamTexture;
webcamTexture.Play();
rotation.text= webcamTexture.videoRotationAngle.ToString(); // to check the angle
}
I know this is late reply but may help someone facing similar issues.
If you are using RawImage as a Texture, below code should help you achieve the rendering both in Potrait and Landscape mode.
Just ensure that you set "Aspect Mode" in "Aspect Ratio Fitter" of Raw Image to "Width Controls Height" or "Height Controls Width" (whichever is larger based on orientation)
Code Snippet
using UnityEngine;
using UnityEngine.UI;
using System.Linq;
using System.Collections;
public class DeviceCameraController : MonoBehaviour
{
public RawImage image;
public AspectRatioFitter imageFitter;
//set it to either FRONT or BACK
string myCamera = "BACK";
// Device cameras
WebCamDevice frontCameraDevice;
WebCamDevice backCameraDevice;
WebCamDevice activeCameraDevice;
WebCamTexture frontCameraTexture;
WebCamTexture backCameraTexture;
WebCamTexture activeCameraTexture;
// Image rotation
Vector3 rotationVector = new Vector3(0f, 0f, 0f);
// Image uvRect
Rect defaultRect = new Rect(0f, 0f, 1f, 1f);
Rect fixedRect = new Rect(0f, 1f, 1f, -1f);
// Image Parent's scale
Vector3 defaultScale = new Vector3(1f, 1f, 1f);
Vector3 fixedScale = new Vector3(-1f, 1f, 1f);
void Start()
{
// Check for device cameras
if (WebCamTexture.devices.Length == 0)
{
Debug.Log("No devices cameras found");
return;
}
// Get the device's cameras and create WebCamTextures with them
frontCameraDevice = WebCamTexture.devices.Last();
backCameraDevice = WebCamTexture.devices.First();
frontCameraTexture = new WebCamTexture(frontCameraDevice.name);
backCameraTexture = new WebCamTexture(backCameraDevice.name);
// Set camera filter modes for a smoother looking image
frontCameraTexture.filterMode = FilterMode.Trilinear;
backCameraTexture.filterMode = FilterMode.Trilinear;
// Set the camera to use by default
if (myCamera.Equals("FRONT"))
SetActiveCamera(frontCameraTexture);
else if (myCamera.Equals("BACK"))
SetActiveCamera(backCameraTexture);
else // default back
SetActiveCamera(backCameraTexture);
}
// Set the device camera to use and start it
public void SetActiveCamera(WebCamTexture cameraToUse)
{
if (activeCameraTexture != null)
{
activeCameraTexture.Stop();
}
activeCameraTexture = cameraToUse;
activeCameraDevice = WebCamTexture.devices.FirstOrDefault(device =>
device.name == cameraToUse.deviceName);
image.texture = activeCameraTexture;
image.material.mainTexture = activeCameraTexture;
activeCameraTexture.Play();
}
// Make adjustments to image every frame to be safe, since Unity isn't
// guaranteed to report correct data as soon as device camera is started
void Update()
{
// Skip making adjustment for incorrect camera data
if (activeCameraTexture.width < 100)
{
Debug.Log("Still waiting another frame for correct info...");
return;
}
// Rotate image to show correct orientation
rotationVector.z = -activeCameraTexture.videoRotationAngle;
image.rectTransform.localEulerAngles = rotationVector;
// Set AspectRatioFitter's ratio
float videoRatio =
(float)activeCameraTexture.width / (float)activeCameraTexture.height;
imageFitter.aspectRatio = videoRatio;
// Unflip if vertically flipped
image.uvRect =
activeCameraTexture.videoVerticallyMirrored ? fixedRect : defaultRect;
}
}
Let me know if you face any issue.
Well you have two options: you could either pick portrait or landscape and block screen rotation, or you could automatically rotate your object and stretch it according to the screen boundaries. See Screen.height and Screen.length for more info.
(mCamera.videoRotationAngle + 90) % 360 will rotate the texture properly, then assign a localScale that swaps the height and width of the texture to fix the size.
You need to flip and rotate it. If you something like CameraCaptureKit (https://www.assetstore.unity3d.com/en/#!/content/56673) you will see there is diffirent ways of achieving what you want. In CameraCaptureKit there is a customized RawImage component that essentailly fiddles with the UV coordinates of the RawImahge instead of roatting it. That way you can rotate the image 90 or 270 and flip it without worring if the phone is running in landscape mode or what ever.