Unity-围绕Y轴旋转的对象,同时不断向地面设置不同的旋转

问题描述 投票:-1回答:1

所以我不知道我是否在标题中正确解释了它,但是我想做的是通过单击Q或E绕Y轴旋转对象,但与此同时我正在向地面进行光线投射检查点旋转使其面向正确的方向。

为了阐明这一点,下面是一个示例:我正在尝试放置壁炉,我在山上。为了防止壁炉进入地形,我需要旋转壁炉,以便将其底部“粘在”地形上,但是随后我想将其绕Y旋转几度。这是我得到的代码:

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));
                }
            }
        }
    }
}

这里的问题是它面向地形没有任何问题,但是我无法自己将其围绕Y旋转。我认为这是由于事实,我一直在更新轮换,但是我不知道如何更改它。

unity3d rotation raycasting
1个回答
0
投票

是,是因为您要使用prefabAsTransform.transform.up = hit.normal;设置每帧的旋转度。并且不考虑当前的前进方向。

相反,您应该使用prefabAsTransform.rotation = LookRotation(newForward, newUp);,但是,如何确定newForward?您可以为此使用交叉产品。这对我有用:

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));
            }
            //transform.Rotate(Vector3.up * 50f * Time.deltaTime);
        }
        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));
            }
            //transform.Rotate(Vector3.up * 50f * Time.deltaTime);
        }
    }
}

example of code working

© www.soinside.com 2019 - 2024. All rights reserved.