Unity C#脚本实现的相机漫游…

来源:互联网 发布:淘宝楼梯实木踏步板 编辑:程序博客网 时间:2024/05/20 22:03
转载请注明出处http://blog.sina.com.cn/u/1580340211
最近总监把之前的项目导出发现有相机乱晃动的情况,后来发现竟然是Unity版本的问题,之前的3.5的版本导入到4.0里面(因为用的是64bit的win7),导出成x64的时候竟然出现了很大的问题,于是总监建议自己写一个结合mouselook和move的代码,虽然在人视模式的时候没有完全消除刚体碰撞带来的影响,代码还没有足够的优化,但是基本的切换已经实现了(话说因为不知道什么叫人视模式还被boss鄙视了....)
using UnityEngine;
using System.Collections;


public class RotandMove_Camera : MonoBehaviour {
private Vector3 oldMousePos;
private Vector3 newMosuePos;
private Texture2D gogj;
public GameObject currentCamera=null;
public GameObject currentCam_root=null;
public float moveSpeed=0.1f;
public float rotSpeed=15.0f;
public float scalSensetive=10.0f;
public float minFov=15.0f;
public float maxFov=90.0f;
public float minimumY = -60F;
public float maximumY = 60F;
public float personHeight=2.0F;
public float middleMoveSpeed=0.1F;//鼠标中间控制相机的速度
public GameObject cube;
private Vector3 origiPos;
private Vector3 origiUp;
private Vector3 origiRight;
private string viewString="Person Veiw";
public enum ViewMode { SuperView = 0, PersonView = 1 }
public ViewMode camView = ViewMode.PersonView;

// Use this for initialization
void OnGUI()
{
if(GUILayout.Button("SuperView",GUILayout.Height(50)))
{
       camView=ViewMode.SuperView;
if(currentCamera)
{
currentCamera.collider.isTrigger=true;
}
viewString="Super View";
}
if(GUILayout.Button("PersonView",GUILayout.Height(50)))
{
camView=ViewMode.PersonView;
if(currentCamera)
{
currentCamera.gameObject.collider.isTrigger=false;
//currentCamera.rigidbody.isKinematic=true;
}
viewString="Person View";
}
if(GUILayout.Button("Reset",GUILayout.Height(50)))
{
if(currentCamera)
{
currentCamera.transform.position=origiPos;
currentCamera.transform.up=origiUp;
currentCamera.transform.right=origiRight;
}
}
GUILayout.Label(viewString);
}
void Start () 
{
if(currentCamera==null)
currentCamera=GameObject.Find("MainCamera");
origiPos=currentCamera.transform.position;
origiUp=currentCamera.transform.up;
origiRight=currentCamera.transform.right;
currentCamera.rigidbody.freezeRotation=true;

oldMousePos=newMosuePos=Input.mousePosition;
}
// Update is called once per frame
void Update () 
{
 if(camView==ViewMode.PersonView)
{
moveCamera();
scaleCamera();
rotateCamera();
terrainDetect();
}
 if(camView==ViewMode.SuperView)
{
moveCamera();
scaleCamera();
superViewMouse();
}
oldMousePos=Input.mousePosition;
}
void moveCamera(){
if(Input.GetKey(KeyCode.A)||Input.GetKey(KeyCode.LeftArrow))
{
currentCamera.transform.Translate(newVector3(-moveSpeed,0,0),Space.Self);
}
if(Input.GetKey(KeyCode.D)||Input.GetKey(KeyCode.RightArrow))
{
currentCamera.transform.Translate(newVector3(moveSpeed,0,0),Space.Self);
}
if(Input.GetKey(KeyCode.W)||Input.GetKey(KeyCode.UpArrow))
{
currentCamera.transform.Translate(newVector3(0,0,moveSpeed),Space.Self);
}
if(Input.GetKey(KeyCode.S)||Input.GetKey(KeyCode.DownArrow))
{
currentCamera.transform.Translate(newVector3(0,0,-moveSpeed),Space.Self);
}
if(Input.GetKey(KeyCode.Q)&&(camView==ViewMode.SuperView))
{
currentCamera.transform.Translate(newVector3(0,moveSpeed,0),Space.World);
}
if(Input.GetKey(KeyCode.E)&&(camView==ViewMode.SuperView))
{
   currentCamera.transform.Translate(newVector3(0,-moveSpeed,0),Space.World);
}

}
void rotateCamera(){
if(Input.GetMouseButton(0))
{
newMosuePos=Input.mousePosition;
Vector3 dis=newMosuePos-oldMousePos;
float angleX=dis.x*rotSpeed*Time.deltaTime;
float angleY=dis.y*rotSpeed*Time.deltaTime;
currentCamera.transform.Rotate(newVector3(-angleY,0,0),Space.Self);
  currentCamera.transform.Rotate(newVector3(0,angleX,0),Space.World);
}
//oldMousePos=newMosuePos=Input.mousePosition;
}

void scaleCamera()
{
float fov=currentCamera.camera.fieldOfView;
fov-=Input.GetAxis("Mouse ScrollWheel")*scalSensetive;
fov=Mathf.Clamp(fov,minFov,maxFov);
currentCamera.camera.fieldOfView=fov;
}
void terrainDetect()
{
Ray ray=newRay(currentCamera.transform.position,Vector3.down);
RaycastHit rayHit;
if(Physics.Raycast(ray,out rayHit,10))
{   
   Vector3oldVec=currentCamera.transform.position;
currentCamera.transform.position=newVector3(oldVec.x,rayHit.point.y+personHeight,oldVec.z);

}
}
void middleMove()
{
//鼠标中键控制相机的移动
if(Input.GetMouseButton(1))
{
newMosuePos=Input.mousePosition;
Vector3 dis2=newMosuePos-oldMousePos;
      
Debug.Log("Dis2 X "+dis2.x+" Y"+dis2.y);
currentCamera.transform.Translate(newVector3(-dis2.x*middleMoveSpeed*Time.deltaTime,0,0),Space.Self);
  currentCamera.transform.Translate(newVector3(0,-dis2.y*middleMoveSpeed*Time.deltaTime,0),Space.Self);

}
}
void superViewMouse()
{
if(Input.GetAxis("Fire3")==1)
{
newMosuePos=Input.mousePosition;
Vector3 dis2=newMosuePos-oldMousePos;
      
Debug.Log("Dis2 X "+dis2.x+" Y"+dis2.y);
currentCamera.transform.Translate(newVector3(-dis2.x*middleMoveSpeed*Time.deltaTime,0,0),Space.Self);
  currentCamera.transform.Translate(newVector3(0,-dis2.y*middleMoveSpeed*Time.deltaTime,0),Space.Self);

}
if(Input.GetMouseButton(0))
{
newMosuePos=Input.mousePosition;
Vector3 dis=newMosuePos-oldMousePos;
float angleX=dis.x*rotSpeed*Time.deltaTime;
float angleY=dis.y*rotSpeed*Time.deltaTime;
currentCamera.transform.Rotate(newVector3(-angleY,0,0),Space.Self);
  currentCamera.transform.Rotate(newVector3(0,angleX,0),Space.World);
}
}
}
PS:
使用的时候要给相机绑定一个刚体,同时最好是使用胶囊碰撞体(人视模式同时实现了碰撞检测,可以实现不同的高度在不平坦地形上的运动)
超级模式
Unity <wbr>C#脚本实现的相机漫游(可以实现人视/超级模式的切换)



人视模式Unity <wbr>C#脚本实现的相机漫游(可以实现人视/超级模式的切换)