How to rotate on an angled plane defined by the plane normal

Viewed 29

For a school assignment I am trying to make a tank point and shoot game, where I need align the tank to the plane normal using raycasting. But when I do this the Y axis rotaton gets locked and I can't rotate it any more.

The idea is that if a plane is angled, the tank is sticking to it and the transform.up is defined by the plane normal and the tank is able to go up and down the plane and also rotate on it.

This is the code.

public class PlayerController : MonoBehaviour
{
    public GameObject player;

    public float movementSpeed;
    public float rotationSpeed;

    RaycastHit hitinfo;
    public float hoverHeight = 0.7f;
    float offsetdistance;
    //public Vector2 moveVal;


    public Vector2 moveVal;
    public Vector3 Dir;
    public float moveSpeed;


    //get OnMovie input and put it in a vector to be used later on
    void OnMove(InputValue value)
    {
        moveVal = value.Get<Vector2>();
    }

    void Update()
    {
        //moves player 
        PlayerHover();
        player.transform.Translate(new Vector3(0, 0, moveVal.y) * moveSpeed * Time.deltaTime);
        player.transform.Rotate(0, moveVal.x * rotationSpeed * Time.deltaTime, 0, Space.Self);



    }

    void PlayerHover()
    {
        if (Physics.Raycast(transform.position, -Vector3.up, out hitinfo, 20f))
        {
            offsetdistance = hoverHeight - hitinfo.distance;
            transform.up = hitinfo.normal;
            transform.position = new Vector3(transform.position.x, transform.position.y + offsetdistance, transform.position.z);
        }

    }
1 Answers

You are probably using the wrong overload of transform.Rotate, you should probably be using:

public void Rotate(Vector3 axis, float angle, Space relativeTo = Space.Self); 

Where the axis parameter should be the plane normal. Assuming you want to rotate around the plane normal

If you want to set the rotation directly you might need to use SetPositionAndRotation, you should be able to get the quaternion from LookDirection using the plane normal for the forward parameter, but you may need to play around with the axes or apply a 90-degree rotation to get the desired axis to point in the right direction.

In general if you want to rotate an object so that one axis matches up to some other axis you can:

  1. Calculate the angle between the axes, i.e. compute the dot-product and apply the ACos function. Or use any built in methods.
  2. Calculate an orthogonal vector by taking the cross-product between the two vectors
  3. Use this axis and angle in the Rotate function above to produce the desired rotation. Or any other functions that produce a rotation that take an axis and angle.

Use the up-direction of your tank and the plane normal as input axes for the algorithm above if you want to rotate your tank to be orientated to the plane.

Related