creating a bezier curve in real time and making it move an object (read notes)
Wed Jan 25 2023 02:37:05 GMT+0000 (Coordinated Universal Time)
Saved by
@miguel9177
#c#
#unity
#physics
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CurveBallTest : MonoBehaviour
{
private enum CurveBallState { idle, startCross,crossingBall, endedCross}
[Header("bezier curve points")]
public Transform pointA; // The starting point of the Bezier curve
public Transform pointB; // The first control point of the Bezier curve
public Transform pointC; // The second control point of the Bezier curve
public Transform pointD; // The end point of the Bezier curve
public Transform crossingTarget;
private CurveBallState state;
[Header("cross settings")]
public float speedOfCross = 1.0f; // The speed at which the object moves along the curve
public float crossHeight = 3f;
public float crossCurve = 3f;
[Header("variables to get the ball speed while on bezier")]
private Vector3 currentVelocity;
private Vector3 lastPos;
//public float duration = 5.0f; // The total duration of the curve
Rigidbody rb;
float startTime;
void Start()
{
rb = GetComponent<Rigidbody>();
state = CurveBallState.startCross;
}
void FixedUpdate()
{
CallFunctionsDependingOnState();
}
//this calls the correct functions depending on the current state
private void CallFunctionsDependingOnState()
{
switch(state)
{
case CurveBallState.startCross:
StartCross();
break;
case CurveBallState.crossingBall:
CrossingBall();
break;
case CurveBallState.endedCross:
EndedCross();
break;
}
}
//this will initialize the cross
private void StartCross()
{
startTime = Time.time;
state = CurveBallState.crossingBall;
CreateBezierCurvePoints();
}
//this is called while the cross isnt finished (bezier curve hasnt ended)
private void CrossingBall()
{
Debug.Log(currentVelocity);
float t = (Time.time - startTime) * speedOfCross;
CalculateBallVelocityWhileOnBezier();
Vector3 position = CalculateBezierPoint(t, pointA.position, pointB.position, pointC.position, pointD.position);
rb.MovePosition(position);
if (t >= 1)
{
state = CurveBallState.endedCross;
}
}
//this is called at the end of the cross (bezier curve ended)
private void EndedCross()
{
rb.isKinematic = false;
rb.velocity = currentVelocity;
state = CurveBallState.idle;
}
#region Utility functions
Vector3 CalculateBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
{
// Calculate the position on the Bezier curve based on the t value
float u = 1 - t;
float tt = t * t;
float uu = u * u;
float uuu = uu * u;
float ttt = tt * t;
Vector3 p = uuu * p0;
p += 3 * uu * t * p1;
p += 3 * u * tt * p2;
p += ttt * p3;
return p;
}
private void CalculateBallVelocityWhileOnBezier()
{
currentVelocity = (rb.position - lastPos) / Time.fixedDeltaTime;
lastPos = rb.position;
}
private void CreateBezierCurvePoints()
{
pointA.position = this.transform.position;
Vector3 pointBPos_;
pointBPos_ = pointA.position + (Vector3.forward * crossCurve);
pointBPos_.y = pointA.position.y + crossHeight;
pointB.position = pointBPos_;
pointD.position = crossingTarget.position;
Vector3 pointCPos_;
pointCPos_ = pointD.position + (Vector3.forward * crossCurve);
pointCPos_.y = pointD.position.y + crossHeight;
pointC.position = pointCPos_;
}
#endregion
}
content_copyCOPY
this will create a bezier curve in real time and move the ball through it, in this example the point B and C are Moved at real time, if you want to setup this positions yourself, just comment the CreateBezierCurvePoints function.
Comments