一个简单的测试,wasd可以控制相机运动,右键可以控制旋转角度,当相机移动到距离碰撞距离超过所设定的距离时,停止往移动的方向移动,主要利用射线检测距离的功能。
using UnityEngine;
using System.Collections;
public class FlyCamera : MonoBehaviour {
public float _mFSpeed = 250f;
public float _mMaxSpeed = 500.0f;
public float _mMinSpeed = 0.1f;
/// <summary>
/// 旋转轴向控制
/// </summary>
public enum RotateAxes {
MouseXAndY=0,
MouseX=1,
MouseY=2
}
/// <summary>
/// 实际使用的旋转轴向
/// </summary>
public RotateAxes _mRotateAxes = RotateAxes.MouseXAndY;
/// <summary>
/// X轴向分量
/// </summary>
public float _mFsensitivityX = 12.0f;
/// <summary>
/// Y轴向分量
/// </summary>
public float _mFSensitivityY = 12.0f;
/// <summary>
/// X轴向最小旋转角度
/// </summary>
public float _mFminiX = -360.0f;
/// <summary>
/// X轴向最大旋转角度
/// </summary>
public float _mFmaxX = 360.0f;
/// <summary>
/// Y轴最小旋转角度
/// </summary>
public float _mFminiY = -60.0f;
/// <summary>
/// Y轴最大旋转速度
/// </summary>
public float _mFmaxY = 60.0f;
/// <summary>
/// Y轴向旋转
/// </summary>
float _mFrotateY = 0.0f;
public float _mLimitHeight=1.2f;
public bool _mCanLimitHeight=false;
public float _mPadRotAngle = 8.0f;
public enum RotateMode{
RotateByMoveMouse=0,
RotateByRightMouseButton=1
}
public RotateMode _mRotMode=RotateMode.RotateByRightMouseButton;
private Vector2 _mFirstVec = Vector2.zero, _mSceondVec = Vector2.zero;
void Awake() {
_mCanLimitHeight = false;
_mFirstVec=Vector2.zero;
_mSceondVec=Vector2.zero;
Hide("UI");
}
void FixedUpdate () {
if(Input.GetKey(KeyCode.Delete)){
if(Input.GetKeyDown(KeyCode.B)){
_mCanLimitHeight = !_mCanLimitHeight;
}
}
if(_mCanLimitHeight){
transform.localPosition=new Vector3 (transform.localPosition.x,_mLimitHeight,transform.localPosition.z);
}
}
void Update () {
_MoveCamera();
if(_mRotMode==RotateMode.RotateByMoveMouse){
_RotateCamera(0);
}else{
_RotateCamera(1);
}
_ModifySpeed();
}
void _ModifySpeed() {
if (Input.GetKeyDown(KeyCode.KeypadPlus)) {
_mFSpeed+=0.1f;
if (_mFSpeed >= _mMaxSpeed) _mFSpeed = _mMaxSpeed;
//print(_mFSpeed);
}
if (Input.GetKeyDown(KeyCode.KeypadMinus)) {
_mFSpeed -= 0.1f;
if (_mFSpeed <= _mMinSpeed) _mFSpeed = _mMinSpeed;
//print(_mFSpeed);
}
}
void _MoveCamera() {
if (Input.GetKey(KeyCode.W) && CanMove(transform.forward)) transform.Translate(Vector3.forward * Time.deltaTime * _mFSpeed);
if (Input.GetKey(KeyCode.S) && CanMove(-transform.forward)) transform.Translate(Vector3.back * Time.deltaTime * _mFSpeed);
if (Input.GetKey(KeyCode.A) && CanMove(-transform.right)) transform.Translate(Vector3.left * Time.deltaTime * _mFSpeed);
if (Input.GetKey(KeyCode.D) && CanMove(transform.right)) transform.Translate(Vector3.right * Time.deltaTime * _mFSpeed);
if (Input.GetKey(KeyCode.Q) && CanMove(transform.up)) transform.Translate(Vector3.up * Time.deltaTime * _mFSpeed);
if (Input.GetKey(KeyCode.E) && CanMove(-transform.up)) transform.Translate(Vector3.down * Time.deltaTime * _mFSpeed);
}
void _RotateCamera(int m_MouseKeycodeNumber) {
if(Input.GetMouseButton(m_MouseKeycodeNumber)){
if (_mRotateAxes == RotateAxes.MouseXAndY) {
float rotateX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * _mFsensitivityX;
_mFrotateY += Input.GetAxis("Mouse Y") * _mFSensitivityY;
_mFrotateY = Mathf.Clamp(_mFrotateY, _mFminiY, _mFmaxY);
transform.localEulerAngles = new Vector3(-_mFrotateY, rotateX,0);
//Debug.Log("MouseXY");
}else if(_mRotateAxes==RotateAxes.MouseX){
transform.Rotate(0, Input.GetAxis("Mouse X") * _mFsensitivityX, 0);
//Debug.Log("MouseX");
}else{
_mFrotateY += Input.GetAxis("Mouse Y") * _mFSensitivityY;
_mFrotateY = Mathf.Clamp(_mFrotateY, _mFminiY, _mFmaxY);
transform.localEulerAngles = new Vector3(-_mFrotateY, transform.localEulerAngles.y, 0);
//Debug.Log("MouseY");
}
}
}
private void Hide(string someLayer)
{
GetComponent<Camera>().cullingMask &= ~(1 << LayerMask.NameToLayer(someLayer));
}
private RaycastHit _hit;
public float rayLength = 0.5f;
/// <summary>
/// 相机距离检测与设定距离对比并返回是否运动的判断
/// </summary>
/// <param name="dir">本物体所朝的方向</param>
/// <returns></returns>
bool CanMove(Vector3 dir)
{
Ray ray = new Ray(transform.position, dir);
//if (Physics.Raycast(ray, out _hit, RayLength, 1 << LayerMask.NameToLayer("wall")))
if (Physics.Raycast(ray, out _hit, rayLength))
{
//print(_hit.transform.name);
return false;
}
return true;
}
}
工程的下载地址链接:链接: https://pan.baidu.com/s/1nhjrJ6eKB68oUfINPGcwQQ 密码: kd8r 。
unity版本:Unity 2017.3.1p4
大家有好的想法,可以写一下