How to resize / stretch World Space UI? - unity3d

I have some canvases with sliders and buttons with World Space render mode in my 3d game. Canvases attached to different game objects at different distances from each other.
How can I resize canvases depending on the zoom in or out of the Camera?
Importat! All canvases must do this at the same time.
For example: Canvas should shrink when Camera zoom in or stretch when zoom out.
For now I make it like this (but it seems to me there is a better way):
if (Vector3.Distance(_camera.transform.position, transform.position) < 70)
{
var scaleFactor = Vector3.Lerp(transform.localScale, new Vector3(0.5f, 0.5f, 0.5f), 0.01f);
transform.localScale = scaleFactor;
}
else
{
//Because default canvas scale is 1, 1, 1
var scaleFactor = Vector3.Lerp(transform.localScale, Vector3.one, 0.01f);
transform.localScale = scaleFactor;
}

Just asking, you can use canvas with overlay screen or overlay camera, it will always be on your screen with screen size no matter you zoom in or zoom out or you slide.
Or you can make a parent game object with two childrens in it. One children being the gameobject the canvas is attached to and another being the canvas and apply transform on the parent, It will also work for both the children I guess.

Related

How to copy one Rect Transform data to other Rect Transform

For my game UI requirements, I require to switch TvScreen in Normal and Maximal View/Size based on click of Toggle Button.
I have just tried to assign one Rect Transform to other Rect Transform but it is not working.
It just transferring reference data not actual component data like anchor point, pivot, position, scale and rotation.
I am attaching few images for TvScreen Rect Transform, Normal Screen Size Rect Transform and Maximum Screen Size Rect Transform.
Tv Screen With Its Rect Transform
Maximize Screen Size Rect Transform
Normal Screen Size Rect Transform
At present, I have done this but it is not visually changing Tv Screen size.
public void OnFullscreenMediaButtonClick()
{
SoundManager.Instance.PlayButtonClickSound();
Debug.Log("maximize button clicked: " + isTvScreenMaximized);
if (!isTvScreenMaximized)
{
isTvScreenMaximized = true;
tvScreen = maximizeScreenRectTransform;
}
else
{
isTvScreenMaximized = false;
tvScreen = normalSizeScreenRectTransform;
}
}
I hope you got my question so please give your suggestion related to this.
I notice the 2 RectTransform have different anchor preset. If it's not necessary, set them to the same anchor preset.
void CopyRectTransformSize(RectTransform copyFrom, RectTransform copyTo){
copyTo.anchorMin = copyFrom.anchorMin;
copyTo.anchorMax = copyFrom.anchorMax;
copyTo.anchoredPosition = copyFrom.anchoredPosition;
copyTo.sizeDelta = copyFrom.sizeDelta;
}
then call it like this to copy maximizeScreenRectTransform's size to tvScreen
CopyRectTransformSize(maximizeScreenRectTransform, tvScreen);

How can I use CGAffineTransform to skew a UIView in multiple directions, for example make one side larger than the other?

I know how to rotate a UIView and also scale it and translate x and y coordinates. But I don't know how to skew it as shown in the images below.
First image is a normal red rectangle with margins of size 20px from the sides. This is the unskewed view.
Here is the desired end result rectangle. I have drawn arrows to emphasize the direction of change. Its height is larger on the right side, and lower on the left side, and it is also moved slightly towards the right, so it looks like the rectangle is being pushed into the screen from the left side.
How can I achieve this transform?
You could create a rotation in the Y-axis and adjust the m34 for your perspective:
// Assuming that you have a CALayer. It can be your view's layer.
// In my example this was a 100x100 square layer
let boxLayer = CALayer()
var transform = CATransform3DIdentity
let angle = -CGFloat.pi / 8
transform.m34 = -1.0 / 500.0 // [500]: Smaller -> Closer to the 'camera', more distorted
transform = CATransform3DRotate(transform, angle, 0, 1, 0)
boxLayer.transform = transform
which results to this:

Unity: Having trouble in taking screenshot for the content inside scrollView

I am new in Unity. I'm trying to make a code that will take a screenshot of a object inside scrollview. My problem is that the whole object/image inside the scrollView is not visible in device.YOu have to pan the scrollView to see the hidden part.What I wanna do is to take the screenshot of the whole object/image inside the scrollview. Please help
My code below is
private IEnumerator TakeScreenshot()
{
yield return new WaitForEndOfFrame();
var width = Screen.width;
var height = Screen.height;
var tex = new Texture2D(width, height, TextureFormat.RGB24, false);
// Read screen contents into the texture
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
tex.Apply();
byte[] screenshot = tex.EncodeToPNG();
}
Code above only takes the screenshot that is visible to the device screen. I want to take the screenshot the whole object/image. Please help
Just point a camera with render texture setup towards your object and use the encode function.
Use of render texture and encodeToPng is recommended.
Your code simply creates a texture and reads the first pixel in it and doesn't do anything with it.

SpriteKit - Nodes not adding to SKCameraNode - Swift

Im trying to pin the game pad controller to the bottom left on my camera node but when i add the node as a child of my camera it doesnt show up?
let gameCamera = SKCameraNode()
var joypadBackground : SKSpriteNode = SKSpriteNode(imageNamed: "a")
override func didMove(to view: SKView) {
//Set game camera
self.camera = gameCamera
joypadBackground.position = convert(CGPoint(x: 0, y: 0), to: gameCamera)
joypadBackground.size = CGSize(width: 50, height: 50)
joypadBackground.zPosition = 1000
gameCamera.addChild(joypadBackground)
}
I had a hard time with this same problem the first time I was working with SKCameraNode and creating a heads up display.
Basically you have to remember that there are two parts to the camera. Running its functionality and rendering its children. By setting the scene's camera to gameCamera you've setup the functionality, but your camera isn't in the node tree for rendering. So, if you ever have a camera that needs to render its children don't forget to add it to the scene as a child, then the camera's children will be displayed.
self.camera = gameCamera
self.addChild(gameCamera)
Hope that helps someone avoid a very common error with a very simple solution.
You don't need
convert(CGPoint(x: 0, y: 0), to: gameCamera)
You can just set the CGPoint position to (0,0) and it should be at that point relative to the camera's space.
Not sure if this helps, at all, but what I do is (generally) position a child node AFTER I've added it to its parent. This is mainly a mental reminder, to me, that the child's position is within the coordinate space of the parent. So I'd do something like this:
gameCamera.addChild(joypadBackground)
joypadBackground.position = CGPoint(x: 0, y: 0)
If you're using a mid screen origin in your SKScene, this should be in the middle of the screen.
Bottom left will be a negative x and negative y value, size of which is relative to your frame size.

Gravity Keep Ball In Screen

I have a problem where I am spawning balls at the the of the screen and they fall at the standard speed. However, once they reach the bottom, they just fall right through and are removed. How do I make it so that they are kept in the screen?
If it helps, I have a function where I make the ball and set its properties. (similar to a class). Another function where I add the ball to the screen (add child) and make random coords. And a final function where I have the ball endlessly spawn at the top of the screen.
Thanks for your help!
You have to define an physics body edge and set it to the physicsBody of the scene.
let edgeFrame = CGRectMake(0, 0, size.width, size.height)
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: edgeFrame)