理解Quaternion.LookRotation()

类似这些函数,这个坐标,那个坐标,什么旋转,四元数一直是我比较头疼的东西,但是既然坑已然挖到这里了。不填也不行了。先理解一下这个函数,首先来看Unity Manual------https://docs.unity3d.com/ScriptReference/Quaternion.LookRotation.html

public static Quaternion LookRotation(Vector3 forward, Vector3 upwards = Vector3.up);

Parameters

forward The direction to look in.
upwards The vector that defines in which direction up is.

Description

Creates a rotation with the specified forward and upwards directions.

Z axis will be aligned with forward, X axis aligned with cross product between forward and upwards, and Y axis aligned with cross product between Z and X.

Returns identity if forward or upwards magnitude is zero. 
Returns identity if forward and upwards are colinear.

// You can also use transform.LookAt
using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    public Transform target;

    void Update()
    {
        Vector3 relativePos = target.position - transform.position;

        // the second argument, upwards, defaults to Vector3.up
        Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up);
        transform.rotation = rotation;
    }
}

从这个手册里我的理解就是:

Vector3.up为上方向,也就是(0,1,0)为上方向,forward就是该物体“看向”的方向。求得旋转角的四元数。。。emmm,什么鬼?所以求得的到底是什么值?有什么用呢?还是来个例子吧!

-----------------------------------------------------------------------------------------------------------------------------------------------

参考博客:https://blog.csdn.net/narutojzm1/article/details/51276433

-----------------------------------------------------------------------------------------------------------------------------------------------

于是我参照上面的博客,做了一个方向盘,截图如下:

理解Quaternion.LookRotation()_第1张图片

因为那篇博客的作者没有给出这个小测试项目的做法,这里我给出我猜测的做法。在做的过程中我还遇到了一点小问题,我要把这个问题的解决方法也记载下来。

首先Main Camera和Directional Light系统自带,我就不说了。

MainRule是个小Cube,在Hierarchy面板下点击Create-->3D Object-->cube就行,我把Scale缩小了一下,Inspector面板如下:

理解Quaternion.LookRotation()_第2张图片

然后蓝色的球和绿色的球,就是Sphere,蓝色代表z方向,绿色代表y方向,和 一样。球的创建方法和cube一样,绿色的是UpwardTarget,蓝色的是ForwardTarget。Inspector面板如下。球的颜色的话,直接拖动有颜色的图片到这个球上面去就行,自动创建Material:

理解Quaternion.LookRotation()_第3张图片

下面就是那几根平衡板了。用什么都行,我还是用的Sphere,然后把它拽扁了,插到cube中。短头的当正方向。Direction是一个空物体,x,y,z也是空物体,其中一个拉扁的Sphere(x轴)的Inspector如下,位置可根据情景调整:

理解Quaternion.LookRotation()_第4张图片

 然后在camera上挂在cs文件:

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

public class TestLookRotation : MonoBehaviour
{
    public GameObject forwardTarget;
    public GameObject mainRule;
    public GameObject line;

    // Start is called before the first frame update
    void Start()
    {
        forwardTarget = GameObject.Find("ForwardTarget");
        mainRule = GameObject.Find("MainRule");
        line = GameObject.Find("Direction");
    }

    // Update is called once per frame
    void Update()
    {
        //Debug.Log(forwardTarget.name);
        
        Quaternion qua = Quaternion.LookRotation(forwardTarget.transform.position - mainRule.transform.position);
        line.transform.rotation = qua;
        line.transform.position = mainRule.transform.position;
    }
}

于是你会发现,运行游戏,line发生了旋转,它的z轴转向了蓝色的小球,Rotation也发生了变化。之前mainRule是(0,0,0)。Direction是(0,0,0),forwardTarget是(6,0,0)。

理解Quaternion.LookRotation()_第5张图片

所以可以理解到LookRotation的含义,就是本物体z轴对齐forward,y轴对齐upward所需要的旋转四元数。再来一次示例,让forwardtarget坐标是(6,0,6),你会发现,还是蓝轴对着蓝球。

理解Quaternion.LookRotation()_第6张图片

此时Direction的旋转角度是理解Quaternion.LookRotation()_第7张图片 

但是注意MainRule的旋转角不变,因为没让MainRule转理解Quaternion.LookRotation()_第8张图片 

再来一次实验,让绿色的球也就是upward的坐标变成(-6,6,0),绿色的球变成了这样,同时代码里:

Quaternion qua = Quaternion.LookRotation(forwardTarget.transform.position - mainRule.transform.position,upwardTarget.transform.position-mainRule.transform.position);

理解Quaternion.LookRotation()_第9张图片

再次运行游戏:

理解Quaternion.LookRotation()_第10张图片

 我想走到这里,基本就讲清楚了。那么来讲我在实验过程中遇到的问题,这个问题就是自己基础知识不牢固导致的。我刚开始并并没有在cs文件中用GameObject,而是用的transform。是这样写的:

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

public class TestTransform : MonoBehaviour
{
    public Transform forwardTarget;
    public Transform mainRule;
    public Transform line;

    // Start is called before the first frame update
    void Start()
    {
        forwardTarget = transform.Find("ForwardTarget");
        mainRule = transform.Find("MainRule");
        line = transform.Find("Direction");
    }

    // Update is called once per frame
    void Update()
    {
        //Debug.Log(forwardTarget.name);
        Quaternion qua = Quaternion.LookRotation(forwardTarget.position - mainRule.position);
        line.rotation = qua;
        line.position = mainRule.position;

    }
}

在Unity面板中也拖了进去相应的transform

但是运行以后,报错:

意思就是 :对象引用未设置为对象实例。也就是没有实例化一个对象

经过了好久,我终于弄明白了。。。首先来看官方手册https://docs.unity3d.com/ScriptReference/Transform.Find.html

Transform The returned child transform or null if no child is found.

意思就是返回子对象,所以不能直接查找父对象。并且也不能返回孙对象。更重要的是,挂载到相机上是不行的!

transform.Find()只能挂载到本父物体上,查找本父物体的子对象。。。。。

 歇菜。。。。

你可能感兴趣的:(Unity游戏开发)