公司准备做二期的项目,自己给项目的一些需求提前先做一些记录,自己拿了一期项目(别人写的)的源代码看了一下,对于一期项目摄像机控制并不是满意,然后自己对比一下某网站操作方式做了修改,代码基本参考网上的代码。主要功能就是左键旋转,右键平移,滚轮缩进远离。
参考一:
这里主要是修改滚轮缩进远离其它代码基本没有改动。
参考二:
这里代码右键上下拖动并不是上下视角主要是坐标y没有变动,变动的是左边z,修改组合之后就成了完整的操作方式。
基本上代码的注释都非常详尽,其他细节的代码方法请查阅api
具体代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class mousedrag : MonoBehaviour
{
//旋转速度,需要调试
public float xSpeed = 130.0f;
public float ySpeed = 130.0f;
//限制旋转角度,物体绕x轴旋转限制,不能上下颠倒。
public float yMinLimit = -30;
public float yMaxLimit = 30;
//物体的旋转角度
public float x = 0.0f;
public float y = 0.0f;
// 设置相机移动速度
public float moveSpeed = 10;
void Start()
{
//初始化旋转角度,记录开始时物体的旋转角度。
Vector3 angels = transform.eulerAngles;
x = angels.y;
y = angels.x;
//
}
void Update()
{
// 当按住鼠标右键的时候
if (Input.GetMouseButton(1))
{
// 获取鼠标的x和y的值,乘以速度和Time.deltaTime是因为这个可以是运动起来更平滑
float h = Input.GetAxis("Mouse X") * -moveSpeed * Time.deltaTime;
float v = Input.GetAxis("Mouse Y") * -moveSpeed * Time.deltaTime;
// 设置当前摄像机移动,y轴并不改变
// 需要摄像机按照世界坐标移动,而不是按照它自身的坐标移动,所以加上Spance.World
this.transform.Translate(h, v, 0, Space.World);
}
if (Input.GetMouseButton(0))
{
//鼠标沿x轴的移动乘以系数当作物体绕y轴的旋转角度。
//鼠标沿y轴的移动乘以系数当作物体绕x轴的旋转角度。
x += Input.GetAxis("Mouse X") * xSpeed * Time.deltaTime;
y += Input.GetAxis("Mouse Y") * ySpeed * Time.deltaTime;
}
Camera.main.fieldOfView = Camera.main.fieldOfView - Input.GetAxis("Mouse ScrollWheel") * 20;
}
void LateUpdate()
{
//限制绕x轴的移动。
y = Mathf.Clamp(y, yMinLimit, yMaxLimit);
Quaternion rotation = Quaternion.Euler(y, -x, 0);
transform.rotation = rotation;
}
}
脚本挂在摄像机上,运行一下发现ok,调一下xspeed数值完成。暂时不考虑一些最大范围和最小范围的限制就这样。
编辑:
因为客户觉得之前摄像机控制不好用,所以做了一堆修改,不使用上下左右键移动以及添加旋转摄像机功能,主要代码如下:
/// <summary>
/// 滚轮控制摄像机缩放
/// </summary>
private void WheelContrl()
{
float distance = 0;
distance = Input.GetAxis("Mouse ScrollWheel") * moveSpeed_s;//获取鼠标中建响应
transform.position = transform.position + transform.rotation *new Vector3(0, 0, distance);
// //滚轮控制
// if (Input.GetAxis("Mouse ScrollWheel") < 0)
// {
// //控制的范围自行调整
// if (Camera.main.fieldOfView <= 100)
// {
// Camera.main.fieldOfView += 2;
// }
// if (Camera.main.orthographicSize <= 20)
// {
// Camera.main.orthographicSize += 0.5F;
// }
// }
// if (Input.GetAxis("Mouse ScrollWheel") > 0)
// {
// if (Camera.main.fieldOfView > 20
//)
// {
// Camera.main.fieldOfView -= 2;
// }
// if (Camera.main.orthographicSize >= 1)
// {
// Camera.main.orthographicSize -= 0.5F;
// }
// }
}
void RotateCamera()
{
//鼠标左键按下状态启用旋转摄像机
if (Input.GetMouseButtonDown(0))
{
isRotate = true;
}
//鼠标左键抬起状态停止旋转摄像机
if (Input.GetMouseButtonUp(0))
{
isRotate = false;
}
if (!EventSystem.current.IsPointerOverGameObject())
{
if (isRotate)
{
//x 和 y 是绝对值 相对于世界坐标没有转动的位置的最终转动位置
//鼠标的上下移动 移动的Y值 在三维中相当于沿X轴转动
y -= Input.GetAxis("Mouse Y") * moveSpeed_y * Time.deltaTime;
//上下需要限定范围 在完全俯视 和 完全仰视之间
//去掉该限制的话可以使摄像机倒置
y = Mathf.Clamp(y, yMinLimit, yMaxLimit);
//鼠标的左右移动 移动的X值 在三维中相当于沿Y轴转动
//左右是允许360度旋转的 不需要限制到最大最小范围
x += Input.GetAxis("Mouse X") * moveSpeed_x * Time.deltaTime;
//Quaternion rotation = Quaternion.Euler(y, x, 0);
//transform.rotation = rotation;
//和上面2句等价
transform.eulerAngles = new Vector3(y, x, 0);
}
}
}
因为放大缩小客户一直觉得视角变形了,所以做了修改,完整代码包含之前的功能,完整代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class CameraContrl : MonoBehaviour
{
/// <summary>
/// 摄像机X轴 Z轴的坐标的临界点
/// </summary>
public float Z_min;
public float Z_max;
public float X_min;
public float X_max;
public float Y_min;
public float Y_max;
//主摄像机起始坐标
private Vector3 StartPos;
//主摄像机缩放参数
private float StartFieldOfView;
private Vector3 StartRotation;
//[SerializeField]
//private Slider SpeedSlider;
// 设置相机移动速度 ,测试最大速度30
public float moveSpeed_x;//X轴的移动速度
public float moveSpeed_y;//Y轴的移动速度
public float moveSpeed_s;//鼠标滑动到边界摄像机的移动速度
public float yMinLimit = -90f; //上下旋转摄像机的最小角度限制
public float yMaxLimit = 90f; //上下旋转摄像机的最大角度限制
//是否旋转镜头 鼠标右键按下时启用
private bool isRotate;
//左右旋转的角度 相对世界原始位置 非transform初始位置(沿三维Y轴)
private float x;
//上下旋转的角度 相对世界原始位置 非transform初始位置(沿三维X轴)
private float y;
public float Min = 0.05f;
private void Awake()
{
//SpeedSlider = GameObject.Find("SettingPanel/SpeedSlider").GetComponent<Slider>();
StartPos = Camera.main.transform.position;
StartFieldOfView = Camera.main.fieldOfView;
StartRotation = Camera.main.transform.eulerAngles;
Vector3 angles = transform.eulerAngles;
//鼠标的左右移动 在三维中相当于沿Y轴转动
x = angles.y;
//鼠标的上下移动 在三维中相当于沿X轴转动
y = angles.x;
}
// Update is called once per frame
void LateUpdate()
{
Boundary();
WheelContrl();
RotateCamera();
DragScreen();
//CodeControl();
//MouseControl();
if (Input.GetKeyDown(KeyCode.F5))
{
ResetPos();
}
}
/// <summary>
/// 摄像机移动边界设定
/// </summary>
public void Boundary()
{
Vector3 pos = Camera.main.transform.localPosition;
Camera.main.transform.localPosition = new Vector3(Mathf.Clamp(pos.x, X_min, X_max), Mathf.Clamp(pos.y, Y_min, Y_max), Mathf.Clamp(pos.z, Z_min, Z_max));
}
/// <summary>
/// 重置摄像机位置
/// </summary>
private void ResetPos()
{
Camera.main.transform.position = StartPos;
Camera.main.transform.eulerAngles = StartRotation;
Camera.main.fieldOfView = StartFieldOfView;
}
/// <summary>
/// 滚轮控制摄像机缩放
/// </summary>
private void WheelContrl()
{
float distance = 0;
distance = Input.GetAxis("Mouse ScrollWheel") * moveSpeed_s;//获取鼠标中建响应
transform.position = transform.position + transform.rotation *new Vector3(0, 0, distance);
// //滚轮控制
// if (Input.GetAxis("Mouse ScrollWheel") < 0)
// {
// //控制的范围自行调整
// if (Camera.main.fieldOfView <= 100)
// {
// Camera.main.fieldOfView += 2;
// }
// if (Camera.main.orthographicSize <= 20)
// {
// Camera.main.orthographicSize += 0.5F;
// }
// }
// if (Input.GetAxis("Mouse ScrollWheel") > 0)
// {
// if (Camera.main.fieldOfView > 20
//)
// {
// Camera.main.fieldOfView -= 2;
// }
// if (Camera.main.orthographicSize >= 1)
// {
// Camera.main.orthographicSize -= 0.5F;
// }
// }
}
void RotateCamera()
{
//鼠标左键按下状态启用旋转摄像机
if (Input.GetMouseButtonDown(0))
{
isRotate = true;
}
//鼠标左键抬起状态停止旋转摄像机
if (Input.GetMouseButtonUp(0))
{
isRotate = false;
}
if (!EventSystem.current.IsPointerOverGameObject())
{
if (isRotate)
{
//x 和 y 是绝对值 相对于世界坐标没有转动的位置的最终转动位置
//鼠标的上下移动 移动的Y值 在三维中相当于沿X轴转动
y -= Input.GetAxis("Mouse Y") * moveSpeed_y * Time.deltaTime;
//上下需要限定范围 在完全俯视 和 完全仰视之间
//去掉该限制的话可以使摄像机倒置
y = Mathf.Clamp(y, yMinLimit, yMaxLimit);
//鼠标的左右移动 移动的X值 在三维中相当于沿Y轴转动
//左右是允许360度旋转的 不需要限制到最大最小范围
x += Input.GetAxis("Mouse X") * moveSpeed_x * Time.deltaTime;
//Quaternion rotation = Quaternion.Euler(y, x, 0);
//transform.rotation = rotation;
//和上面2句等价
transform.eulerAngles = new Vector3(y, x, 0);
}
}
}
/// <summary>
/// 鼠标右键拖拽移动上下左右视角
/// </summary>
private void DragScreen()
{
// 当按住鼠标右键的时候
if (Input.GetMouseButton(1))
{
// 获取鼠标的x和y的值,乘以速度和Time.deltaTime是因为这个可以是运动起来更平滑
float h = Input.GetAxis("Mouse X") * moveSpeed_s * Time.deltaTime;
float v = Input.GetAxis("Mouse Y") * moveSpeed_s * Time.deltaTime;
// 设置当前摄像机移动,y轴并不改变
// 需要摄像机按照世界坐标移动,而不是按照它自身的坐标移动,所以加上Spance.World
Camera.main.transform.Translate(-h, 0, -v, Space.World);
}
}
/// <summary>
/// 实时更新摄像机速度值
/// </summary>
public void GetSpeed(float value)
{
//moveSpeed_x = value*50;
}
/// <summary>
/// 按键控制摄像机移动
/// </summary>
private void CodeControl()
{
//float h = Mathf.Clamp()
float h = Input.GetAxisRaw("Horizontal") * moveSpeed_x * Time.deltaTime;
float v = Input.GetAxisRaw("Vertical") * moveSpeed_y * Time.deltaTime;
Camera.main.transform.Translate(h, 0, v, Space.World);
}
/// <summary>
/// 鼠标放在屏幕边缘移动摄像机
/// </summary>
private void MouseControl()
{
Vector3 v1 = Camera.main.ScreenToViewportPoint(Input.mousePosition);
//移到ui上不触发
if (EventSystem.current.IsPointerOverGameObject())
{
return;
}
//范围限制
if (v1.x > 1 + Min || v1.x < -Min || v1.y > 1 + Min || v1.y < -Min) return;
if (v1.x < Min)//鼠标停靠在左边
{
transform.Translate(Vector3.left * moveSpeed_s * Time.deltaTime, Space.World);
}
if (v1.x > 1 - Min)//鼠标停靠在右边
{
transform.Translate(Vector3.right * moveSpeed_s * Time.deltaTime, Space.World);
}
if (v1.y < Min)//鼠标停靠在下边
{
transform.Translate(Vector3.back * moveSpeed_s * Time.deltaTime, Space.World);
}
if (v1.y > 1 - Min)//鼠标停靠在上边
{
transform.Translate(Vector3.forward * moveSpeed_s * Time.deltaTime, Space.World);
}
}
}
今天测试摄像机发现旋转之后位置移动就错误了重新做了修改,完整代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class CameraContrl : MonoBehaviour
{
/// <summary>
/// 摄像机X轴 Z轴的坐标的临界点
/// </summary>
public float Z_min;
public float Z_max;
public float X_min;
public float X_max;
public float Y_min;
public float Y_max;
//主摄像机起始坐标
private Vector3 StartPos;
//主摄像机缩放参数
private float StartFieldOfView;
private Vector3 StartRotation;
private Vector3 cameraPos;
//[SerializeField]
//private Slider SpeedSlider;
// 设置相机移动速度 ,测试最大速度30
public float moveSpeed_x;//X轴的移动速度
public float moveSpeed_y;//Y轴的移动速度
public float moveSpeed_s;//鼠标滑动到边界摄像机的移动速度
public float yMinLimit = -90f; //上下旋转摄像机的最小角度限制
public float yMaxLimit = 90f; //上下旋转摄像机的最大角度限制
//是否旋转镜头 鼠标右键按下时启用
private bool isRotate;
//左右旋转的角度 相对世界原始位置 非transform初始位置(沿三维Y轴)
private float x;
//上下旋转的角度 相对世界原始位置 非transform初始位置(沿三维X轴)
private float y;
public float Min = 0.05f;
private void Awake()
{
//SpeedSlider = GameObject.Find("SettingPanel/SpeedSlider").GetComponent<Slider>();
StartPos = Camera.main.transform.position;
cameraPos = Camera.main.transform.position;
StartFieldOfView = Camera.main.fieldOfView;
StartRotation = Camera.main.transform.eulerAngles;
Vector3 angles = transform.eulerAngles;
//鼠标的左右移动 在三维中相当于沿Y轴转动
x = angles.y;
//鼠标的上下移动 在三维中相当于沿X轴转动
y = angles.x;
}
// Update is called once per frame
void LateUpdate()
{
if (EventSystem.current.IsPointerOverGameObject()) return;
Boundary();
WheelContrl();
RotateCamera();
DragScreen();
transform.position = cameraPos;
//CodeControl();
//MouseControl();
if (Input.GetKeyDown(KeyCode.F5))
{
ResetPos();
}
}
/// <summary>
/// 摄像机移动边界设定
/// </summary>
public void Boundary()
{
Vector3 pos = Camera.main.transform.localPosition;
cameraPos = new Vector3(Mathf.Clamp(pos.x, X_min, X_max), Mathf.Clamp(pos.y, Y_min, Y_max), Mathf.Clamp(pos.z, Z_min, Z_max));
}
/// <summary>
/// 重置摄像机位置
/// </summary>
private void ResetPos()
{
Camera.main.transform.position = StartPos;
Camera.main.transform.eulerAngles = StartRotation;
Camera.main.fieldOfView = StartFieldOfView;
}
/// <summary>
/// 滚轮控制摄像机缩放
/// </summary>
private void WheelContrl()
{
float distance = 0;
distance = Input.GetAxis("Mouse ScrollWheel") * moveSpeed_s;//获取鼠标中键响应
transform.position = transform.position + transform.rotation *new Vector3(0, 0, distance);
//滚动鼠标滑轮缩放摄像机
if (Input.GetAxis("Mouse ScrollWheel") > 0)
{
if (cameraPos.y < Y_min)
return;
Vector3 moveDirectionZ = transform.forward;
cameraPos += moveDirectionZ * moveSpeed_s;
}
if (Input.GetAxis("Mouse ScrollWheel") < 0)
{
if (cameraPos.y > Y_max)
return;
Vector3 moveDirectionZ = -transform.forward;
cameraPos += moveDirectionZ * moveSpeed_s;
}
// //滚轮控制
// if (Input.GetAxis("Mouse ScrollWheel") < 0)
// {
// //控制的范围自行调整
// if (Camera.main.fieldOfView <= 100)
// {
// Camera.main.fieldOfView += 2;
// }
// if (Camera.main.orthographicSize <= 20)
// {
// Camera.main.orthographicSize += 0.5F;
// }
// }
// if (Input.GetAxis("Mouse ScrollWheel") > 0)
// {
// if (Camera.main.fieldOfView > 20
//)
// {
// Camera.main.fieldOfView -= 2;
// }
// if (Camera.main.orthographicSize >= 1)
// {
// Camera.main.orthographicSize -= 0.5F;
// }
// }
}
void RotateCamera()
{
//鼠标左键按下状态启用旋转摄像机
if (Input.GetMouseButtonDown(0))
{
isRotate = true;
}
//鼠标左键抬起状态停止旋转摄像机
if (Input.GetMouseButtonUp(0))
{
isRotate = false;
}
if (!EventSystem.current.IsPointerOverGameObject())
{
if (isRotate)
{
//x 和 y 是绝对值 相对于世界坐标没有转动的位置的最终转动位置
//鼠标的上下移动 移动的Y值 在三维中相当于沿X轴转动
y -= Input.GetAxis("Mouse Y") * moveSpeed_y * Time.deltaTime;
//上下需要限定范围 在完全俯视 和 完全仰视之间
//去掉该限制的话可以使摄像机倒置
y = Mathf.Clamp(y, yMinLimit, yMaxLimit);
//鼠标的左右移动 移动的X值 在三维中相当于沿Y轴转动
//左右是允许360度旋转的 不需要限制到最大最小范围
x += Input.GetAxis("Mouse X") * moveSpeed_x * Time.deltaTime;
//Quaternion rotation = Quaternion.Euler(y, x, 0);
//transform.rotation = rotation;
//和上面2句等价
transform.eulerAngles = new Vector3(y, x, 0);
}
}
}
/// <summary>
/// 鼠标右键拖拽移动上下左右视角
/// </summary>
private void DragScreen()
{
// 当按住鼠标右键的时候
if (Input.GetMouseButton(1))
{
获取鼠标的x和y的值,乘以速度和Time.deltaTime是因为这个可以是运动起来更平滑
//float h = Input.GetAxis("Mouse X") * moveSpeed_s * Time.deltaTime;
//float v = Input.GetAxis("Mouse Y") * moveSpeed_s * Time.deltaTime;
设置当前摄像机移动,y轴并不改变
需要摄像机按照世界坐标移动,而不是按照它自身的坐标移动,所以加上Spance.World
TODO 方向判断
//Camera.main.transform.Translate(-h, 0, -v, Space.World);
//第一种方法按下WS、AD,Input.GetAxis()会返回1或-1
float moveZ = -Input.GetAxis("Mouse Y");
Vector3 moveDirectionZ = transform.forward;
moveDirectionZ.y = 0;
cameraPos += moveDirectionZ * moveZ * moveSpeed_s;
float moveX = -Input.GetAxis("Mouse X");
Vector3 moveDirectionX = transform.right;
moveDirectionZ.y = 0;
cameraPos += moveDirectionX * moveX * moveSpeed_s;
}
}
/// <summary>
/// 实时更新摄像机速度值
/// </summary>
public void GetSpeed(float value)
{
//moveSpeed_x = value*50;
}
/// <summary>
/// 按键控制摄像机移动
/// </summary>
private void CodeControl()
{
//float h = Mathf.Clamp()
float h = Input.GetAxisRaw("Horizontal") * moveSpeed_x * Time.deltaTime;
float v = Input.GetAxisRaw("Vertical") * moveSpeed_y * Time.deltaTime;
Camera.main.transform.Translate(h, 0, v, Space.World);
}
/// <summary>
/// 鼠标放在屏幕边缘移动摄像机
/// </summary>
private void MouseControl()
{
Vector3 v1 = Camera.main.ScreenToViewportPoint(Input.mousePosition);
//移到ui上不触发
if (EventSystem.current.IsPointerOverGameObject())
{
return;
}
//范围限制
if (v1.x > 1 + Min || v1.x < -Min || v1.y > 1 + Min || v1.y < -Min) return;
if (v1.x < Min)//鼠标停靠在左边
{
transform.Translate(Vector3.left * moveSpeed_s * Time.deltaTime, Space.World);
}
if (v1.x > 1 - Min)//鼠标停靠在右边
{
transform.Translate(Vector3.right * moveSpeed_s * Time.deltaTime, Space.World);
}
if (v1.y < Min)//鼠标停靠在下边
{
transform.Translate(Vector3.back * moveSpeed_s * Time.deltaTime, Space.World);
}
if (v1.y > 1 - Min)//鼠标停靠在上边
{
transform.Translate(Vector3.forward * moveSpeed_s * Time.deltaTime, Space.World);
}
}
}
这功能应该是最后一次修改了,主要修改速度和边界的数值就可以使用了。