纳金网
标题:
摄像机移动脚本
[打印本页]
作者:
烟雨
时间:
2016-1-27 00:00
标题:
摄像机移动脚本
using UnityEngine;
using System.Collections;
/// <summary>=
///本脚本挂在摄像机上
/// 摄像机移动脚本,有两种移动方式,A跟随角色移动B鼠标超过屏幕边缘移动,就是鼠标在屏幕上方时,摄像机向前移动
///存在的问题,向左、右移动时,会略微向前移动,也就是斜着移动
/// </summary>
public class CameraFollowPlayer : MonoBehaviour {
public Camera camera;
public GameObject player;
///摄像机相对角色的拉远拉近缩放速度.
/// </summary>
public float forwardAndBackZoomSpeed =13f;
/// <summary>
/// 摄像机与角色最大最小距离
/// </summary>
public float withPlayerDistanceMin =2f;
public float withPlayerDistanceMax =18f;
public enum CameraMoveType//摄像机移动方式
{
FollowPlayerMove,//跟随角色移动
MouseExceedScreenFrameMove,//鼠标超过屏幕边缘移动
}
public CameraMoveType cameraMoveType = CameraMoveType.MouseExceedScreenFrameMove;
public float CameramoveSpeed =3f;
public bool GetCamera()
{
if(!camera)
{
camera = GetComponent<Camera> ( );
}
return camera != null ? true : false;
}
public bool GetPlayer ( )
{
if (! player )
{
player = GameObject.FindWithTag ( Tags.Player );
}
return player != null ? true : false;
}
public Transform cameraT
{
get
{
if ( GetCamera ( ) == false )
return null;
return camera.transform;
}
}
public Vector3 cameraPos
{
get
{
return cameraT.position;
}
}
public Transform PlayerT
{
get
{
if ( GetPlayer ( ) == false )
return null;
return player.transform;
}
}
public Vector3 PlayerPos
{
get
{
return PlayerT.position;
}
}
/// <summary>
/// cameraPos -PlayerPos的摄像机减角色的偏移值.
/// </summary>
Vector3 offset;
Quaternion cameraOriginalRotation;//相机初始旋转.
Quaternion cameraCurrentRotation;//相机当前旋转.
Vector3 OriginalForwardPoint;
// Use this for initialization
void Start ()
{
StartGameTimeCameraMoveToFollowPlayer ( );
offset = cameraPos -PlayerPos ;
}
// Update is called once per frame
void Update ()
{
RotationView ( cameraT , PlayerT , ref offset , 3f , 3f,0.5f );
ScrollView ( );
if ( cameraMoveType == CameraMoveType.FollowPlayerMove )
{
StartGameTimeCameraMoveToFollowPlayer ( );
}
else if ( cameraMoveType == CameraMoveType.MouseExceedScreenFrameMove )
{
MouseExceedScreenFrameMoveFunction();
}
}
/// <summary>
/// 鼠标滚轮拉近拉运摄像机.
/// </summary>
void ScrollView ( )
{
if(Input.GetAxis ( "Mouse ScrollWheel" )!=0)
{
float distance = Vector3.Distance ( cameraPos , PlayerPos );// 摄像机与角色的距离;
distance += Input.GetAxis ( "Mouse ScrollWheel" ) * forwardAndBackZoomSpeed;
distance = Mathf.Clamp ( distance , withPlayerDistanceMin , withPlayerDistanceMax );//限制缩减的最小最大距离
offset = offset.normalized * distance; //更新摄像机与角色位置偏移,使摄像机与角色位置偏移除去距离变成方向的向量 在乘以距离就是要偏移的位置.
cameraT.position = PlayerT.position + offset;
}
}
/// <summary>
/// 开始游戏时,摄像机对准角色初始位置
/// </summary>
void StartGameTimeCameraMoveToFollowPlayer()
{
cameraOriginalRotation = Quaternion.Euler ( 62f , -114f , -7f );
cameraT.rotation = cameraOriginalRotation;
cameraT.position = new Vector3 ( PlayerT.position.x + 3f , PlayerT.position.y + 9f , PlayerT.position.z + 1f );
}
/// <summary>
///鼠标右键按下, 实现摄像机对角色左右上下旋转.
///time =按下右键多长才旋转.
/// </summary>
float timer;
bool startRotate;
void RotationView ( Transform cameraT , Transform playerT , ref Vector3 offset,float LeftRMoveSpeed,float UpDMoveSpeed,float time )
{
if ( Input.GetMouseButtonDown ( 1 ) )
{
//Debug.Log ( "鼠标右键瞬间按下=" + Time.realtimeSinceStartup );
timer = Time.realtimeSinceStartup;
startRotate = false;
}
if ( !Input.GetMouseButton ( 1 ) )
{
//Debug.Log ( "鼠标右键弹起=" + Time.realtimeSinceStartup );
return;
}
if ( Input.GetMouseButton ( 1 ) )
{
// Debug.Log ( "鼠标右键按下中=" + Time.realtimeSinceStartup + "))result=" +( timer + time <= Time.realtimeSinceStartup?"true":"false ") );
if ( timer + time <= Time.realtimeSinceStartup )
{
startRotate = true;
}
}
if(startRotate)
{
float RotateThreshold = 0.1f;//旋转阀值,超过才旋转
//旋转前让摄像机与角色对齐
//让摄像机rotation.z归0
//摄像机.position.x== 角色.position.x
//transform.RotateAround旋转会修改position和rotation
//======开始旋转===
//===左右旋转=====
if ( Input.GetAxis ( "Mouse X" ) > RotateThreshold || Input.GetAxis ( "Mouse X" ) < -RotateThreshold )
{
// Debug.Log ( Input.GetAxis ( "Mouse X" ) );
//transform.RotateAround(角色位置,角色.transform.up,rotateSpeed *Input.GetAxis ("Mouse X") );//绕角色位置这个点,绕Y轴旋转. 注意:旋转的时候不能一直在修改相机的位置,造成旋转错误.
cameraT.RotateAround ( playerT.position , playerT.up , LeftRMoveSpeed * Input.GetAxis ( "Mouse X" ) );//绕角色位置这个点,绕Y轴旋转. 注意:旋转的时候不能一直在修改相机的位置,造成旋转错误.
offset = cameraT.position - playerT.position;//旋转后摄像机位置改变,更新摄像机与角色位置偏移
}
//===左右旋转=====
//===上下旋转====
//旋转前记录一下摄像机的旋转和位置.如果旋转超过限定的边界,就恢复.就是让旋转无效
//旋转会修改position和rotation
if ( Input.GetAxis ( "Mouse Y" ) > RotateThreshold || Input.GetAxis ( "Mouse Y" ) < -RotateThreshold )
{
Vector3 originalPos = cameraT.position;
Quaternion originalRotation = cameraT.rotation;
//transform.RotateAround(角色位置,摄像机.transform.right,-rotateSpeed *Input.GetAxis ("Mouse Y") );//绕角色位置这个点,绕Y轴旋转. 注意:旋转的时候不能一直在修改相机的位置,造成旋转错误.
cameraT.RotateAround ( playerT.position , cameraT.right , -UpDMoveSpeed * Input.GetAxis ( "Mouse Y" ) );//绕角色位置这个点,绕Y轴旋转. 注意:旋转的时候不能一直在修改相机的位置,造成旋转错误.
//如果旋转超出范围,将属性归为未旋转前的值,就是让旋转无效
float x = cameraT.eulerAngles.x;
if ( x < 10 || x > 80 )
{
cameraT.position = originalPos;
cameraT.rotation = originalRotation;
}
offset = cameraT.position - playerT.position;//旋转后摄像机位置改变,更新摄像机与角色位置偏移
//===上下旋转====
}
cameraOriginalRotation = cameraT.rotation;
}
}
void MouseExceedScreenFrameMoveFunction()
{
if(Input.mousePosition.y>=Screen.height)
{
MoveDirection (1 );
}
if(Input.mousePosition.y<=0)//back
{
MoveDirection (2 );
}
if(Input.mousePosition.x >=Screen.width)
{
MoveDirection (3 );
}
if ( Input.mousePosition.x <=0 )//right
{
MoveDirection (4 );
}
}
/// <summary>
/// 把物体移动到某个点,但是不旋转物体,也就是不面向点
/// </summary>
void MoveToPoint (Transform WantMoveObj,Vector3 TargetPoint ,float MoveSpeed)
{
if ( WantMoveObj )
{
Vector3 Direction = ( TargetPoint - WantMoveObj.position ).normalized;
if(Vector3.Distance(TargetPoint,WantMoveObj.position)>0.5f)
{
WantMoveObj.position = WantMoveObj.position + Direction * MoveSpeed*Time.deltaTime;
}
}
}
/// <summary>
/// 从屏幕的某个坐标发射射线,返回碰到的点
/// </summary>
/// <param name="Position"></param>
/// <returns></returns>
Vector3 LaunchRay(Vector2 Position)
{
Ray ray = Camera.main.ScreenPointToRay ( Position );
RaycastHit raycastHit;
if ( Physics.Raycast ( ray , out raycastHit , 99f ) )
{
//Debug.DrawLine ( cameraPos , raycastHit.point,Color.red );
return raycastHit.point;
}
return Vector3.zero;
}
//向前移动时,检测鼠标是否在屏幕的上方边界,就在屏幕的上方中点发射射线,点Y是屏幕高度,X是屏幕宽度的一半,当射线碰到地面时,获取到碰撞点,然后摄像机就向这个碰撞点平移.
void MoveDirection(int direction )//1=qian,2=hou ,3=zuo,4=you
{
Vector2 position=Vector3.zero;
switch ( direction )
{
case 1:
position = new Vector2 ( Screen.width * 0.5f , Screen.height );
break;
case 2:
position = new Vector2 ( Screen.width * 0.5f , 0f);
break;
case 3:
position = new Vector2 ( Screen.width , Screen.height * 0.5f );
break;
case 4:
position = new Vector2 ( 0f , Screen.height * 0.5f );
break;
}
Vector3 HitPoint = LaunchRay ( position );
if(HitPoint==Vector3.zero)
{
return;
}
//Debug.Log ( "mouse" + Input.mousePosition + ") Hitpoint = " + HitPoint );
if ( direction == 2 )//向后移动做,特殊处理,由于摄像机是斜着的,所有碰撞点会位于摄像机前面,相对于碰撞点,要向后偏移,计算一个朝后的点
{
Vector3 forwardP = GetForwardPoint ( );
Vector3 BackPoint=Vector3.zero;
Vector3 dir = ( HitPoint - forwardP ).normalized;
HitPoint += dir * 15f;
//Debug.DrawLine ( cameraPos , BackPoint , Color.yellow );
}
//不修改高度
HitPoint.y = cameraPos.y;
//开始移动
MoveToPoint ( cameraT , HitPoint , CameramoveSpeed );
}
Vector3 GetForwardPoint()
{
Vector2 position = new Vector2 ( Screen.width * 0.5f , Screen.height );
return LaunchRay ( position );
}
}
复制代码
欢迎光临 纳金网 (http://c-www.narkii.com/club/)
Powered by Discuz! X2.5