花了一天时间琢磨这个,看网上的解决办法。。没几个彻底解决的。。。都是说什么方法复杂。。让我们自己去看视频教程。。!!!!
感觉跟没有回答一样。。。。自己也是很多方法都试了。。不是有这种问题,就是那种问题。。。。。。烦!!!最后自己琢磨出这个不是办法的办法。。。。。。
虽然没有用到什么高深的东西,复杂的算法。。。。但是自己花时间琢磨的。亲测效果还过得去。注意有三个版本(全当学习过程了),最后版本为最简单最完美的.
using UnityEngine;
using System.Collections; public class CameraFollow : MonoBehaviour { public float V_upAngle; // 屏幕从z轴向上抬的高度的限制 public float V_downAngle; //屏幕从z轴向下低头的限制 public float H_Angle; //屏幕左右旋转的最大角度的限制。绕y轴 public float smooth; // how smooth the camera movement is public float distance_obj; public float distance_h; public Transform targe_position; //player private Vector3 mouse_point; private float screen_w; //屏幕信息 private float screen_h; private float H_unit_rotation; //鼠标在屏幕移动距离投射到三维世界的角度旋转单位大小 private float V_up_unit_rotation; private float V_down_unit_rotation; private Vector3 screen_center; private Quaternion center_rotation; //最终旋转结果 private Quaternion current_rotation_H; //水平旋转结果 private Quaternion current_rotation_V; //垂直旋转结果 void Start() { center_rotation = new Quaternion(); center_rotation=transform.rotation; FixedUpdate(); } void LateUpdate()//利用欧拉角旋转相机 { transform.rotation = center_rotation; mouse_point = Input.mousePosition; current_rotation_V = Quaternion.AngleAxis((mouse_point.x - screen_center.x) * H_unit_rotation, Vector3.up); if (mouse_point.y >= screen_center.y) { current_rotation_H = Quaternion.AngleAxis((mouse_point.y - screen_center.y) * V_up_unit_rotation, Vector3.left); } if (mouse_point.y < screen_center.y) { current_rotation_H = Quaternion.AngleAxis((mouse_point.y - screen_center.y) * V_down_unit_rotation, Vector3.left); } //move transform.rotation =current_rotation_V*current_rotation_H; //利用向量叉乘得到最终效果。。。注意顺序不能改变(不满足交换律); transform.position=(targe_position.position + Vector3.up * distance_h - Vector3.forward * distance_obj); } private void FixedUpdate() { screen_w = Screen.width; screen_h = Screen.height; screen_center = new Vector3(screen_w / 2, screen_h / 2, 0); //参考点。决定视角往那一边旋转 H_unit_rotation =H_Angle/ screen_w; V_up_unit_rotation = V_upAngle / screen_h / 2; V_down_unit_rotation = V_downAngle / screen_h / 2; }}
///
///
///这是后面改良版,加入了以目标为视野焦点的旋转。
using UnityEngine; using System.Collections; public class CameraFollow : MonoBehaviour { public float distance_v; public float distance_h; public float H_unit_rotation; //鼠标在屏幕移动距离投射到三维世界的角度旋转单位大小 public float V_unit_rotation; public float max_up_angle=320; //越小,头抬得越高 public float max_down_angle=50; //越大,头抬得越低 public Transform targe_position; //player private Vector3 mouse_point; private Quaternion previous_rotation; private Vector3 mouse_start_pos; private Quaternion current_rotation_H; //垂直旋转结果 private Quaternion current_rotation_V; //水平旋转结果 void Start() { mouse_start_pos = Input.mousePosition; previous_rotation = transform.rotation; } private void Update() //改变旋转 { mouse_point = Input.mousePosition; transform.rotation = previous_rotation; if (mouse_point == mouse_start_pos) return; ///每次旋转是以世界坐标为参考 if (mouse_point.x != mouse_start_pos.x) //水平旋转 { current_rotation_V = Quaternion.AngleAxis((mouse_point.x - mouse_start_pos.x) * H_unit_rotation, Vector3.up); } if (mouse_point.y!=mouse_start_pos.y) //垂直旋转 { current_rotation_H = Quaternion.AngleAxis((mouse_point.y - mouse_start_pos.y) * V_unit_rotation, Vector3.left); } //rotation,向量叉乘得到组合效果 transform.rotation*=(current_rotation_V*current_rotation_H); //利用向量叉乘得到最终效果。。。注意顺序不能改变(不满足交换律); mouse_start_pos = mouse_point; float angle_x = transform.rotation.eulerAngles.x; //200只是区别是抬头还是低头,因为欧拉角的性质 if (angle_x<=max_up_angle&&angle_x>200) //往上抬头 { transform.rotation = Quaternion.Euler( new Vector3(max_up_angle, transform.rotation.eulerAngles.y, 0f)); } if(angle_x>=max_down_angle&&angle_x<200) { //低头 transform.rotation = Quaternion.Euler( new Vector3(max_down_angle, transform.rotation.eulerAngles.y, 0f)); } transform.rotation=Quaternion.Euler( new Vector3(transform.rotation.eulerAngles.x,transform.rotation.eulerAngles.y,0f)); //阻止相机绕z轴旋转(会让视野倾斜) previous_rotation = transform.rotation; } void LateUpdate() //改变位置 { transform.position = targe_position.position; transform.Translate(Vector3.back * distance_h, Space.Self); transform.Translate(Vector3.up * distance_v, Space.World); //相对于世界坐标y轴向上 } }
///
最终版
using UnityEngine; using System.Collections; public class CameraController : MonoBehaviour { public float distance_v; public float distance_h; public float rotation_H_speed=1; public float rotation_V_speed=1; public float max_up_angle = 80; //越大,头抬得越高 public float max_down_angle =-60; //越小,头抬得越低 public Transform follow_obj; //player private float current_rotation_H; //水平旋转结果 private float current_rotation_V; //垂直旋转结果 void LateUpdate() { //控制旋转 current_rotation_H+= Input.GetAxis("Mouse X")*rotation_H_speed; current_rotation_V += Input.GetAxis("Mouse Y")*rotation_V_speed; current_rotation_V=Mathf.Clamp(current_rotation_V, max_down_angle, max_up_angle); //限制垂直旋转角度 transform.localEulerAngles = new Vector3(-current_rotation_V,current_rotation_H,0f); //改变位置,以跟踪的目标为视野中心,且视野中心总是面向follow_obj transform.position =follow_obj.position; transform.Translate(Vector3.back * distance_h, Space.Self); transform.Translate(Vector3.up * distance_v, Space.World); //相对于世界坐标y轴向上 } }