当前位置:   article > 正文

Unity 点击模型上任意位置,模型旋转,令点击位置朝向摄像机_unity 物体始终朝向摄像机方向

unity 物体始终朝向摄像机方向

Unity 点击模型上任意位置,模型旋转,令点击位置朝向摄像机
效果如下
在这里插入图片描述

1.鼠标点击屏幕时,从摄像机向鼠标屏幕坐标发射射线,获取射线与球交点P坐标(球需要添加 Sphere Collider 碰撞盒)
2.构建两个向量
向量a 从球心O指向摄像机,a = 摄像机坐标 - 球心坐标
向量b从球心O指向交点Pb = P - 球心坐标
3.如何计算旋转?
先看下图
在这里插入图片描述
我们需要将 向量b 经过旋转后与 向量a 重合

首先需要确认一个旋转轴
向量b 叉乘 向量a得到向量cross
向量cross垂直于向量a和向量b
所以向量cross可以作为向量b的旋转轴

计算向量b到向量a的夹角角度angle,然后计算以向量cross为旋转轴,旋转angle度的 四元数

Quaternion quaternion = Quaternion.AngleAxis(angle, cross);
  • 1

最后令 向量c = 四元数 quaternion 左乘 向量b
向量c 就跟向量a重合了
Vector3 c = quaternion * b;

上面讲的是向量的旋转

我们需要的是将球体旋转,道理也是一样的
令 四元数 result = 四元数 quaternion 左乘 球体旋转四元数
四元数 result 的结果就是球最终旋转的四元数

Quaternion result = quaternion * transform.rotation;
  • 1

新建 RotationTo.cs 脚本,将脚本挂载到需要旋转的球体对象上,运行Unity,点击模型,即可看到效果。代码如下

using UnityEngine;

public class RotationTo : MonoBehaviour
{
    private Transform tr;
    private Quaternion finalQuaternion = Quaternion.identity;

    void Start()
    {
        tr = transform;

        Transform redPoint = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;
        redPoint.transform.localScale = Vector3.one * 0.2f;
        redPoint.GetComponent<MeshRenderer>().material.color = Color.red;

        Vector3 position = tr.position + (Camera.main.transform.position - tr.position).normalized * tr.localScale.x;
        redPoint.transform.position = position;
    }

    void Update()
    {

        if (Input.GetMouseButtonDown(0))
        {
            GetTheClickPoint();
        }

        // 使用差值函数平滑的旋转到最终朝向
        tr.rotation = Quaternion.Lerp(tr.rotation, finalQuaternion, 0.01f);
    }

    // 获取点中球面上点坐标
    private void GetTheClickPoint()
    {
        //实例一个从主摄像机到鼠标点击位置的射线
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hitInfo;


        //发射射线,如果射线碰撞到带有 Collider 组件的对象将返回 true,否则返回 false
        if (Physics.Raycast(ray, out hitInfo))
        {
            // hitInfo.point 为射线和球面碰撞点坐标(鼠标点击球面坐标)
            finalQuaternion = CalculateRotation(hitInfo.point);
        }
    }

    //计算球面上点 hitPoint 朝向主摄像机时球的 rotation
    private Quaternion CalculateRotation(Vector3 hitPoint)
    {
        // 获取球心到点击球面点的向量
        Vector3 v1 = hitPoint - tr.position;

        // 获取球心到主摄像机的向量
        Vector3 v2 = Camera.main.transform.position - tr.position;

        // 球进行旋转即是以通过球心且和 v1、v2 组成界面垂直的向量(法向量)为旋转轴
        // v1 和 v2 叉乘,获取 v1、v2 组成界面的法向量
        Vector3 cross = Vector3.Cross(v1, v2);

        // 球绕旋转轴旋转的角度为 v1 和 v2 的夹角
        // 获取向量 v1、v2 的夹角
        float angle = Vector3.Angle(v1, v2);

        //获取球以 cross 为旋转轴 旋转angle 角度的 四元数
        Quaternion quaternion = Quaternion.AngleAxis(angle, cross);

        // 这样错误, 必须要 quaternion 左乘 tr.rotation
        //return tr.rotation * quaternion;
        return quaternion * tr.rotation;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/108822
推荐阅读
相关标签
  

闽ICP备14008679号