I'm writing a simple player movement script in Unity 3D, and I've been using Vector3.ProjectOnPlane()
to accomplish slope/ramp movement. For the most part, this works on smaller slopes but I've noticed that the steeper the slope is, the more the direction seems to drift further away than expected, causing the player to walk further to one side than the input would suggest.
(To clarify, orientationTransform
is rotated via the Mouse Input, thus only needing to use transform.forward/right
in the movement calculation.)
Code:
// Excerpt from main movement loop
Vector3 movementDirection = (orientationTransform.forward.normalized * inputs.y + orientationTransform.right.normalized * inputs.x).normalized;
if (stateHandler.IsGrounded) {
if(stateHandler.IsOnSlope) {
Debug.DrawRay(orientationTransform.position, movementDirection.normalized * 3f, Color.magenta);
return GetVectorOnSlope(movementDirection) * movementForce * Time.fixedDeltaTime;
} else {
return movementDirection * movementForce * Time.fixedDeltaTime;
}
}
// Vector Function
Vector3 GetVectorOnSlope(Vector3 vector) {
RaycastHit hitInfo;
if (Physics.Raycast(orientationTransform.transform.position, Vector3.down, out hitInfo,
1f, groundLayer)) {
Debug.DrawRay(orientationTransform.position, Vector3.ProjectOnPlane(vector,
hitInfo.normal) * 2f, Color.red);
return Vector3.ProjectOnPlane(vector, hitInfo.normal).normalized;
} else {
return vector;
}
}
Example:
Desired Direction - Magenta
ProjectOnPlane Direction - Red
I've tried normalizing the result and experimenting with Vector3.Cross()
as well as attempting to skip using Vector3.ProjectOnPlane()
altogether, but I've not had much luck.
Is this the correct way for me to be implementing this? I feel like Vector3.ProjectOnPlane()
is behaving exactly as it should, but I can't figure out an alternative to achieve what I'm looking for.
Any help is greatly appreciated!
.normalized
getters in there.forward
andright
are already unit vectors, so you don't need to normalize them. And you already normalizedmovementDirection
when you assigned it, so you don't have to normalize it again when you read it. \$\endgroup\$