MrGohut
MrGohut

Reputation: 23

Unity - rotating object around Y axis, while constantly setting up different rotation towards the ground

so i don't know if i explained it properly in the title, but what i'm trying to do is by clicking Q or E rotate object around the Y axis, but at the same time i'm raycasting to the ground to check the point rotation to face it in to the right direction.

To clarify this, here is an example: I'm trying to place the fireplace, i'm on the hill. To prevent the fireplace go into the terrain, i need to rotate it so that i would "stick" to the terrain by it's bottom, but then i want to rotate it around the Y a couple of degrees.. Here is the code that i've got:

using UnityEngine;

public class Foobar : MonoBehaviour
{
    Transform cam;
    Transform prefabAsTransform;
    Vector3 currentPos;
    float addToY = 0.5f;
    int mask;

    void Start()
    {
        cam = Camera.main.transform;
        prefabAsTransform = transform;
        mask = LayerMask.GetMask("Default");
    }

    void Update()
    {
        RaycastHit hit;
        if (Physics.Raycast(cam.position, cam.forward, out hit, Mathf.Infinity, mask))
        {
            currentPos = new Vector3(hit.point.x, hit.point.y + addToY, hit.point.z);
            prefabAsTransform.position = currentPos;
            prefabAsTransform.transform.up = hit.normal;
        }

        if (prefabAsTransform != null)
        {
            if (Input.GetKeyDown(KeyCode.Q))
            {
                if (Input.GetKey(KeyCode.LeftControl))
                {
                    prefabAsTransform.Rotate(new Vector3(0, 1, 0));
                }
                else
                {
                    prefabAsTransform.Rotate(new Vector3(0, 10, 0));
                }
            }
            if (Input.GetKeyDown(KeyCode.E))
            {
                if (Input.GetKey(KeyCode.LeftControl))
                {
                    prefabAsTransform.Rotate(new Vector3(0, -1, 0));
                }
                else
                {
                    prefabAsTransform.Rotate(new Vector3(0, -10, 0));
                }
            }
        }
    }
}

The problem here is that it's facing the terrain without any issues, but i'm unable to rotate it around Y by myself. I assume that's due to the fact, that i'm constantly updating the rotation, but i have no idea how to change that.

Upvotes: 2

Views: 1523

Answers (1)

Ruzihm
Ruzihm

Reputation: 20259

Yes, it's because you are setting the rotation every frame with prefabAsTransform.transform.up = hit.normal; and not taking the current forward direction into account.

Instead, you should use prefabAsTransform.rotation = LookRotation(newForward, newUp); But, how can you use the current forward to determine newForward? You can use cross products for that. This worked for me:

void Update()
{
    RaycastHit hit;
    if (Physics.Raycast(cam.position, cam.forward, out hit, Mathf.Infinity, mask))
    {
        currentPos = new Vector3(hit.point.x, hit.point.y + addToY, hit.point.z);
        prefabAsTransform.position = currentPos;

        Vector3 newUp = hit.normal;
        Vector3 oldForward = prefabAsTransform.forward;

        Vector3 newRight = Vector3.Cross(newUp, oldForward);
        Vector3 newForward = Vector3.Cross(newRight, newUp);

        prefabAsTransform.rotation = Quaternion.LookRotation(newForward, newUp);
    }

    if (prefabAsTransform != null)
    {
        if (Input.GetKeyDown(KeyCode.Q))
        {
            if (Input.GetKey(KeyCode.LeftControl))
            {
                prefabAsTransform.Rotate(new Vector3(0, 1, 0));
            }
            else
            {
                prefabAsTransform.Rotate(new Vector3(0, 10, 0));
            }
        }
        if (Input.GetKeyDown(KeyCode.E))
        {
            if (Input.GetKey(KeyCode.LeftControl))
            {
                prefabAsTransform.Rotate(new Vector3(0, -1, 0));
            }
            else
            {
                prefabAsTransform.Rotate(new Vector3(0, -10, 0));
            }
        }
    }
}

example of code working

Upvotes: 1

Related Questions