Unity 3D地图鼠标根据目标点缩放
之前要做一个以鼠标目标点进行Zoom In/Zoom Out的功能,查了一些资料,没查到- 。-所以自己动手写了一个,造福广大和我一样没有找到这种方法的同学,加快工作速度,好好享受生活与学习。
因最近在准备各种杂七杂八的东西,所以物理流体模拟一直没更新,也请谅解~趁着有空写篇小的,也算抒发下最近的一段时间的感慨了~
效果大致如下:
https://www.zhihu.com/video/1586344044770344960
其实,步骤很简单,如果要改变相机位置而鼠标定的远距离目标点不变的话,只需要将摄像机移动以后的目标点的移动的向量反向给相机就可以,简而言之,目标点移动,鼠标点不动,相机相对于反方向运动。
如图所示,分别画了侧视图和正视图,黑色1是远离鼠标的一步,粉色是移回来的那一步。这个方法可以在有俯仰角变换的时候通用。
第一步,在摄像机的高度和俯仰角都没变的时候,发出的一根射线,计算射线打到的物体,也就是图中的兔子的某个点的世界坐标,
float sign = Input.GetAxis("Mouse ScrollWheel");
//perform lowering down Camera
//1.更新相机位置发出射线
Camera.transform.position = temptransform.transform.position;
RaycastHit hit0;
Ray ray0 = Camera.ScreenPointToRay(Input.mousePosition);
Vector3 point0=Vector3.zero;
if (Physics.Raycast(ray0, out hit0, Mathf.Infinity))
{
point0 = hit0.point;
}
目标点远离屏幕鼠标点发出射线检测到的点所在的世界坐标,
第二步,对摄像机做偏移动画,降低高度,俯仰角根据高度改变:
float DiveRatio = Camera.transform.position.y / CameraMaxHeight;
Vector3 temposition = temptransform.transform.position + new Vector3(0, -sign * SensityDive* DiveRatio, 0);
temposition = new Vector3(Mathf.Clamp(temposition.x, CameraXmin, CameraXMax),
Mathf.Clamp(temposition.y, HeightMinimum+0.01f, CameraMaxHeight-0.01f),
Mathf.Clamp(temposition.z, CameraBottomMin, CameraUpMax));
temptransform.transform.position = temposition;
pitchAngle = PitchRotateAnimation();
Camera.transform.rotation = Quaternion.Euler(pitchAngle, rotationY, 0);
Camera.transform.position = temposition;
第三步,再将鼠标的目标点发出射线,检测这个新的鼠标目标的位置。
RaycastHit hit1;
Ray ray1 = Camera.ScreenPointToRay(Input.mousePosition);
Vector3 point1 = Vector3.zero;
if (Physics.Raycast(ray1, out hit1, Mathf.Infinity))
{
point1 = hit1.point;
}
Vector3 direction = point0 - point1;
Vector3 offset = new Vector3(direction.x, 0, direction.z);
这个offset便是要将目标点移到原本的鼠标位置的点的反方向,也就是摄像机应该相对做出的位移
最后更新位置:
Camera.transform.position += offset;
Camera.transform.position = new Vector3(Mathf.Clamp(Camera.transform.position.x, CameraXmin, CameraXMax),
Mathf.Clamp(Camera.transform.position.y, HeightMinimum, CameraMaxHeight),
Mathf.Clamp(Camera.transform.position.z, CameraBottomMin, CameraUpMax));
temptransform.position = Camera.transform.position;
Bingo!
函数如下(大家可以放心忽略temptransform的值赋来赋去,可以直接CameraTransform)
void Zoom()
{
//Get Camera position beforeHeighchange
//Get Camera pitch beforeHeighchange
float pitchAngle1 = Camera.transform.rotation.eulerAngles.x;
float sign = Input.GetAxis("Mouse ScrollWheel");
//perform lowering down Camera
//1.更新相机位置发出射线
Camera.transform.position = temptransform.transform.position;
RaycastHit hit0;
Ray ray0 = Camera.ScreenPointToRay(Input.mousePosition);
Vector3 point0=Vector3.zero;
if (Physics.Raycast(ray0, out hit0, Mathf.Infinity))
{
point0 = hit0.point;
}
Debug.Log("sign" + sign);
float DiveRatio = Camera.transform.position.y / CameraMaxHeight;
Vector3 temposition = temptransform.transform.position + new Vector3(0, -sign * SensityDive* DiveRatio, 0);
temposition = new Vector3(Mathf.Clamp(temposition.x, CameraXmin, CameraXMax),
Mathf.Clamp(temposition.y, HeightMinimum+0.01f, CameraMaxHeight-0.01f),
Mathf.Clamp(temposition.z, CameraBottomMin, CameraUpMax));
// Debug.Log("point0" + point0);
temptransform.transform.position = temposition;
// Debug.Log(point0);
//相机角度
//Get Camera position after Height change
//CameraHeight2 = Camera.transform.position.y;
//2.更新相机位置再发出射线
pitchAngle = PitchRotateAnimation();
Camera.transform.rotation = Quaternion.Euler(pitchAngle, rotationY, 0);
Camera.transform.position = temposition;
//Get Object offsets position after Height change
RaycastHit hit1;
Ray ray1 = Camera.ScreenPointToRay(Input.mousePosition);
Vector3 point1 = Vector3.zero;
if (Physics.Raycast(ray1, out hit1, Mathf.Infinity))
{
point1 = hit1.point;
}
Vector3 direction = point0 - point1;
Vector3 offset = new Vector3(direction.x, 0, direction.z);
// Debug.Log(offset);
//pitchAngle = PitchRotateAnimation();
//Camera.transform.rotation = Quaternion.Euler(pitchAngle, rotationY, 0);
//perform the opposite offset
Camera.transform.position += offset;
Camera.transform.position = new Vector3(Mathf.Clamp(Camera.transform.position.x, CameraXmin, CameraXMax),
Mathf.Clamp(Camera.transform.position.y, HeightMinimum, CameraMaxHeight),
Mathf.Clamp(Camera.transform.position.z, CameraBottomMin, CameraUpMax));
temptransform.position = Camera.transform.position;
}
好了,到此为止~祝大家工作学习愉快
页:
[1]