Unity3d中摄像机控制脚本实现

/-------------------------------------------------------------
// 摄像机功能
// 鼠标左键按住,上下左右滑动,控制摄像机观察的位置
// 鼠标右键没做设定,因为WebPlayer里点鼠标右键是浏览器事件
// 鼠标滚轮滚动,调整摄像机与被看点的距离
//--------------------------------------------------------------
//获得场景主角的对象
var MainRole : GameObject;
//摄像机的观察点设置为头部上方的Cube
private var LookAtPoint: Transform;
//观察点的旋转四元数
private var LooAtPointQuaternion;
//摄像机与观察点的距离
var distance = 50.0;
var minidistance = 30;
var maxidistance = 70;
//摄像机的高度,可以不用
//var height = 5.0;
//摄像机距离调整系数
var distanceAdjust = 10;
//旋转、俯仰调整系数
var rotationYAdjust = 10.0;
var rotationXAdjust = 10.0;
//摄像机高度调整系数
var heightAdjust = 1.0;
//观察点Y轴的旋转系数(调整旋转)
var yQuaternion uaternion;
var rotationY = 0F;
var minimumY = -360F;
var maximumY = 360F;
//观察点X轴的旋转系数(调整俯仰)
var xQuaternion uaternion;
var rotationX = 0F;
var minimumX = -75F;
var maximumX = 75F;
var currentRotationAngle = 0F;
var wantedRotationAngle = 0F;
// Place the script in the Camera-Control group in the component menu
@script AddComponentMenu("Camera-Control/Smooth Follow")
function Awake()
{
MainRole = GameObject.Find(" layer_Man_1");
LookAtPoint = MainRole.transform.Find("Cube_LookAtPoint_WhenUnderBody");
}
function LateUpdate () {
if (!LookAtPoint)
return;
//鼠标左键控制摄像机的上下左右转动,以观察玩家角色
//计算摄像机需要绕观察点坐标系的各个轴的角度值
if(Input.GetMouseButton(0))
{
//旋转计算-----------绕观察点的Y轴
rotationY += Input.GetAxis("Mouse X") * rotationYAdjust ;
rotationY = ClampAngleY(rotationY, minimumY, maximumY);
yQuaternion = Quaternion.AngleAxis(rotationY, LookAtPoint.up);
//俯仰计算-----------绕观察点的X轴
rotationX += Input.GetAxis("Mouse Y") * rotationXAdjust ;
rotationX = ClampAngleX(rotationX, minimumX, maximumX);
xQuaternion = Quaternion.AngleAxis(rotationX, LookAtPoint.right);
}
//计算摄像机距离
var distanceDelta = Input.GetAxis("Mouse ScrollWheel");
distance += -distanceDelta * distanceAdjust;
distance = Mathf.Clamp(distance, minidistance, maxidistance);
//注意四元数的乘法顺序, unity3d 的四元数与向量可以直接乘,结果为一个向量
//这里的理解跟D3D不同,可以把Q*V理解为“V向量被四元数Q给改变了”,unity3d中,四元数必须作为左操作数才能与向量相乘,详情看Quaternion重载的*符号操作
//将摄像机坐标系与观察点坐标系相重合
transform.position = LookAtPoint.position;
transform.rotation = LookAtPoint.rotation;
//将摄像机在世界坐标系下进行旋转
var cameraRotationW = Quaternion.Euler (rotationX, rotationY + LookAtPoint.eulerAngles.y, 0);
//沿着摄像机Z轴方向的反方向向后拉摄像机,使其与观察点距离相距distance
transform.position += cameraRotationW * Vector3(0.0, 0.0, -distance);
// 如果低于主角的高度,就设置为主角的高度,+1 是为了不让摄像机看到地面以下
if (transform.position.y {
transform.position.y = MainRole.transform.position.y+heightAdjust;
}
// 让摄像机器最终对准观察点
transform.LookAt (LookAtPoint);
}
function ClampAngleY(angle, min, max)
{
if (angle < min) angle += max; if (angle > max)
angle -= max;
return Mathf.Clamp(angle, min, max);
}
function ClampAngleX(angle, min, max)
{
if (angle = max)
angle = max;
return Mathf.Clamp(angle, min, max);
}
经验总结:
1.Unity3D中,四元数也不支持交换率,谁先乘谁后乘会影响最终结果。
2.Unity3D中,四元数操作重载了* 操作符,使得四元数可以和向量相乘,但此时四元数必须作为左操作数。
3.变换过程中不能简单把四元数理解为旋转矩阵,Q*V倒是可以简单的理解为“向量V被Q给影响了,旋转到了Q的坐标系下”。
4.同时要密切注意坐标系的统一。
5.Unity3D中,介于第一点和第三点的总结,最简单安全直接的办法是先把坐标系统一一下,然后在一个坐标系下算出总的旋转角度,用 Quaternion.Euler算出总的四元数,然后用这个四元数进行变换。
6.尽量用一个四元数进行变换,多个四元数相乘计算会因为U3D的计算精度很高的原因,计算出一个非常小的误差,但是这个误差还是会对画面产生巨大影响。

你可能感兴趣的:(Unity3d)