本文原创,转载请注明出处:http://www.cnblogs.com/AdvancePikachu/p/6856374.html
首先,总结了下最近工作中关于摄像机漫游的功能,
脚本如下:
Transform _Camera; public LayerMask mask; public float checkHeight = 500f; public float minHeight = 20f; public float maxHeight = 8000f; public float minClamp = 50f; public float maxClamp = 950f; public float sensitivityX = 5f; public float sensitivityY = 5f; private float rotationY = 0f; //上下最大Y视角 public float minimumY = -90f; public float maximumY = 30f; public Vector3 PreMouseMPos; public float scrollSpeed = 200f; void Start () { mask.value = 1; _Camera = Camera.main.transform; } // Update is called once per frame void Update () { if(Input.GetKey(KeyCode.LeftAlt)) { MouseScrollWheel (); CameraMove (); MoveEulerAngles (); } } /// <summary> /// Checks the height of the low. /// </summary> void CheckLowHeight() { if (_Camera.position.x < minClamp) _Camera.position = new Vector3 (minClamp, _Camera.position.y, _Camera.position.z); if (_Camera.position.x > maxClamp) _Camera.position = new Vector3 (maxClamp, _Camera.position.y, _Camera.position.z); if (_Camera.position.z < minClamp) _Camera.position = new Vector3 (_Camera.position.x, _Camera.position.y, minClamp); if (_Camera.position.z > maxClamp) _Camera.position = new Vector3 (_Camera.position.x, _Camera.position.y, maxClamp); RaycastHit hit; if(Physics.Raycast(_Camera.position+Vector3.up*checkHeight,Vector3.down,out hit ,checkHeight+minHeight,mask)) { if(_Camera.position.y-hit.point.y<minClamp) { Vector3 lowPoint = hit.point + new Vector3 (0, minHeight, 0); _Camera.position = lowPoint; } } } /// <summary> /// Mouses the scroll wheel. /// </summary> private void MouseScrollWheel() { if(Input.GetAxis("Mouse ScrollWheel")!=0) { _Camera.Translate (new Vector3 (0, 0, Input.GetAxis ("Mouse ScrollWheel") * Time.deltaTime * scrollSpeed)); } CheckLowHeight (); if (_Camera.position.y >= maxHeight) _Camera.position = new Vector3 (_Camera.position.x, maxHeight, _Camera.position.z); } /// <summary> /// Cameras the move. /// </summary> private void CameraMove() { if(Input.GetMouseButton(0)) { if(PreMouseMPos.x<=0) { PreMouseMPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, 0); } else { Vector3 CurMouseMPos = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, 0); Vector3 offset = CurMouseMPos - PreMouseMPos; offset = -offset * 0.5f * 2; if((_Camera.position+offset).y>=minHeight &&(_Camera.position+offset).y<=maxHeight) { _Camera.Translate(offset); CheckLowHeight(); PreMouseMPos = CurMouseMPos; } } } else PreMouseMPos = Vector3.zero; } /// <summary> /// Moves the euler angles. /// </summary> private void MoveEulerAngles() { if(Input.GetMouseButton(1)) { float rotationX = _Camera.localEulerAngles.y + Input.GetAxis ("Mouse X") * sensitivityX; rotationY += Input.GetAxis ("Mouse Y") * sensitivityY; rotationY = Mathf.Clamp (rotationY, minimumY, maximumY); _Camera.localEulerAngles = new Vector3 (-rotationY, rotationX, 0); } }
第二个是关于摄像机的限制范围和遇到障碍物自动变换与target的距离的功能
代码如下:
public Transform target; public LayerMask mask = new LayerMask(); public Vector2 targetOffset = new Vector2(); public Vector2 originRotation = new Vector2(); public float distance = 5; public float minDistance = 0; public float maxDistance = 10; public Vector2 sensitivity = new Vector2(3, 3); public float zoomSpeed = 1; public float zoomSmoothing = 16; public float minAngle = -90; public float maxAngle = 90; private float _zoom_in_timer = 0; private float _zoom_out_timer = 0; private float _wanted_distance; private Quaternion _rotation; private Vector2 _input_rotation; private Transform _t; void Start() { mask.value = 1; _t = transform; _wanted_distance = distance; _input_rotation = originRotation; 41 } void Update() { if (target) { if (Input.GetMouseButton (0) || Input.GetMouseButton (1)) { if (Input.GetAxis ("Mouse X") != 0 || Input.GetAxis ("Mouse Y") != 0) { if (!Cursor.visible) { Cursor.visible = false; Cursor.lockState = CursorLockMode.Locked; } } return; } } if (!Cursor.visible) { Cursor.visible = true; Cursor.lockState = CursorLockMode.None; } } void FixedUpdate() { if(target) { // Zoom control if(Input.GetAxis("Mouse ScrollWheel") < 0 ) { _wanted_distance += zoomSpeed; } else if(Input.GetAxis("Mouse ScrollWheel") > 0 ) { _wanted_distance -= zoomSpeed; } _wanted_distance = Mathf.Clamp(_wanted_distance, minDistance, maxDistance); if (Input.GetMouseButton (0) || Input.GetMouseButton (1)) { _input_rotation.x += Input.GetAxis ("Mouse X") * sensitivity.x; ClampRotation (); _input_rotation.y -= Input.GetAxis ("Mouse Y") * sensitivity.y; _input_rotation.y = Mathf.Clamp (_input_rotation.y, minAngle, maxAngle); _rotation = Quaternion.Euler (_input_rotation.y, _input_rotation.x, 0); } // Lerp from current distance to wanted distance distance = Mathf.Clamp(Mathf.Lerp(distance, _wanted_distance, Time.deltaTime * zoomSmoothing), minDistance, maxDistance); // Set wanted position based off rotation and distance Vector3 wanted_position = _rotation * new Vector3(targetOffset.x, 0, -_wanted_distance - 0.2f) + target.position + new Vector3(0, targetOffset.y, 0); Vector3 current_position = _rotation * new Vector3(targetOffset.x, 0, 0) + target.position + new Vector3(0, targetOffset.y, 0); // Linecast to test if there are objects between the camera and the target using collision layers RaycastHit hit; if(Physics.Linecast(current_position, wanted_position, out hit, mask)) { distance = Vector3.Distance(current_position, hit.point) - 0.2f; } // Set the position and rotation of the camera _t.position = _rotation * new Vector3(targetOffset.x, 0.0f, -distance) + target.position + new Vector3(0, targetOffset.y, 0); _t.rotation = _rotation; } } private void ClampRotation() { if(originRotation.x < -180) { originRotation.x += 360; } else if(originRotation.x > 180) { originRotation.x -= 360; } if(_input_rotation.x - originRotation.x < -180) { _input_rotation.x += 360; } else if(_input_rotation.x - originRotation.x > 180) { _input_rotation.x -= 360; } }
你有什么资格不努力!——进击的皮卡丘