so im trying to build a grid of objects (Canvas Objects) that when i move them they move with my finger relative to their position and when i release they arrange themselves on a y axis offeset by 50 and spacing of
100 so in this picture(the one where they are not messed up) they are at y of -150 -50 50 150
the size varies but those rules apply
for some reason i cant for the life of me get it to work it gets messed up for some reason i duuno…
tried couple of ways ill show one of them here in the hope somebody will come on a white horse and save me !
this called on every item in the column after i release my finger
would really appreciate some help
private IEnumerator GetToClosestPoint(Item _item)
{
Vector2 startingPos = _item.transform.localPosition;
float delta = startingPos.y % 100;
bool goUp = false;
if (delta >= 50)
{
//Go Down
goUp = false;
}
else
{
//Go Up
goUp = true;
}
delta %= 50;
Vector2 endPos = startingPos;
float newY = startingPos.y + delta + (spacing / 2);
if (goUp)
{
newY = startingPos.y - delta;
}
else
{
newY = startingPos.y + delta;
}
endPos.y = newY;
for (float i = 0; i < autoArrangeTime; i += Time.deltaTime)
{
_item.transform.localPosition = Vector3.Lerp(startingPos, endPos, i / autoArrangeTime);
yield return null;
}
_item.transform.localPosition = endPos;
yield return null;
}
OK, there are a number of problems here, though I’m not sure which of them (or what combination) is causing the specific issue you have in mind.
For one, you’re abusing Lerp. Don’t do that. Use Vector3.MoveTowards instead.
Second, I don’t understand why, having already found the correct delta, you then do delta %= 50. That makes no sense.
This followed by more code I don’t understand.
Why make it so hard? There are only two steps to this problem:
- Figure out where the thing should be (probably by simply using Mathf.Round).
- Move it there smoothly over time, by using Vector3.MoveTowards in a coroutine loop (or Update event).
And actually the Update event would probably be preferable, since then the user can interrupt it by grabbing the tile again even while it’s moving towards its target. Something like this.
public Vector3d target; // where we are settling into
public float speed = 10; // speed in units/sec
void Update() {
transform.position = Vector3.MoveTowards(transform.position, target, speed * Time.deltaTime);
}
public void SnapTarget(Vector3d dropPos) {
// set our target to the nearest proper position near dropPos
target = dropPos;
target.y = Mathf.Round(target.y/100) * 100; // or whatever
target.x = Mathf.Round(target.x/100) * 100;
}
So at the end of dragging, just call SnapTarget with wherever it is (maybe just transform.position), and that’s it. It’ll move there at the designated speed thanks to the Update method.
im using lerp because i need to control the amount of time of that snap it should be always fixed , how can i figure out where they should be ? from the current position ? i dont just want to round their current position , and the user will not be able to interrupt the animation it just not added yet, thank you for your replay but i dont think its the answer
OK, I apologize — I’m so used to seeing Lerp abuse that I saw it where it didn’t exist! You are using it correctly in your code (by storing the starting position, rather than using the current position as most beginners do).
Good luck with your project!
1 Like