- Home /
Map level selection slide smoothly
Hello everyone. I want to do with my map levels selection slide smoothly after dragging the mouse or finger on the screen. I have this code but it doesn't work the way I want to, so he's shutting down without sliding smoothly after sliding the finger on the screen of the phone.
Explaining best: what I want to do is that the camera continues to slide smoothly after the drag of the mouse. Similar to map levels selection Candy Crush. This code I have not continued to slide after the lifting of the mouse or touch, the camera immediately. The code below is added to the camera
private Vector2 _prevPosition;
private Transform _transform;
public Camera Camera;
public Bounds Bounds;
public void Awake()
{
_transform = transform;
}
public void OnDrawGizmos()
{
Gizmos.DrawWireCube(Bounds.center, Bounds.size);
}
public void Update()
{
#if (UNITY_ANDROID || UNITY_IPHONE) && !UNITY_EDITOR
HandleTouchInput();
#else
HandleMouseInput();
#endif
}
private void HandleTouchInput()
{
if(Input.touchCount == 1)
{
Touch touch = Input.GetTouch(0);
if(touch.phase == TouchPhase.Began)
{
_prevPosition = touch.position;
}
else if(touch.phase == TouchPhase.Moved)
{
Vector2 curPosition = touch.position;
MoveCamera(_prevPosition, curPosition);
_prevPosition = curPosition;
}
}
}
private void HandleMouseInput()
{
if (Input.GetMouseButtonDown(0))
_prevPosition = Input.mousePosition;
if (Input.GetMouseButton(0))
{
Vector2 curMousePosition = Input.mousePosition;
MoveCamera(_prevPosition, curMousePosition);
_prevPosition = curMousePosition;
}
}
private void MoveCamera(Vector2 prevPosition, Vector2 curPosition)
{
if(EventSystem.current.IsPointerOverGameObject(-1)) return;
SetPosition(
transform.localPosition +
(Camera.ScreenToWorldPoint(prevPosition) - Camera.ScreenToWorldPoint(curPosition)));
}
public void SetPosition(Vector2 position)
{
Vector2 validatedPosition = ApplyBounds(position);
_transform.position = new Vector3(validatedPosition.x, validatedPosition.y, _transform.position.z);
}
private Vector2 ApplyBounds(Vector2 position)
{
float cameraHeight = Camera.orthographicSize*2f;
float cameraWidth = (Screen.width * 1f/Screen.height)*cameraHeight;
position.x = Mathf.Max(position.x, Bounds.min.x + cameraWidth/2f);
position.y = Mathf.Max(position.y, Bounds.min.y + cameraHeight/2f);
position.x = Mathf.Min(position.x, Bounds.max.x - cameraWidth/2f);
position.y = Mathf.Min(position.y, Bounds.max.y - cameraHeight/2f);
return position;
}
A screenshot would really help, as well as more code maybe? Because while it's clear what you're trying to do in this code, I can't tell what the context is.
$$anonymous$$y only comments on the code you posted is to ask what you think Bounds.max and Bounds.$$anonymous$$ is supposed to be?
I edited my post explaining better what I want to do and posted the full code also
Answer by Eudaimonium · Mar 28, 2016 at 07:54 PM
You can use ScrollRect on the container of your level selection objects, it will do what you want automatically:
Although making a gigantic scrollbar seems inelegant, it's probably the simplest way to do what OP wants yea.
With this control, the buttons in the levels do not work because of the ' Image ' script added to the ScrollView. I click on the levels and nothing happens
So remove the Image componenet.....
Did you read the ScrollRect documentation he linked? It has no Image component or requirement for an Image component. The "Content" parameter can be an image, but can also be anything like a Rect Transform.
When I add the ScrollView control on my Canvas, a component Image (Script) is also added to my object ScrollView. This component der image that makes buttons work, and if I delete this component, the scroll does not work also.
Answer by murkantilism · Mar 28, 2016 at 04:20 PM
Clarify what isn't working, this doesn't make any sense:
I have this code but it doesn't work the way I want to, so he's shutting down without sliding smoothly
The first issue I can see is that doubling the camera size does not give you it's height:
float cameraHeight = Camera.orthographicSize*2f;
And you later divide this value by 2f in the ApplyBounds() function, so why are you even doubling it in the first place?
and this line is redundant:
float cameraWidth = (Screen.width * 1f / Screen.height) *cameraHeight;
Basic math: (w * 1/h) *h will always give you back w, just do Screen.width
I'd start with cleaning out these basic errors in math/logic, then come back to explain what the problem you're seeing is.
Sorry, you're wrong here. Screen.width and Screen.height give pixel values for the window, while Camera.orthographicSize gives half the height of the viewing area in units. His code makes complete sense.
His code makes complete sense.
Not when he's doubling the ortho height and then halving it in almost every usage of the variable. The only place is doesn't halve it is in the width calculation, why not just double it there?
Sure, I could arbitrarily multiply variables and divide by the same amount later when I use them, and that's not "wrong" but it's redundant to do so.
This blog shows a good way of accounting for the aspect ratio, which is what I think OP is attempting to do. Notice how this guy doesn't arbitrarily double and halve his variables.
@dail as an aside from all this, have you considered simply your camera left/right ins$$anonymous$$d of the canvas elements? Could be a simpler approach to level select sliding.
The code that I edited is now complete and is added to the camera, thereby is the camera that moves and not the canvas elements.
Answer by mattlevonian · Mar 29, 2016 at 05:00 AM
Think about the behavior you want: after the release of the mouse, it keeps sliding at the same speed, and then slowly decreases speed to zero.
In order to achieve this, you need to know the speed at which it was sliding to begin with. Since you're already storing previous positions of the mouse every frame, this should be easy. When the mouse is released, calculate the velocity of the mouse in that frame:
velocity = (current - last) / deltaTime
Then each frame when the mouse is up, apply that velocity:
SetPosition( current_position + velocity * deltaTime )
And then slowly smooth the velocity to zero (smoothing value of about 0.5, probably):
velocity = Vector3.Lerp( velocity, Vector3.zero, deltaTime / smoothingValue )
Hope that answers your main concern.
Didn't work or didn't understand how to work this code implemented to my