Hey, am trying to move an object along a series of slopes, and also make it follow a trajectory when it reaches a certain velocity at the apex of a slope. Am having a few issues with my code. Am coding in C# Unity, so am using Unity's rigid body and collision system, and varying properties as and when required. I would really appreciate it someone could just check and see if there is anything wrong with it.
When I accelerate up a slope, it accelerates but on reaching the top or the apex of the slope it starts to move back down. And when I accelerate down a slope it moves very slowly or doesn't move at all (it should be moving at a greater acceleration).
What is the appropriate condition or process to use to synch all the movement together (such that it is smooth and seamless).
public void Accelerate(Vector3 slopeNormal)
{
if(MoveDirection.magnitude > 0f)
{
Vector3 targetVelocity ;
Vector3 currentVelocity ;
Vector3 velocityChange ;
Vector3 force ;
Vector3 a ;
float levelStopTime ;
float brakingDistance ;
targetVelocity = Speed * MoveDirection ;
currentVelocity = Character.rigidbody.velocity;
velocityChange = targetVelocity - currentVelocity;
a.x = Mathf.Clamp(velocityChange.x, -MaxAcceleration, MaxAcceleration);
a.y = Mathf.Clamp(velocityChange.y, -MaxAcceleration, MaxAcceleration);
a.z = Mathf.Clamp(velocityChange.z, -MaxAcceleration, MaxAcceleration);
Acceleration = a.magnitude * Mathf.Pow (Time.deltaTime, 2f); // Not sure, CHECK!!
force = Character.rigidbody.mass * a ;
// levelStopTime = (m_character.rigidbody.velocity / m_maxAcceleration).magnitude ;
// brakingDistance = (m_character.rigidbody.velocity.magnitude * m_levelStopTime) + (m_maxAcceleration * m_levelStopTime) ;//Mathf.Pow(m_levelStopTime, 2f) / 2f) ;
if(Input.GetKey(KeyCode.U))
AccelerateUpSlope(slopeNormal) ;
else if(Input.GetKey(KeyCode.D))
AccelerateDownSlope(slopeNormal) ;
else
Character.rigidbody.AddForce(force) ;
}
else
Debug.LogError("Movement Direction Invalid!!") ;
}
public void AccelerateDownSlope(Vector3 slopeNormal)
{
float fG, fNet, fParallel ;
float m ;
float g ;
float theta ;
float a ;
Vector3 A ;
Vector3 characterNormal = Character.rigidbody.velocity.normalized ;
m = Character.rigidbody.mass ;
g = Physics.gravity.y ;
fG = m * g;
theta = Vector3.Angle(characterNormal, slopeNormal) ;
fParallel = fG * Mathf.Sin(theta) ;
fNet = fParallel ;
a = fNet / m ;
A = a * new Vector3(1f, 1f, 0f) ;
Debug.Log("Down " + A) ;
Acceleration = a * Mathf.Pow (Time.deltaTime, 2f); // Not sure, CHECK!!
Character.rigidbody.AddForce(A, ForceMode.Acceleration) ;
}
public void AccelerateUpSlope(Vector3 slopeNormal)
{
float fG, fNet, fParallel, fPerpendicular ;
float m ;
float g ;
float theta ;
float a ;
Vector3 A ;
Vector3 characterNormal = Character.rigidbody.velocity.normalized ;
m = Character.rigidbody.mass ;
g = Physics.gravity.y ;
fG = m * g;
theta = Vector3.Angle(characterNormal, slopeNormal) ;
Debug.Log(theta) ;
fParallel = fG * Mathf.Sin(theta) ;
fPerpendicular = CoefficentFriction * fG * Mathf.Cos(theta) ;
fNet = fParallel - fPerpendicular ;
a = fNet / m ;
A = a * new Vector3(1f, 1f, 0f) ;
Debug.Log("UP " + A) ;
Acceleration = a * Mathf.Pow (Time.deltaTime, 2f); // Not sure, CHECK!!
Character.rigidbody.AddForce(A, ForceMode.Acceleration) ;
}
public void ProjectileMotion(Vector3 colliderNormal)
{
float maxVelocityX = 45f ;
float maxVelocityY = 60f ;
Vector3 initialVelocity = go.rigidbody.velocity ;
Vector3 initialPosition = go.rigidbody.position ;
// float angle = Vector3.Angle(go.rigidbody.position.normalized, colliderNormal) ;
// float launchAngleRad = (angle * Mathf.PI) / 180f ;
float launchAngleRad = (m_launchAngle * Mathf.PI) / 180f ;
float timeOfFlight = (2f * initialVelocity.magnitude * Mathf.Sin(launchAngleRad)) / Physics.gravity.magnitude ;
// Debug.Log("Launch Angle (rad) - " + launchAngleRad) ;
// Debug.Log("Time of Flight - " + timeOfFlight) ;
float x, y ;
x = initialPosition.x + (initialVelocity.x * Mathf.Cos(launchAngleRad) * timeOfFlight) ;
y = initialPosition.y + (initialVelocity.y * Mathf.Sin(launchAngleRad) * timeOfFlight) - (0.5f * Physics.gravity.y * Mathf.Pow(timeOfFlight, 2)) ;
// Debug.Log("x Position - " + x) ;
// Debug.Log("y Position - " + y) ;
Vector3 amtToMove = new Vector3(x, y, go.transform.position.z) ;
Vector3 finalVelocity = amtToMove / timeOfFlight ;
// go.rigidbody.MovePosition(amtToMove) ;
if(finalVelocity.x >= 0f)
{
// Debug.Log(finalVelocity) ;
finalVelocity.x = Mathf.Clamp(finalVelocity.x, -maxVelocityX, maxVelocityX);
finalVelocity.y = Mathf.Clamp(finalVelocity.y, -maxVelocityY, maxVelocityY);
go.rigidbody.AddForce(finalVelocity, ForceMode.VelocityChange) ; // ForceMode.Acceleration) ;
}
}
Also would this be the best way to check if the object is moving on a slope.
public void CollisionCheck(GameObject go)
{
Ray ray ;
RaycastHit hit ;
float x, y ;
// float offset = 10f ;
float playerGroundSpace = 0.0005f ;
CapsuleCollider collider = go.GetComponent<CapsuleCollider>() ;
// Checking for collision up and down
x = go.transform.position.x - go.transform.localScale.x / 2f ;
y = go.transform.position.y + go.transform.localScale.y / 2f ;
ray = new Ray(new Vector2(x, y), new Vector2(0f, 10f)) ;
Debug.DrawRay(ray.origin, ray.direction);
if (Physics.Raycast(ray, out hit))
{
float dst = Vector3.Distance(ray.origin, hit.point) ;
if(dst > playerGroundSpace)
{
Debug.Log("Collision, UP/DOWN") ;
}
}
// Checking for collision left and right
x = go.transform.position.x + go.transform.localScale.x / 2f ;
y = go.transform.position.y - go.transform.localScale.y / 2f ;
ray = new Ray(new Vector2(x, y), new Vector2(10, 0)) ;
Debug.DrawRay(ray.origin, ray.direction);
if (Physics.Raycast(ray, out hit))
{
float dst = Vector3.Distance(ray.origin, hit.point) ;
if(dst > playerGroundSpace)
{
Debug.Log("Collision, LEFT/RIGHT") ;
}
}
}