Bezier list<> movement, Logic getting stuck moving to new curve in list with ugly current fix.
This works fine but I had to add this nasty " _logicFixForChangingCurves = 0.01f;" because when I swap up or down my list to a new curve my object was sticking. I can see that it's having a problem with the way I find my position on the bezier which is 0 for the start of the curve and 1 at the end. When moving to the next curve in the list its getting stuck if I set it to 0 or 1;
So the total curve looks like 0 start, 1 end, 0 start next curve, 1 end of curve, 0 start of next curve .... Setting the position from 1 end of first curve to 0 start of next curve triggers the object to stick in place. Using the offset it works fine but obviously is just hiding a flaw in my logic and/or my bad design.
Any suggestions on how to change the logic or architecture would be appreciated.
EDIT:: Have subsequently found the problem, see comment below, However I would like to know any suggestions for a better architecture for this.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TigerForge;
public class BezierPathPosition: MonoBehaviour
{
[SerializeField] private Transform[] PlayerRoutes;
public SOInt RouteIndex;
public SOFloat CurrentTParam;
public GameObject player;
public Vector3 P0, P1, P2, P3;
public float EndOfBezierCurve = 1f;
public float StartOfBezierCurve = 0f;
private float _logicFixForChangingCurves = 0.01f;
private void Awake()
{
EventManager.StartListening("HORIZONTAL_MOVEMENT", PlayerTParamChange);
}
private void Start()
{
RouteIndex.CurrentIntValue = 0;
CurrentTParam.SOFloatValue = 0.5f;
BezierMove(gameObject);
}
private void Update()
{
// if object is all the way left
if (CurrentTParam.SOFloatValue <= StartOfBezierCurve)
{
ChangeCurveDown();
}
// if the object is all the way right.
if (CurrentTParam.SOFloatValue >= EndOfBezierCurve)
{
ChangeCurveUp();
}
BezierMove(gameObject);
}
private void ChangeCurveUp()
{
//All the way right in base bezier curve and there are more available
if (RouteIndex.CurrentIntValue != PlayerRoutes.Length - 1)
{
RouteIndex.CurrentIntValue++;
CurrentTParam.SOFloatValue = 0;
}else if (RouteIndex.CurrentIntValue == PlayerRoutes.Length - 1) //We Are on the last curve
{
CurrentTParam.SOFloatValue = 1; // set to the end of the new curve
}
}
private void ChangeCurveDown()
{
//We have more than one curve in the list
if (PlayerRoutes.Length - 1 >= 1 && RouteIndex.CurrentIntValue != 0)
{
RouteIndex.CurrentIntValue--; // increase to next index / next curve
CurrentTParam.SOFloatValue = EndOfBezierCurve - _logicFixForChangingCurves;// set to very near the end of the new curve (float rounding) fix stops
// looping and fixing the object in place where two curves Meet.
}
else if (RouteIndex.CurrentIntValue == 0) //All the way left in base bezier curve.
{
CurrentTParam.SOFloatValue = StartOfBezierCurve;
}
}
public Vector3 PositionOnCurve(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
{
Vector3 position;
//Brezier maths equation where tParam is distance along the curve from start (0) to End (1);
position = Mathf.Pow(1 - CurrentTParam.SOFloatValue, 3) * p0 +
3 * Mathf.Pow(1 - CurrentTParam.SOFloatValue, 2) * CurrentTParam.SOFloatValue * p1 +
3 * (1 - CurrentTParam.SOFloatValue) * Mathf.Pow(CurrentTParam.SOFloatValue, 2) * p2 +
Mathf.Pow(CurrentTParam.SOFloatValue, 3) * p3;
return position;
}
private void PointsDefiningBezierCurve()
{
P0 = PlayerRoutes[RouteIndex.CurrentIntValue].GetChild(0).position;
P1 = PlayerRoutes[RouteIndex.CurrentIntValue].GetChild(1).position;
P2 = PlayerRoutes[RouteIndex.CurrentIntValue].GetChild(2).position;
P3 = PlayerRoutes[RouteIndex.CurrentIntValue].GetChild(3).position;
}
public void BezierMove(GameObject objecttomove)
{
PointsDefiningBezierCurve();
objecttomove.transform.position = PositionOnCurve(P0, P1, P2, P3);
}
public void PlayerTParamChange()
{
var eventData = EventManager.GetDataGroup("HORIZONTAL_MOVEMENT");
var leftorright = eventData[0].ToFloat();
var speedmodifier = eventData[1].ToFloat();
if (leftorright < 0f)
{
CurrentTParam.SOFloatValue -= Time.deltaTime * speedmodifier;
}
else if (leftorright > 0f)
{
CurrentTParam.SOFloatValue += Time.deltaTime * speedmodifier;
}
}
}
have fixed by changing two if statement s if (CurrentTParam.SOFloatValue <= StartOfBezierCurve) to if (CurrentTParam.SOFloatValue < StartOfBezierCurve) and if (CurrentTParam.SOFloatValue >= EndOfBezierCurve) to if (CurrentTParam.SOFloatValue > EndOfBezierCurve). removing the = fixed it so it no longer needs the _logicFixForChangingCurves fix.
Your answer
Follow this Question
Related Questions
Simple `Match 3+ in a row` pattern 0 Answers
If else condition didn't work 0 Answers
For loop and conditionals... 1 Answer
Class value as list of the same class 0 Answers
Only spawning power ups that the player wants in that game 1 Answer