类似这些函数,这个坐标,那个坐标,什么旋转,四元数一直是我比较头疼的东西,但是既然坑已然挖到这里了。不填也不行了。先理解一下这个函数,首先来看Unity Manual------https://docs.unity3d.com/ScriptReference/Quaternion.LookRotation.html
public static Quaternion LookRotation(Vector3 forward, Vector3 upwards = Vector3.up);
forward | The direction to look in. |
upwards | The vector that defines in which direction up is. |
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
-----------------------------------------------------------------------------------------------------------------------------------------------
于是我参照上面的博客,做了一个方向盘,截图如下:
因为那篇博客的作者没有给出这个小测试项目的做法,这里我给出我猜测的做法。在做的过程中我还遇到了一点小问题,我要把这个问题的解决方法也记载下来。
首先Main Camera和Directional Light系统自带,我就不说了。
MainRule是个小Cube,在Hierarchy面板下点击Create-->3D Object-->cube就行,我把Scale缩小了一下,Inspector面板如下:
然后蓝色的球和绿色的球,就是Sphere,蓝色代表z方向,绿色代表y方向,和 一样。球的创建方法和cube一样,绿色的是UpwardTarget,蓝色的是ForwardTarget。Inspector面板如下。球的颜色的话,直接拖动有颜色的图片到这个球上面去就行,自动创建Material:
下面就是那几根平衡板了。用什么都行,我还是用的Sphere,然后把它拽扁了,插到cube中。短头的当正方向。Direction是一个空物体,x,y,z也是空物体,其中一个拉扁的Sphere(x轴)的Inspector如下,位置可根据情景调整:
然后在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)。
所以可以理解到LookRotation的含义,就是本物体z轴对齐forward,y轴对齐upward所需要的旋转四元数。再来一次示例,让forwardtarget坐标是(6,0,6),你会发现,还是蓝轴对着蓝球。
但是注意MainRule的旋转角不变,因为没让MainRule转
再来一次实验,让绿色的球也就是upward的坐标变成(-6,6,0),绿色的球变成了这样,同时代码里:
Quaternion qua = Quaternion.LookRotation(forwardTarget.transform.position - mainRule.transform.position,upwardTarget.transform.position-mainRule.transform.position);
再次运行游戏:
我想走到这里,基本就讲清楚了。那么来讲我在实验过程中遇到的问题,这个问题就是自己基础知识不牢固导致的。我刚开始并并没有在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;
}
}
但是运行以后,报错:
意思就是 :对象引用未设置为对象实例。也就是没有实例化一个对象
经过了好久,我终于弄明白了。。。首先来看官方手册https://docs.unity3d.com/ScriptReference/Transform.Find.html
Transform The returned child transform or null if no child is found.
意思就是返回子对象,所以不能直接查找父对象。并且也不能返回孙对象。更重要的是,挂载到相机上是不行的!
transform.Find()只能挂载到本父物体上,查找本父物体的子对象。。。。。
歇菜。。。。