so, i’m using hit.normal to make the player character’s ‘‘up’’ direction perpendicular to whichever surface they’re standing on, and if you jump, it retains the last ‘‘up’’ vector it measured, which is useful for me because the idea is to jump off any immediate surface
when i’m not using quaternion.angleaxis, jumping off of a wall works perfectly
when i am, as soon as the raycast is out of range it changes the transform.up to 0
why is this
why
is there any way i can fix this, make it so it doesn’t go to zero when using angleaxis or an alternative way of rotating the player with effectively the same results
in the end, i fixed it in the most naïve and least sustainable way possible by just setting the rotation speed to 0
i’m happy with this, even if it’s suboptimal
however, if you have a better solution, please show me the way
{
Rigidbody rb;
bool airborne;
bool jumping;
float y_airspeed;
public float rayDistance;
public float spd;
float stickmagnitude;
float jump;
sbyte jumping_drag;
sbyte gravity;
float angle;
float ang = 40f;
Quaternion targetrotation;
// Use this for initialization
void Start()
{rb = GetComponent<Rigidbody>();}
// Update is called once per frame
void FixedUpdate()
{
float hor = Input.GetAxisRaw("Horizontal");
float ver = Input.GetAxisRaw("Vertical");
stickmagnitude = Mathf.Clamp01(new Vector2(hor, ver).magnitude);
if (hor != 0.0f || ver != 0.0f) { angle = Mathf.Atan2(hor, ver) * Mathf.Rad2Deg; }
RaycastHit hit;
var theRay = transform.TransformDirection(Vector3.down);
if (Physics.Raycast(transform.position, theRay, out hit, rayDistance))
{transform.rotation = Quaternion.FromToRotation(transform.up, hit.normal) * transform.rotation;}
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.AngleAxis(angle, transform.up), Time.deltaTime * ang);
transform.Translate(Vector3.forward * stickmagnitude * spd * Time.deltaTime, Space.Self);
if (Input.GetButtonDown("Jump"))
{
jumping = true;
jump = 48;
airborne = true;
}
if (airborne == true)
{
gravity = 28;
y_airspeed -= gravity * Time.deltaTime;
if (jump <= 0) {jump = 0;}
transform.Translate (Vector3.up * y_airspeed * Time.deltaTime, Space.World);
transform.Translate(Vector3.up * jump * Time.deltaTime, Space.Self);
if (jumping == true)
{
jumping_drag = 2;
jump -= jumping_drag * Time.deltaTime;
}
}
}
void OnCollisionEnter(Collision col)
{
if (col.collider)
{
airborne = false;
jumping = false;
gravity = 0;
jumping_drag = 0;
y_airspeed = -7;
jump = 0;
ang = 5;
}
}
private void OnCollisionExit(Collision col)
{
if (col.collider)
{ airborne = true;
ang = 0;
}
}
}
Double check if your math is correct.
You can insert a few Debugs to check if the actual angle is not 0 (before changing transform’s rotation).
For each quaternion approach, there a vector one (Which may be faster and easier to read / maintain).
If you can illustrate what are you trying to achieve we’ll probably figure something out.
var theRay = transform.TransformDirection(Vector3.down);
This one is probably can be transform.down.
Reorder multiplication order:
Vector3.forward * stickmagnitude * spd * Time.deltaTime
To:
stickmagnitude * spd * Time.deltaTime * Vector3.forward
So instead of doing Vector3 (x, y, z) * float (3), Vector3 * float (), Vector3 * float, it will compile to float * float, float * float, float * Vector3, which will run faster.
Time.deltaTime can be stored in a float variable inside method. Like float delta = Time.deltaTime.
Each time you do Time.deltaTime that is an external c++ call. Its small, but in the end everything counts towards FPS count.
Use Vector3.sqrMagnitude > 0 to check if the inputs are pressed instead of float comparison. Float comparison can be imprecise.
Or, use stickMagnitude, because you’ve already got it.
thanks for replying, you really went above and beyond with giving me plenty of options and i’ve since had an opportunity to finally read through and put your suggestions into practice
i have some questions i’d like to ask and comments too and i’ll also supply my notes of what i’m planning to achieve
quaternion.rotatetowards relies on a 2nd quaternion to rotate to from the first rotation, how do i go about modifying that 2nd quaternion to work like a quaternion.angleaxis? i.e: only rotate on a local pivot
i know my code for moving the character is flaud, but i simply use it to move around so i can test how the player object handles slopes,
the math is correct and the order of everything seems to be irrelevant; adding quaternion.angleaxis at any point in the code makes the transform.up revert back to 0 as soon as the raycast is out of range…i debugged this as you suggested, and when using angleaxis, the transform.up seems to always be set to 0, but the raycast normal negates that, until it becomes out of range
while i heeded your advice about using vector3.sqrmagnitude and i’ll leave it that way, as it is still good practice, i noticed no difference in precision, granularity or stability when i switched over from float comparison
that’s all the questions and comments i’ve got for now, i’ve included a tagged-on png of my design notes, although i forgot to mention that you go very, very fast, too