宿州房地产网站建设/上海广告推广
鼠标滚轮:缩放
鼠标右键:旋转
鼠标中键:平移
鼠标左键:选中实体(下面的代码中未实现)
注:
1.地形必须在Terrain图层下
2.相机上必须挂载Rigidbody+Collider,防止钻到地下。
Rigidbody的Interpolate:Interpolate
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;public class Viewer : MonoBehaviour
{public Texture2D RotateIcon;public Texture2D PanIcon;public Rigidbody rigibodyCamera;public bool IsRecoverCameraForword = false;// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){//鼠标是否在UI上if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject()){return;}//旋转视角if (Input.GetMouseButtonDown(1)){Cursor.SetCursor(RotateIcon, Vector3.zero, CursorMode.Auto);}if (Input.GetMouseButtonUp(1)){Cursor.SetCursor(null, Vector3.zero, CursorMode.Auto);}if (Input.GetMouseButton(1)){Vector3 ptCenter = rigibodyCamera.transform.position - rigibodyCamera.transform.forward * 0.1f;Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hitInfo;LayerMask mask = 1 << (LayerMask.NameToLayer("Terrain"));//鼠标点在地面上,以鼠标点为旋转中心if (Physics.Raycast(ray, out hitInfo, Mathf.Infinity, mask.value)){ptCenter = hitInfo.point;float dist = Vector3.Distance(ptCenter, rigibodyCamera.transform.position);float axis_x = Input.GetAxis("Mouse X");float axis_y = Input.GetAxis("Mouse Y");float radius = 10.0f * dist;//防止相机钻到地面下radius = GetMoveableRadius(radius);if (Mathf.Abs(axis_x) > Mathf.Abs(axis_y)){float drag_x_speed = Mathf.Rad2Deg * (radius / dist);float rotX = axis_x * drag_x_speed * Time.deltaTime;rigibodyCamera.transform.RotateAround(ptCenter, Vector3.up, rotX);}else{float drag_y_speed = Mathf.Rad2Deg * (radius / dist);float rotY = axis_y * drag_y_speed * Time.deltaTime;rigibodyCamera.transform.RotateAround(ptCenter, -rigibodyCamera.transform.right, rotY);}}//鼠标没点在地面上,自由旋转else{float axis_x = Input.GetAxis("Mouse X");float axis_y = Input.GetAxis("Mouse Y");if (Mathf.Abs(axis_x) > Mathf.Abs(axis_y)){float drag_x_speed = 50.0f;float rotX = axis_x * drag_x_speed * Time.deltaTime;rigibodyCamera.transform.RotateAround(ptCenter, Vector3.up, rotX);}else{float drag_y_speed = 30.0f;float rotY = axis_y * drag_y_speed * Time.deltaTime;rigibodyCamera.transform.RotateAround(ptCenter, -rigibodyCamera.transform.right, rotY);}}}//放大if (Input.GetAxis("Mouse ScrollWheel") > 0){ float speed = 50.0f;Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hitInfo;LayerMask mask = 1 << (LayerMask.NameToLayer("Terrain"));if (Physics.Raycast(ray, out hitInfo, Mathf.Infinity, mask.value)){speed = 0.25f * Vector3.Distance(hitInfo.point, ray.origin);}//防止相机钻到地面下speed = GetMoveableRadius(speed);//相机往鼠标点的地方移动Ray ray2 = Camera.main.ScreenPointToRay(Input.mousePosition);rigibodyCamera.MovePosition(rigibodyCamera.position + ray2.direction * speed);}//缩小if (Input.GetAxis("Mouse ScrollWheel") < 0){float speed = 50.0f;Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hitInfo;LayerMask mask = 1 << (LayerMask.NameToLayer("Terrain"));if (Physics.Raycast(ray, out hitInfo, Mathf.Infinity, mask.value)){speed = 0.5f * Vector3.Distance(hitInfo.point, ray.origin);}//防止相机钻到地面下speed = GetMoveableRadius(speed);//相机往鼠标点的地方反方向移动Ray ray2 = Camera.main.ScreenPointToRay(Input.mousePosition);rigibodyCamera.MovePosition(rigibodyCamera.position - ray2.direction * speed);if(IsRecoverCameraForword){RecoverCameraForword();} }//鼠标左键操作 if (Input.GetMouseButtonDown(2)){Cursor.SetCursor(PanIcon, Vector3.zero, CursorMode.Auto);}if (Input.GetMouseButtonUp(2)){Cursor.SetCursor(null, Vector3.zero, CursorMode.Auto);}if (Input.GetMouseButton(2)){float speed = 20.0f;Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hitInfo;LayerMask mask = 1 << (LayerMask.NameToLayer("Terrain"));if (Physics.Raycast(ray, out hitInfo, Mathf.Infinity, mask.value)){speed = 0.05f * Vector3.Distance(hitInfo.point, ray.origin);}speed = GetMoveableRadius(speed);float x_mouse = -Input.GetAxis("Mouse X");float y_mouse = -Input.GetAxis("Mouse Y");float angle = Vector3.Angle(Camera.main.transform.forward, Vector3.down);if(angle < 5){Vector3 vecTemp = Vector3.zero;vecTemp += speed * x_mouse * Camera.main.transform.right;vecTemp += 0.4f * speed * y_mouse * Camera.main.transform.up;//防止相机钻到地面下float len = GetMoveableRadius(vecTemp.magnitude);rigibodyCamera.MovePosition(rigibodyCamera.position + vecTemp.normalized * len);}else{Vector3 vecTemp = Vector3.zero;Vector3 dir = Vector3.ProjectOnPlane(Camera.main.transform.forward, Vector3.up);vecTemp += speed * x_mouse * Camera.main.transform.right;vecTemp += speed * y_mouse * dir.normalized;//防止相机钻到地面下float len = GetMoveableRadius(vecTemp.magnitude);rigibodyCamera.MovePosition(rigibodyCamera.position + vecTemp.normalized * len);}}}//计算可移动距离private float GetMoveableRadius(float radius){int i = 0;while (true){i++;if (i > 50){radius = 0.0f;break;}if (IsHaveCollider(Camera.main.transform.position, radius)){radius = 0.5f * radius;}else{break;}}return radius;}//判断某个点,一定距离内有无碰撞物,-1为小于最小距离,0为位于两个距离内,1为大于最大距离bool IsHaveCollider(Vector3 ptCenter, float radius1){Collider[] collider1 = Physics.OverlapSphere(ptCenter, radius1);if (collider1.Length > 1){return true;}return false;}//慢慢将相机朝下void RecoverCameraForword(){Quaternion lodRotatiton = rigibodyCamera.transform.rotation;lodRotatiton.SetLookRotation(Vector3.down, Vector3.forward);Quaternion rot = Quaternion.Lerp(rigibodyCamera.transform.rotation, lodRotatiton, 0.08f);rigibodyCamera.MoveRotation(rot);}
}