# Limit of movement - French fries in fryer đźŤź

I am currently trying to get the French fries inside a fryer to move according to the rotation where they are stored.
Iâ€™m not using physics, Iâ€™m moving the fries/ingredients by code but I donâ€™t know how to implement the movement limitation on the Y axis.

In the following video can see how the fryer and the ingredients are currently working.
Fryer Video

In the following image can see the fryer with a red box Gizmo, that is the area where I am limiting the movement in the X and Z axis.

I have arranged objects in the position of the limits and it recognizes them correctly.

To know which direction to apply the force in which the ingredients should be directed, I am using a Plane created from the location of the fryer and using the Plane.ClosestPointOnPlane method to identify the highest point on the fryer, subtracting that point with the central pivot of the fryer I can get a direction that is facing downwards, so I can always know which downward direction the ingredients should go as if they had gravity to apply the movement.
A tutorial that I found interesting about the planes was: Unity Tutorial - How to Make Calculations on Geometric Planes

``````/// <summary>
/// ClosestPointOnPlane is assigned the transform that will act as a plane, when the plane/GameObject
/// is rotated we can obtain the side closest to the plane, either the position closest to the top or
/// the bottom regardless of the direction in which it is tilted. the plane/GameObject.
/// </summary>
[System.Serializable]
public class ClosestPointOnPlane
{
//Plane Settings
private Transform planeInNormal;

//ClosestPointOnPlane
//closestPointAboveOnPlane: If equal to true: It will search for the closest point from the top of the plane.
private bool closestPointAboveOnPlane;
private Vector3 pointForClosetPointOnPlane;
private readonly Vector3 offsetPointForClosetPointOnPlane = new Vector3(0, 0.5f, 0);
private Vector3 transClosetPointOnPlane;

[SerializeField]
private bool enableGizmosClosestPointOnPlane;

public Plane getPlane { get { return planeFryerBasket; } }
public Vector3 getTransClosetPointOnPlane { get { return transClosetPointOnPlane; } }

// -----------------------------------------------------------------------------------------------------------------

public void InitClosestPointOnPlane(Transform transformForPlaneInNormal, bool closestPointAboveOnPlane = true)
{
planeInNormal = transformForPlaneInNormal;
this.closestPointAboveOnPlane = closestPointAboveOnPlane;
}

public void UpdateClosestPointOnPlane()
{
if (closestPointAboveOnPlane == true)
{
//Top
pointForClosetPointOnPlane = planeInNormal.position + offsetPointForClosetPointOnPlane;
}
else
{
//Bottom
pointForClosetPointOnPlane = planeInNormal.position - offsetPointForClosetPointOnPlane;
}

}

// -----------------------------------------------------------------------------------------------------------------

public void UpdateGizmosClosestPointOnPlane()
{
if (enableGizmosClosestPointOnPlane == true && planeInNormal != null)
{
//Plane position
Gizmos.color = Color.white;

//pointForClosetPointOnPlane

//transClosetPointOnPlane
Gizmos.color = Color.red;
}
}
}
``````

First, the angle of rotation is checked to know if a moving force must be applied. In the previous code we saw how to obtain the downward direction in which the ingredient should move, depending on the axis to which the direction is, it will be added ( time.delaTime * speedVFXMovement) constantly to move the position of the ingredient.
Since the movement is applied locally, I am only moving it in the X and Z axis, that is, towards the sides inside the fryer.

``````        #region Movement EntitiesVFX
[Space(50)]
[SerializeField]
private float yMaxRotation = 55f;
[SerializeField]
private float yMinRotation = 30f;

private float rotationAngle;
private float forceMovement;
[SerializeField]
private float speedVFXMovement = 0.1f;
private Vector3 targetDirection;

private float CalculatePourangle()
{
}

//Run On Update
{
rotationAngle = Mathf.Clamp(CalculatePourangle(), yMinRotation, yMaxRotation);
forceMovement = Mathf.InverseLerp(yMaxRotation, yMinRotation, rotationAngle);

if (forceMovement > 0)
{
for (int i = 0; i < cookingIngredientOnFryerBaskets.Count; i++)
{
targetDirection = transform.position - closestPointOnPlane.getTransClosetPointOnPlane;
float timeSpeed = Time.deltaTime * speedVFXMovement;

if (targetDirection.x > 0)
{
//Right
}
else if (targetDirection.x < 0)
{
//Left
}
if (targetDirection.z > 0)
{
//Forward
}
else if (targetDirection.z < 0)
{
//Reverse
}

cookingIngredientLocalPos.y,

GizmosUtilities.DrawArrow(cookingIngredientOnFryerBaskets[i].transform.position, targetDirection, Color.green, 0.3f, 0.05f, 10);
}
}
}
#endregion
``````

