Maintain proportion of a sprite in Unity - unity3d

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

Related

Infinite Vertical Scrolling in Unity3D

While I try to use scrolling background vertically, the patches appear while scrolling vertically.
Can you explain me why? If the background is scrolling horizontally it works fine!
Maybe due to lighting problems.
Scroll Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Scrollscript : MonoBehaviour
{
private float scrollSpeed = 0.2f;
private Renderer rend;
private Vector2 offset;
// Start is called before the first frame update
void Start() {
rend = GetComponent<Renderer>();
}
// Update is called once per frame
void Update() {
offset = new Vector2(0, Time.time * scrollSpeed);
rend.material.mainTextureOffset = offset;
}
}
You need to create the image so that it fits with its copy on horizontal and vertical.
i.e looping of an image should be created so that when the image scrolls for second time, it is not noticed. This is something you need to solve in photoshop or some other photo editing software rather than unity.

Why can't I zoom my Unity2D Orthographic game?

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!

Orbiting target with camera and changing height

I want to be able to use joystick (left-right) to make the camera orbit around target. I have this handled with the code below:
using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;
public class OrbitCamera : MonoBehaviour {
public Transform target;
public float turnSpeed;
public float height;
public float distance;
private Vector3 offsetX;
void Start()
{
offsetX = new Vector3 (0, height, distance);
}
void LateUpdate()
{
offsetX = Quaternion.AngleAxis (CrossPlatformInputManager.GetAxis ("hOrbit") * turnSpeed, Vector3.down) * offsetX;
transform.position = target.position + offsetX;
transform.LookAt (target.position);
}
}
I need to extend this script so that the player can move camera also up and down using the same joystick. So what I want is the camera to be able to move around player in a shape of sphere, always looking at the player. Thanks in advance.
Use a boom camera
A boom camera is wonderfully easy to setup and has a range of convenient cinematic controls:
To set it up, you simply create a new game object which we'll call the dolly. You then simply parent the camera to the dolly and tidy up the positions and rotations:
Camera
Transform: 0,0,-distance
Rotation: 0,0,0
Dolly
Transform: 0,height,0
Rotation: 0,0,0
Why a boom camera is great
Rotate the dolly on x and y and you'll get the camera moving in a sphere. (Note that dragging the rotation gizmo in scene view doesn't show the effect properly because of axis alignment; edit the x/y rotation values in the inspector only).
That -distance z value is the zoom. Change the local position of the camera to zoom in/out.
Local rotating the camera gives interesting tilt/pan effects.
Making it work in your case
You'd attach the script to the dolly gameobject, then use the joystick input to rotate it on x/y:
using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;
public class OrbitCamera : MonoBehaviour {
// Height and distance are now set in the scene (by positioning the dolly and changing that camera z value).
public float turnSpeed;
private float horizontal;
private float vertical;
void LateUpdate()
{
// Update horizontal/ vertical angles:
horizontal += CrossPlatformInputManager.GetAxis ("hOrbit") * turnSpeed;
vertical += CrossPlatformInputManager.GetAxis ("vOrbit") * turnSpeed;
// Update the rotation:
transform.rotation = Quaternion.Euler(horizontal, vertical, 0f);
}
}

Find all objects between player and camera

I am using an orthographic projection for camera to follow a player. I would like to find all gameobjects between the player and the camera so I can change the opacity so they are partially transparent while blocking the camera's view. I read about raycasting, but it seems it would give only the first object between the player and camera. What approaches are there to accomplish this?
Just use Physics.RaycastAll like this:
public class CameraScript : MonoBehaviour
{
//Attach this script to the camera//
public GameObject player;
void Update()
{
float dist = Vector3.Distance(transform.Position, player.transform.position);
RaycastHit[] hits = hits = Physics.RaycastAll(transform.position,
transform.forward, 100.0F);
foreach (RaycastHit h in hits)
{
//Change the opacity of the of each object to semitransparent.
}
}
}

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.