I can't find how to constantly dynamically blend between 3 cameras (I call them middle, upper & lower) based on the rate and height of the hero, constantly.
When following the hero, the middle vCam is the main/base one, I'd like to proportionally blend through upper and lower vCams based on the height of the hero.
The player/hero can move rapidly between heights, so the blend should be weighted with eases. Which is a natural part of Cinemachine blends. And works. But it's like a switch, to me, at my current understanding of Cinemachine blends, rather than a constant dynamic blending based on height.
You may consider removing the upper and lower camera and do your own "Manual blending" with only the middle camera. Recently I've been using Cinemachine and I do something similar of what your desired result is.
Since I don't exactly know how do you want your camera to behave, I show you some of my manual blending I've done, explained:
//Camera Direction
//If I´m not in ground, and I've been on the air for a specific time
if (!onGround && timeSinceLastJump > cameraDelay)
{
//Moves the offset of the camera down to the maximum allowed y offset (In your case it would be where the lower camera is)
if (vcam.GetCinemachineComponent<CinemachineTransposer>().m_FollowOffset.y >= maxYOffset)
vcam.GetCinemachineComponent<CinemachineTransposer>().m_FollowOffset.y -= offsetYSensivity;
//It also zooms out up to a specified level
if (vcam.m_Lens.OrthographicSize < maxFOV)
vcam.m_Lens.OrthographicSize += camSensivity;
}
else
{
//Same but upwards
if (vcam.GetCinemachineComponent<CinemachineTransposer>().m_FollowOffset.y <= minYOffset)
vcam.GetCinemachineComponent<CinemachineTransposer>().m_FollowOffset.y += offsetYSensivity;
//Same but zooming in
if (vcam.m_Lens.OrthographicSize > minFOV)
vcam.m_Lens.OrthographicSize -= camSensivity;
}
This way you can use your player height in the conditions, at the cost of having to design well the camera logic.
Maybe this helps you in some way to do what you want.
From what I remember, you can define the blend style in the Cinemachine blend options. From the description, it seems that it is set to "Cut" when you probably want something similar to EaseIn/EaseOut. It even allows you to define your own custom blend between cameras if the default options do not work for you.
Take a look at the documentation for more details.
Related
I am making a side scrolling game.
What I want is that the layers distant view, middle distance view, near distance view zoom in and out at different ratios.
How do you do that?
You have to understand that if you're using an orthographic camera, the depth (i.e. transform.position.z) is used to decide which objects are rendered on top of others.
Any effect associated with perspective (i.e.: scaling) is lost.
So, in order to do what you want to do, a quick way is to group your objects based on distance (far, middle, near) and scale them accordingly via code (changing their transform.localScale X and Y values). Of course the objects on the far distance will change their localScale less than the middle, and the middle will change less than the near.
I'm working on a project, using unity 5.4.
In this projects blocks are stacked next to eachother.
However there appear some annoying weird lines. Also on android these
line occur more often than on PC.
For illustration purposes I added an image and video.
Please zoom in on the picture to see, the line I'm speaking of, clearly.
Could anyone please provide a solution to get red of this nuissance.
Thanks in advance.
Literature:
Block alignment code snippet:
for (int x = 0; x < xSize; x++)
for (int z = 0; z < zSize; z++)
{
Vector3 pos = new Vector3(x, -layerDepth, z);
InstantiateBlock(pos);
}
Video link: https://youtu.be/5wN1Wn51d_Y
You have object seams!
This occurs when there is a physical or perceived gap between objects.
There are multiple causes for this.
1. Floating Point Imprecision
This could be because you are setting the position of the cubes to int's but they have floating point dimensions. The symptom for this is usually no white seams when the camera is close to the objects, and then they gradually appear as you get further away due to floating point imprecision. More.
Most of these blocks appear to line up exactly, from most camera positions. But from the occasional unfortunate position, the exact value for A's position plus its vertex at (0.5,0.5,-0.5) might be slightly different to object B's position plus its vertex at (-0.5,0.5,-0.5) . The result is that Unity shows a tiny gap, within which you can see the shadowed side of cube A.
If you consider the following on paper 3 == 1/3 * 3 this is mathematically correct, however using floats, 1/3 == 0.333333... and subsequently 3 * 0.333333... == 0.999999... BINGO! random gap between objects!
So how to solve? Use floats to calculate the positions of your objects. new vector3(1,1,1); should be new vector3(1f,1f,1f); - for example. For further reading on this try this SOP.
2. Texture Wrap-mode
If you are using textures on your objects, try changing the Wrap-Mode of your texture from wrap to clamp, or try upping the texture padding.
3. Shadow Acne - (Lighting and Shadow artifacts)
This is the arbitrary patterns of pixels in shadow when they should really be lit or NOT lit.
To prevent shadow acne, a Bias value can be added to the distance in the shadow map to ensure that pixels on the borderline definitely pass the comparison as they should, or to ensure that while rendering into the shadow map. source.
In Unity... go to your light source and then increase the Shadow Type > shadow Bias I would suggest doubling the default value of 0.05 and then continue so until fixed. You don't want to crank this value to max because...
Do not set the Bias value too high, because areas around a shadow near the GameObject casting it are sometimes falsely illuminated. This results in a disconnected shadow, making the GameObject look as if it is flying above the ground.
Are you using different blocks that you put against eachother? Your problem sounds like the blocks are not completely against eachother which causes you to see the side of the next block (this explains the camera Y changing: you might see the side better from higher up). That side will have different lighting and appear as a different/lighter colour. To check if this is the problem, try overlapping them slightly manually in the editor and see if the problem still occurs.
Making the blocks kinematic solves that. The issue is the rigid bodies bumping up against one another.
I want to move a camera closer to an object in Unity, so that the zooming is linear. Take a look at the zooming in the Scene window in the Unity Editor. The camera isn't moving with a constant speed. The more zoomed in you are, the slower the camera moves. And I do want to move the camera, I don't want to change the FOV.
First off, yes do not use the FOV to do that, it would be a massive pain to control the movement. Being in low FOV, would mean you are focus on a tiny part and movement would be hard to control since one unit would be a large movement in small FOV. Also, a large FOV creates fish eye effect. So nope.
One way you could achieve this fast to slow effect is to use a distance to define the amount of movement
Let's consider you use the mouse wheel to zoom in and out, you listens to the value and create a movement based on that.
float movement = Input.GetAxis("Mouse ScrollWheel");
if(movement == 0)
{
return;
}
Transform camTr = Camera.main.transform;
float distance = Vector3.Distance(camTr.position, origin.position) + 1;
camTr.Translate(camTr.forward * distance * movement * Time.deltaTime * speed);
speed variable is meant to control how fast regardless of the distance. Distance gets a plus 1 so you can still move while real close to the origin.
The origin position needs to be defined, it could be based on a raycast going forward from the camera and hitting at y = 0. Just an idea. It could also be a focused object, that all depends on what you are doing.
The whole point here is that your camera will move faster if you are far from the focus point. Also, you may want to clamp the movement so that begin far away does not result in gigantic movement.
i propose you to use FOV (because player feel good)
1- use Transform.localPosition to change distance of camera to near or far - you should change z axis to changing distance of camera
2- use camera rendertotexture and in GUI change scale of it ( isn't good because need pro unity license and get allot of memory);
but can't know whats reason for you want forget changing FOV
One step of perspective projection of a point is the division by distance of that point. This means that the projected size of any object does not change linearly with its distance.
projectedSize = originalSize / distance
So if you want to approach an object in a way that its projected size grows linearly, you'll have to change your distance non-linearly.
We do this by also dividing the distance by some value f. The exact value of f depends on the stepSize and (I think) the FoV of your camera.
By using FixedUpdate() instead of Update() we make sure we have a constant stepSize which allows us to assume f as being constant as well.
void FixedUpdate()
{
newDistance = oldDistance / f;
}
For the definition of f you can use any value bigger than, but close to 1. For example f = 1.01f. This will approximate the desired behaviour quite well. If you want it to be perfectly linear, you'll have to dig deeper into the calculations behind perspective projection and calculate the exact value of f yourself: https://en.wikipedia.org/wiki/3D_projection#Perspective_projection
In my scene, the smileys(Quad with png image) are placed at Y:0 and the dots(Quad with tiling 3X3) are placed at Y: -0.25.
The shader I need to use for the smileys is Transparent-Diffuse as I am using a circle png image.
But the dots I use below are showing up above the smiley. Using any other shader like Diffuse solves the issue but the smiley becomes a square.
Screenshot:
If you need any more clarifications please dont hesitate to ask.
Edit:
I have attached the shader details of both the smiley and the dots from the inspector panel.
link: http://postimg.org/image/cvws1os7d/
Edit 2:
I have found that the issue should be with the MainCamera and especially with distance & "Field Of View".
I need to use "Perspective" as projection type and 140 as Field of View.
If I change the projection type to Orthographic the issue is completely fixed.
The below screenshots show how the distance and Field of View controls the appearance of the dots over the smiley.
Screenshot 1:
Y position: 8.48
Field of View: 30
link: http://postimg.org/image/s31tttrkp/
Screenshot 2:
Y position: 9.7
Field of View: 30
link: http://postimg.org/image/f71sq0y4b/
Screenshot 3:
Y position: 11.41
Field of View: 30
link: http://postimg.org/image/3uk4az3d3/
Screenshot 4:
Y position: 1
Field of View: 140
link: http://postimg.org/image/bul9zwg7z/
Can this be a clue?
Just a couple of info, on how transparency is typically implemented (not only by Unity).
Meanwhile opaque objects can be drawn in any order (even if sorting them in front-to-back order can eventually improve some GPU performances relying on an early z-cull). Which pixels are visible can be deduced using the depth value stored into the z-buffer.
You can't rely on z-buffer for transparency.
For rendering translucent objects a typical approach is to draw them after all opaque objects, and sorting them in back-to-front order (transparent objects more distant from the camera are drawn first).
Now the question is: how do you sort objects? with a perspective camera and meshes of a generic shape, the solution is not obvious.
For quad meshes oriented parallel to a ortographic camera view plane, the z order is implicitly correct (that's why it always works for you).
You can also notice that camera position influences the drawing order, because with perspective camera the order is calculated as distance between object position and camera.
So what can you do with Unity3d, in your specific use case scenario?
A couple of tricks:
Explicitly set the render queue of the material
Explicitly set the render order inside the shader (similar of the above, but equals to every object with the same shader)
Fake the depth using Offset into the shader (not that useful in your case but worth to be known)
hope this helps
EDIT
I didn't know that, the camera transparency sorting mode appears to be customizable. So this is another solution, maybe the best for your case if you want to use a perspective camera.
If you are using Sprite Renderer component to render the images, you have to change the rendering order with Sorting Layer and Order in Layer parameters instead of changing the Y position.
Sorting layers can be added by clicking the "default" and choosing "Add Sorting Layer..". The order of the layers is changed by dragging them into different order. With Order in Layer lower numbers are rendered first. This means that higher numbers will be drawn on top of lower ones.
I found this interesting interface(starts at 33 seconds http://vimeo.com/22946428 ), and would like to design something similar for my own apps. I'm particularly interested in the circular intensity gauge/knob control as on the attached image.
It has a very futuristic feel to it and should be fairly simple to implement using touchesMoved: gesture recognizer callback.
But in order to not-reinvent the wheel, are there any open source libraries that offer advanced UI capabilities, like the ones in the picture/video?
Update: Answer by Hubert demonstrates how to use single finger motion to rotate the dial. The second part of the puzzle is: how to fill the control with color?
I'm thinking of rotating a background color image, but a part of it has to be cut off or covered with something else to vary from an empty background to full. Maybe the cut out element (about 1 radian) may hide a set of fan-like segments that follow the finger and create an illusion of a continuously increasing or decreasing fill of the gauge. The 6 segments x,y would be continuously animating, positioning them in such a way as to cover only the required fraction of the control.
I dont think you will find that control exactly, but Here are a couple of links to working with and tutorials on rotary controls for iOS:
http://www.raywenderlich.com/9864/how-to-create-a-rotating-wheel-control-with-uikit
http://maniacdev.com/2012/02/tutorial-creating-a-one-figure-rotation-gesture-recognizer-for-a-rotary-knob-control-on-ios/
http://maniacdev.com/2011/12/open-source-libraries-for-easily-adding-rotary-knob-controls-in-your-ios-apps/
Here's an example of a circular progress view. Combined with a one finger rotary control, it creates a similar gauge to the one requested (simply overlay 2 controls on top of each other)
Then link the two controls with the rotation callback:
- (void) rotation: (CGFloat) angle
{
// calculate rotation angle
imageAngle += angle;
if (imageAngle > 360)
imageAngle -= 360;
else if (imageAngle < -360)
imageAngle += 360;
progress = imageAngle/360.0;
}
DACircularProgress view
+
OneFingerRotationGestrureRecognizer