查看: 1094|回复: 0
打印 上一主题 下一主题

[其他] 摄像机移动脚本

[复制链接]

9903

主题

126

听众

7万

积分

首席设计师

Rank: 8Rank: 8

纳金币
53488
精华
316

最佳新人 热心会员 灌水之王 活跃会员 突出贡献 荣誉管理 论坛元老

跳转到指定楼层
楼主
发表于 2016-1-27 00:00:34 |只看该作者 |倒序浏览
  1. using UnityEngine;
  2. using System.Collections;

  3. /// <summary>=
  4. ///本脚本挂在摄像机上
  5. /// 摄像机移动脚本,有两种移动方式,A跟随角色移动B鼠标超过屏幕边缘移动,就是鼠标在屏幕上方时,摄像机向前移动
  6. ///存在的问题,向左、右移动时,会略微向前移动,也就是斜着移动
  7. /// </summary>
  8. public class CameraFollowPlayer : MonoBehaviour {

  9.     public Camera camera;
  10.     public GameObject player;
  11.     ///摄像机相对角色的拉远拉近缩放速度.
  12.     /// </summary>
  13.     public float forwardAndBackZoomSpeed =13f;
  14.     /// <summary>
  15.     /// 摄像机与角色最大最小距离
  16.     /// </summary>
  17.     public float withPlayerDistanceMin =2f;
  18.     public float withPlayerDistanceMax =18f;

  19.     public enum CameraMoveType//摄像机移动方式
  20.     {
  21.         FollowPlayerMove,//跟随角色移动
  22.         MouseExceedScreenFrameMove,//鼠标超过屏幕边缘移动
  23.     }
  24.    public  CameraMoveType cameraMoveType = CameraMoveType.MouseExceedScreenFrameMove;

  25.    public float CameramoveSpeed =3f;
  26.     public bool GetCamera()
  27.     {
  28.         if(!camera)
  29.         {
  30.             camera = GetComponent<Camera> ( );
  31.         }
  32.         return camera != null ? true : false;
  33.     }
  34.     public bool GetPlayer ( )
  35.     {

  36.         if (! player )
  37.         {
  38.             player = GameObject.FindWithTag ( Tags.Player );
  39.         }
  40.         return player != null ? true : false;
  41.     }
  42.     public Transform cameraT
  43.     {
  44.         get
  45.         {
  46.             if ( GetCamera ( ) == false )
  47.                 return null;
  48.             return camera.transform;
  49.         }
  50.     }
  51.     public Vector3 cameraPos
  52.     {
  53.         get
  54.         {
  55.             return cameraT.position;
  56.         }
  57.     }

  58.     public Transform PlayerT
  59.     {
  60.         get
  61.         {
  62.             if ( GetPlayer ( ) == false )
  63.                 return null;
  64.             return player.transform;
  65.         }
  66.     }
  67.     public Vector3 PlayerPos
  68.     {
  69.         get
  70.         {
  71.             return PlayerT.position;
  72.         }
  73.     }

  74.     /// <summary>
  75.     ///  cameraPos -PlayerPos的摄像机减角色的偏移值.
  76.     /// </summary>
  77.      Vector3 offset;
  78.      Quaternion cameraOriginalRotation;//相机初始旋转.
  79.      Quaternion cameraCurrentRotation;//相机当前旋转.

  80.      Vector3 OriginalForwardPoint;

  81.     // Use this for initialization
  82.     void Start ()
  83.     {
  84.         StartGameTimeCameraMoveToFollowPlayer ( );
  85.         offset = cameraPos -PlayerPos  ;
  86.     }

  87.     // Update is called once per frame
  88.     void Update ()
  89.     {
  90.         RotationView ( cameraT , PlayerT , ref offset , 3f , 3f,0.5f );
  91.         ScrollView ( );
  92.         if ( cameraMoveType == CameraMoveType.FollowPlayerMove )
  93.         {
  94.             StartGameTimeCameraMoveToFollowPlayer ( );
  95.         }
  96.         else if ( cameraMoveType == CameraMoveType.MouseExceedScreenFrameMove )
  97.         {
  98.             MouseExceedScreenFrameMoveFunction();
  99.         }
  100.     }

  101.     /// <summary>
  102.     /// 鼠标滚轮拉近拉运摄像机.
  103.     /// </summary>
  104.     void ScrollView ( )
  105.     {
  106.         if(Input.GetAxis ( "Mouse ScrollWheel" )!=0)
  107.         {
  108.             float distance = Vector3.Distance ( cameraPos , PlayerPos );// 摄像机与角色的距离;
  109.             distance += Input.GetAxis ( "Mouse ScrollWheel" ) * forwardAndBackZoomSpeed;
  110.             distance = Mathf.Clamp ( distance , withPlayerDistanceMin , withPlayerDistanceMax );//限制缩减的最小最大距离
  111.             offset = offset.normalized * distance; //更新摄像机与角色位置偏移,使摄像机与角色位置偏移除去距离变成方向的向量 在乘以距离就是要偏移的位置.
  112.             cameraT.position = PlayerT.position + offset;
  113.         }
  114.     }

  115.     /// <summary>
  116.     /// 开始游戏时,摄像机对准角色初始位置
  117.     /// </summary>
  118.     void StartGameTimeCameraMoveToFollowPlayer()
  119.     {
  120.         cameraOriginalRotation = Quaternion.Euler ( 62f , -114f , -7f );
  121.         cameraT.rotation = cameraOriginalRotation;
  122.         cameraT.position = new Vector3 ( PlayerT.position.x + 3f , PlayerT.position.y + 9f , PlayerT.position.z + 1f );
  123.     }

  124.     /// <summary>
  125.     ///鼠标右键按下, 实现摄像机对角色左右上下旋转.
  126.     ///time =按下右键多长才旋转.
  127.     /// </summary>
  128.     float timer;
  129.     bool startRotate;
  130.     void RotationView ( Transform cameraT , Transform playerT , ref Vector3 offset,float LeftRMoveSpeed,float  UpDMoveSpeed,float time )
  131.     {
  132.         if ( Input.GetMouseButtonDown ( 1 ) )
  133.         {
  134.             //Debug.Log ( "鼠标右键瞬间按下=" + Time.realtimeSinceStartup );
  135.             timer = Time.realtimeSinceStartup;
  136.             startRotate = false;
  137.         }
  138.         if ( !Input.GetMouseButton ( 1 ) )
  139.         {
  140.             //Debug.Log ( "鼠标右键弹起=" + Time.realtimeSinceStartup );
  141.             return;
  142.         }
  143.         if ( Input.GetMouseButton ( 1 ) )
  144.         {
  145.             // Debug.Log ( "鼠标右键按下中=" + Time.realtimeSinceStartup + "))result=" +( timer + time <= Time.realtimeSinceStartup?"true":"false ") );
  146.             if ( timer + time <= Time.realtimeSinceStartup )
  147.             {
  148.                 startRotate = true;
  149.             }
  150.         }

  151.         if(startRotate)
  152.         {
  153.             float RotateThreshold = 0.1f;//旋转阀值,超过才旋转
  154.             //旋转前让摄像机与角色对齐
  155.             //让摄像机rotation.z归0
  156.             //摄像机.position.x== 角色.position.x
  157.             //transform.RotateAround旋转会修改position和rotation
  158.             //======开始旋转===

  159.             //===左右旋转=====
  160.             if ( Input.GetAxis ( "Mouse X" ) > RotateThreshold || Input.GetAxis ( "Mouse X" ) < -RotateThreshold )
  161.             {
  162.                // Debug.Log ( Input.GetAxis ( "Mouse X" ) );
  163.                 //transform.RotateAround(角色位置,角色.transform.up,rotateSpeed *Input.GetAxis ("Mouse X") );//绕角色位置这个点,绕Y轴旋转. 注意:旋转的时候不能一直在修改相机的位置,造成旋转错误.
  164.                 cameraT.RotateAround ( playerT.position , playerT.up , LeftRMoveSpeed * Input.GetAxis ( "Mouse X" ) );//绕角色位置这个点,绕Y轴旋转. 注意:旋转的时候不能一直在修改相机的位置,造成旋转错误.
  165.                 offset = cameraT.position - playerT.position;//旋转后摄像机位置改变,更新摄像机与角色位置偏移
  166.             }
  167.             //===左右旋转=====

  168.             //===上下旋转====
  169.             //旋转前记录一下摄像机的旋转和位置.如果旋转超过限定的边界,就恢复.就是让旋转无效
  170.             //旋转会修改position和rotation
  171.             if ( Input.GetAxis ( "Mouse Y" ) > RotateThreshold || Input.GetAxis ( "Mouse Y" ) < -RotateThreshold )
  172.             {
  173.                 Vector3 originalPos = cameraT.position;
  174.                 Quaternion originalRotation = cameraT.rotation;
  175.                 //transform.RotateAround(角色位置,摄像机.transform.right,-rotateSpeed *Input.GetAxis ("Mouse Y") );//绕角色位置这个点,绕Y轴旋转. 注意:旋转的时候不能一直在修改相机的位置,造成旋转错误.
  176.                 cameraT.RotateAround ( playerT.position , cameraT.right , -UpDMoveSpeed * Input.GetAxis ( "Mouse Y" ) );//绕角色位置这个点,绕Y轴旋转. 注意:旋转的时候不能一直在修改相机的位置,造成旋转错误.
  177.                 //如果旋转超出范围,将属性归为未旋转前的值,就是让旋转无效
  178.                 float x = cameraT.eulerAngles.x;
  179.                 if ( x < 10 || x > 80 )
  180.                 {
  181.                     cameraT.position = originalPos;
  182.                     cameraT.rotation = originalRotation;
  183.                 }

  184.                 offset = cameraT.position - playerT.position;//旋转后摄像机位置改变,更新摄像机与角色位置偏移
  185.                 //===上下旋转====
  186.             }
  187.             cameraOriginalRotation = cameraT.rotation;
  188.         }
  189.     }


  190.     void MouseExceedScreenFrameMoveFunction()
  191.     {

  192.         if(Input.mousePosition.y>=Screen.height)
  193.         {
  194.             MoveDirection (1 );
  195.         }
  196.         if(Input.mousePosition.y<=0)//back
  197.         {
  198.             MoveDirection (2 );
  199.         }
  200.         if(Input.mousePosition.x >=Screen.width)
  201.         {
  202.             MoveDirection (3 );
  203.         }
  204.         if ( Input.mousePosition.x <=0 )//right
  205.         {
  206.             MoveDirection (4 );
  207.         }
  208.     }

  209.     /// <summary>
  210.     /// 把物体移动到某个点,但是不旋转物体,也就是不面向点
  211.     /// </summary>
  212.     void MoveToPoint (Transform WantMoveObj,Vector3 TargetPoint ,float MoveSpeed)
  213.     {
  214.         if ( WantMoveObj )
  215.         {
  216.             Vector3 Direction = ( TargetPoint - WantMoveObj.position ).normalized;
  217.             if(Vector3.Distance(TargetPoint,WantMoveObj.position)>0.5f)
  218.             {
  219.                 WantMoveObj.position = WantMoveObj.position + Direction * MoveSpeed*Time.deltaTime;
  220.             }
  221.         }
  222.     }

  223.     /// <summary>
  224.     /// 从屏幕的某个坐标发射射线,返回碰到的点
  225.     /// </summary>
  226.     /// <param name="Position"></param>
  227.     /// <returns></returns>
  228.     Vector3 LaunchRay(Vector2 Position)
  229.     {
  230.             Ray  ray = Camera.main.ScreenPointToRay ( Position );
  231.             RaycastHit raycastHit;
  232.             if ( Physics.Raycast ( ray , out raycastHit , 99f ) )
  233.             {
  234.                     //Debug.DrawLine ( cameraPos , raycastHit.point,Color.red );
  235.                     return raycastHit.point;
  236.              }
  237.             return Vector3.zero;
  238.     }


  239.     //向前移动时,检测鼠标是否在屏幕的上方边界,就在屏幕的上方中点发射射线,点Y是屏幕高度,X是屏幕宽度的一半,当射线碰到地面时,获取到碰撞点,然后摄像机就向这个碰撞点平移.
  240.     void MoveDirection(int direction )//1=qian,2=hou ,3=zuo,4=you
  241.     {
  242.         Vector2 position=Vector3.zero;
  243.         switch ( direction )
  244.        {
  245.             case 1:
  246.              position = new Vector2 ( Screen.width * 0.5f , Screen.height );
  247.            break;
  248.             case 2:
  249.             position = new Vector2 ( Screen.width * 0.5f , 0f);
  250.            break;
  251.             case 3:
  252.            position = new Vector2 ( Screen.width , Screen.height * 0.5f );
  253.            break;
  254.             case 4:
  255.            position = new Vector2 ( 0f , Screen.height * 0.5f );
  256.            break;
  257.        }
  258.         Vector3 HitPoint = LaunchRay ( position );
  259.         if(HitPoint==Vector3.zero)
  260.         {
  261.             return;
  262.         }
  263.         //Debug.Log ( "mouse" + Input.mousePosition + ") Hitpoint = " + HitPoint );

  264.         if ( direction == 2 )//向后移动做,特殊处理,由于摄像机是斜着的,所有碰撞点会位于摄像机前面,相对于碰撞点,要向后偏移,计算一个朝后的点
  265.         {
  266.             Vector3 forwardP = GetForwardPoint ( );
  267.             Vector3 BackPoint=Vector3.zero;
  268.             Vector3 dir = ( HitPoint - forwardP ).normalized;
  269.             HitPoint += dir * 15f;
  270.             //Debug.DrawLine ( cameraPos , BackPoint , Color.yellow );
  271.         }

  272.         //不修改高度
  273.         HitPoint.y = cameraPos.y;

  274.         //开始移动
  275.         MoveToPoint ( cameraT , HitPoint , CameramoveSpeed );
  276.     }


  277.     Vector3 GetForwardPoint()
  278.     {
  279.         Vector2  position = new Vector2 ( Screen.width * 0.5f , Screen.height );
  280.         return LaunchRay ( position );
  281.     }
  282. }
复制代码
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-11-14 20:20 , Processed in 0.288037 second(s), 29 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部