After applying the movement in the Update, the â€śUpdateLimitForVFXCookingIngredientsâ€ť method is executed to check if the ingredients are within the limits, that is, the red box gizmo that was seen in the first image.

To know if the ingredients are within the limits, the Bounds are used and with the â€śGetObjBoundsEdgesAndCornersPositionsâ€ť method I obtain the edges of the ingredient, since I do not verify the position of the ingredient but rather the edges that take the mesh into account.

If any of the edges of the mesh are outside the limit position/red box gizmo then it returns the new position that should be applied so that it is inside the limits.

``````#region Limit Movement EntitiesVFX
//Run Check Limit With All Ingredients On Update
private void UpdateLimitForVFXCookingIngredients()
{
//Check Cookingredient Is Within The Limits
for (int i = 0; i < cookingIngredientOnFryerBaskets.Count; i++)
{
}
}

{
if (initBoundsAndLimitsPositions == true)
{

ObjBoundsInfo objBoundsInfo = GeneralUtilities.GetObjBoundsEdgesAndCornersPositions(transformCookingIngredient, cookingIngredientOnFryerBasket.getRender.bounds, false);
Vector3 leftEdgeCenter = objBoundsInfo.leftEdgeCenter;
Vector3 rightEdgeCenter = objBoundsInfo.rightEdgeCenter;
Vector3 forwardEdgeCenter = objBoundsInfo.forwardEdgeCenter;
Vector3 reverseEdgeCenter = objBoundsInfo.reverseEdgeCenter;

Vector3 halfSizeOfSpawnZone = sizeOfZoneForSpawnEntitiesStoredVFX / 2;
Vector3 leftEdgeSpawnZoneCenter = transform.position + offsetCenterOfZoneForSpawnEntitiesStoredVFX - new Vector3(halfSizeOfSpawnZone.x, 0, 0);
Vector3 rightEdgeSpawnZoneCenter = transform.position + offsetCenterOfZoneForSpawnEntitiesStoredVFX + new Vector3(halfSizeOfSpawnZone.x, 0, 0);
Vector3 forwardEdgeSpawnZoneCenter = transform.position + offsetCenterOfZoneForSpawnEntitiesStoredVFX + new Vector3(0, 0, halfSizeOfSpawnZone.z);
Vector3 reverseEdgeSpawnZoneCenter = transform.position + offsetCenterOfZoneForSpawnEntitiesStoredVFX - new Vector3(0, 0, halfSizeOfSpawnZone.z);

//CheckLimits
Vector3 newPosition = transformCookingIngredient.position;
/*Debug.Log("Test3: leftEdgeCenter: " + objBoundsInfo.leftEdgeCenter + " - rightEdgeCenter: " + objBoundsInfo.rightEdgeCenter +
"\n - forwardEdgeCenter : " + objBoundsInfo.forwardEdgeCenter + " - reverseEdgeCenter : " + objBoundsInfo.reverseEdgeCenter);*/

if (leftEdgeCenter.x < leftEdgeSpawnZoneCenter.x)
{
//DDebug.Log("leftEdgeCenter i: " + i + " - " + transformCookingIngredient.name, Color.green);
newPosition.x = newPosition.x + Mathf.Abs(leftEdgeSpawnZoneCenter.x - leftEdgeCenter.x);
}
else if (rightEdgeCenter.x > rightEdgeSpawnZoneCenter.x)
{
//DDebug.Log("rightEdgeCenter i: " + i + " - " + transformCookingIngredient.name, Color.green);
newPosition.x = newPosition.x - Mathf.Abs(rightEdgeSpawnZoneCenter.x - rightEdgeCenter.x);
}

if (forwardEdgeCenter.z > forwardEdgeSpawnZoneCenter.z)
{
//DDebug.Log("forwardEdgeCenter i: " + i + " - " + transformCookingIngredient.name, Color.cyan);
newPosition.z = newPosition.z - Mathf.Abs(forwardEdgeSpawnZoneCenter.z - forwardEdgeCenter.z);
}
else if (reverseEdgeCenter.z < reverseEdgeSpawnZoneCenter.z)
{
//DDebug.Log("reverseEdgeCenter i: " + i + " - " + transformCookingIngredient.name, Color.cyan);
newPosition.z = newPosition.z + Mathf.Abs(reverseEdgeSpawnZoneCenter.z - reverseEdgeCenter.z);
}

transformCookingIngredient.position = newPosition;
}
}
#endregion
``````

I am currently not applying the limit in And since I donâ€™t know how to apply it correctly, any help on how to do it will be appreciated, any corrections to the code and how I do things will also be appreciated to improve the system , thanks to everyone who wants to help.