How can I make a rocket pivot around it's bottom part insted of the middle in unity?

Viewed 359

How would I go about making a rocket player controller rotate around its bottom part?

Heres my code up until now (I know it has problems, it's just a proof of concept for now)

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rocket : MonoBehaviour
{
    Rigidbody rigidBody;
    void Start()
    {
        rigidBody = GetComponent<Rigidbody>();
    }

    void Update()
    {
        ProcessInput();
    }

    private void ProcessInput()
    {
        if (Input.GetKey(KeyCode.Space))
        {
            rigidBody.AddRelativeForce(Vector3.up);
        }

        if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
        {
            if (!Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.RightArrow))
            {
                transform.Rotate(new Vector3(0, 0, 2));
            }
        }

        if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
        {
            if (!Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.LeftArrow))
            {
                transform.Rotate(new Vector3(0, 0, -2));
            }
        }
    }
}
2 Answers

Good news, Unity has

https://docs.unity3d.com/ScriptReference/Transform.Rotate.html

but! more usefully, it has:

https://docs.unity3d.com/ScriptReference/Transform.RotateAround.html

I'm pretty sure that's exactly what you want.

(BTW be aware - it's not that trivial to figure out just what the vector you rotate around will be. You have to have a really good feel for cross products and other Vector manipulation. Unity is annoying like that - it seems really easy to use at first, but you really need a superb grasp of physics (I mean Newtonian physics) and every aspect of vectors and quaternions to really be able to make games - it's tough.)

One tip: you see how you are adding force to move it. Try adding torque (AddTorque) to turn it!

If you have a Rigidbody you should not mix in movements via transform! This breaks the physics and collision detection and leads to strange behavior.


rather use e.g. Rigidbody.centerOfMass to set the center of mass according to your needs.

And then AddTorque or MoveRotation

private void ProcessInput()
{
    if (Input.GetKey(KeyCode.Space))
    {
        rigidBody.AddRelativeForce(Vector3.up);
    }

    if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
    {
        if (!Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.RightArrow))
        {
            turnLeft = true;
        }
    }

    if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
    {
        if (!Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.LeftArrow))
        {
            turnRight = true;
        }
    }
}

private bool turnLeft;
private bool turnRight;

private void FixedUpdate ()
{
    if(turnLeft)
    {
        turnLeft = false;
        rigidbody.MoveRotation(rigidBody.MoveRotation(rigidbody.rotation * Quaternion.Euler(0, 0, 2));
    }

    if(turnRight)
    {
        turnRight = false;
        rigidBody.MoveRotation(rigidBody.MoveRotation(rigidbody.rotation * Quaternion.Euler(0, 0, -2));
    }
}

Though in general it is easier to use an angle per second like e.g.

rigidBody.MoveRotation(rigidbody.rotation * Quaternion.Euler(0, 0, -45 * Time.deltaTime));

Time.deltaTime is the time passed since the last physics update so this makes sure you rotate with exactly -45° / second.


Alternatively take a look at How to change objects pivot point -> You could simply put your mesh under a parent object and instead use that parent as the rigidbody and move script etc. so you can create any offset relative to the parent you wish.

And yes one also could recalculate the mesh vertex positions themselves to fit your needs but usually the parenting approach is already sufficient ;)

Related