U3D之摄像机不同视角的方法

U3D摄像机视角

U3D的可以通过设置摄像机来实现第一人称,第三人称等不同游戏视角。

1第一人称视角

四元数转化成欧拉角 Vector3 v3=transform.rotation.eulerAngles;
欧拉角转换成四元数 Quaternion rotation = Quaternion.Euler(v3);

需要实现的效果:鼠标上下左右移动镜头跟着移动;人物移动和跳跃(这里我们人物移动使用的是CharacterController组件的Move和SimpleMove方法);
看到的视野
在这里插入图片描述

//player.cs   人物移动代码
//使用CharacterController组件控制人物移动,simpleMove和Move两种方法的区别是:Move需要自己定义重力,如下:
using UnityEngine;
using System.Collections;/// 
/// CharacterController控制移动
/// 1:SimpleMove(自动应用重力效果)
/// 2:Move(不会应用重力效果,需要自己去实现)
/// 
public class PlayerMove : MonoBehaviour {
private CharacterController cc;//角色控制器,控制物体的移动
private float speed = 4.0f;//移动速度
private float gravity = 10.0f;//重力
private Vector3 moveDir = Vector3.zero;//移动方向
void Start () 
{cc = this.GetComponent<CharacterController>();
}void Update () 
{//模拟重力效果//一开始y方向速度为正,表示再上升即跳起来;当y为负时,开始下降,且下降速度越来越快if (moveDir.y > -gravity){moveDir.y -= gravity * Time.deltaTime;print(moveDir);}cc.Move(moveDir * Time.deltaTime);//首先必須保證moveDir为负数,不能为0,只有是负数,才能算是isGroundedif (cc.isGrounded)//在地上{if (Input.GetKeyDown(KeyCode.Space))//按空格起跳{moveDir.y = speed;}else{float h = Input.GetAxis("Horizontal")*speed;float v = Input.GetAxis("Vertical")*speed;Vector3 dir = new Vector3(h, 0, v);//水平面方向的移动dir *= speed;if (Input.GetKey(KeyCode.LeftShift)){dir *= 2;}//cc.SimpleMove(transform.TransformDirection(dir));//不需要乘以deltaTime,把当前方向转换到世界空间中cc.Move(transform.TransformDirection(dir) * Time.deltaTime);//需要乘以deltaTime}}else {//在空中的运动状态控制if (Input.GetKey("w")){Vector3 zDir = transform.TransformDirection(Vector3.forward);if (Input.GetKey(KeyCode.LeftShift)){cc.Move(zDir * speed * Time.deltaTime * 2);}else{cc.Move(zDir * speed * Time.deltaTime);}}     }
}
}

MouseLook.cs
摄像机旋转带动角色旋转
//作用是当鼠标移动时,player跟着转向,player分为两部分构成:body和head两部分,body负责左右转,head负责上下转
//再body对象中,摄像机旋转类型为MouseX;
再head对象中,摄像机旋转类型为MouseY;

using UnityEngine;
using System.Collections;public class MouseLook : MonoBehaviour {
public enum ERotationAxis//摄像机的旋转类型
{ MouseXY,//水平和垂直方向的旋转MouseX,//只是X方向上的移动MouseY//Y方向上的移动}
public float sensitivityX = 20.0f;//X方向上移动的灵敏度
public float sensitivityY = 15.0f;
public float minAngleY = -60.0f;//鼠标在Y轴方向移动摄像机角度观看范围
public float maxAngleY = 60.0f;
public ERotationAxis axis = ERotationAxis.MouseXY;
private float rotationY;
void Start () 
{if (GetComponent<Rigidbody>()){GetComponent<Rigidbody>().freezeRotation = true;}
}void Update () 
{float x = Input.GetAxis("Mouse X");//鼠标的左右移动float y = Input.GetAxis("Mouse Y");//鼠标的上下移动switch (axis){case ERotationAxis.MouseXY:float rotationX = transform.localEulerAngles.y + x * sensitivityX;rotationY += y * sensitivityY;rotationY = Mathf.Clamp(rotationY, minAngleY, maxAngleY);//夹值transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);break;case ERotationAxis.MouseX:transform.Rotate(0,x*sensitivityX,0);//body执行这个break;case ERotationAxis.MouseY:rotationY += y * sensitivityY;rotationY = Mathf.Clamp(rotationY, minAngleY, maxAngleY);//夹值transform.localEulerAngles = new Vector3(-rotationY,                  transform.localEulerAngles.y, 0);//head执行这个//transform.Rotate(-y * sensitivityY, 0, 0);这个也能用break;}
}
}

第三人称视角

实现效果:点鼠标右键移动摄像机,player跟着移动;如果人物和摄像机之间被挡到,摄像机会跳到挡到点处;同样是摄像机带动人物旋转
在这里插入图片描述
脚本一
ThirdPlayer.cs

using UnityEngine;
using System.Collections;public class ThirdPlayer : MonoBehaviour {public CharacterController cc;public float moveSpeed = 3.0f;public Camera camera;// Use this for initializationvoid Start () {cc=this.GetComponent<CharacterController>();camera=Camera.main;this.transform.rotation = camera.transform.rotation;//角色跟着相机旋转}// Update is called once per framevoid Update () {float vx = Input.GetAxis("Horizontal") * moveSpeed;float vy = Input.GetAxis("Vertical")*moveSpeed;Vector3 cmEuler = camera.transform.eulerAngles;cmEuler.x = cmEuler.z = 0;this.transform.eulerAngles = cmEuler;cc.SimpleMove(transform.TransformDirection(new Vector3(vx,0,vy)));}
}

CameraFollow.cs
相机跟随脚本

using UnityEngine;
using System.Collections;
using System.Collections.Generic;public class CameraFollow : MonoBehaviour {public const float DISTANCE_DEAFULT = 8.0f;//默认主角和摄像机的距离private float distance = 0.0f;//运行时的距离private Transform transTarget;//摄像机跟随目标(主角)public float target_offsety = 0.5f;//盯着目标往上偏移值private Vector3 vLooker;//摄像机盯着的位置private Vector3 rotateXY;//保存X,Y方向的旋转,鼠标移动的时候会发生改变private float speedAngelX = 200;//x方向的旋转速度private float speedAngelY = 100;//y方向的旋转速度public float minAngleAtY = -90.0f;       //摄像机在Y方向的角度的最小值public float maxAngleAtY = 90.0f;       //摄像机在Y方向的角度的最大值Quaternion rotation;//摄像机的旋转角度void Start () {distance = DISTANCE_DEAFULT;transTarget = GameObject.FindGameObjectWithTag("Player").transform;vLooker = new Vector3(transTarget.position.x, transTarget.position.y + target_offsety, transTarget.position.z);//rotation = transform.rotation;rotateXY.y = transform.eulerAngles.x;//摄像机转x欧拉角,会发现主相机上下动rotateXY.x = transform.eulerAngles.y;//摄像机转y欧拉角,会发现相机左右动transform.position = transTarget.position + rotation * Vector3.back * distance; //四元数乘以向量的意义,重点transform.LookAt(vLooker);//一直看着某个点
}void Update(){vLooker = transTarget.position;vLooker.y += 0.5f;// transform.position = transTarget.position + rotation * Vector3.back * distance; ;//按下鼠标右键if (Input.GetMouseButton(1))//0:左键,1:右键,2:中键{float x = Input.GetAxis("Mouse X");//鼠标在X方向上的移动,控制Y轴的旋转float y = Input.GetAxis("Mouse Y");//鼠标在Y方向上的移动,控制X轴的旋转rotateXY.x += speedAngelX * Time.deltaTime * x;//容易理解鼠标左右,上下移动时候的数据改变rotateXY.y -= speedAngelY * Time.deltaTime * y;rotateXY.y = Mathf.Clamp(rotateXY.y, minAngleAtY, maxAngleAtY);//在最小值和最大值之间取值,因为抬头低头总会有角度限制的rotation = Quaternion.Euler(rotateXY.y, rotateXY.x, 0);//值又交换回来了。transform.rotation = rotation;}transform.position = transTarget.position + rotation * Vector3.back * distance;
}void LateUpdate()//射线的碰撞检测{if (transTarget){//vLooker = transTarget.position;//vLooker.y += 0.5f;//transform.position = transTarget.position + rotation * Vector3.back * distance; ;按下鼠标右键//if (Input.GetMouseButton(1))//0:左键,1:右键,2:中键//{//    float x = Input.GetAxis("Mouse X");//鼠标在X方向上的移动,控制Y轴的旋转//    float y = Input.GetAxis("Mouse Y");//鼠标在Y方向上的移动,控制X轴的旋转//    rotateXY.x += speedAngelX * Time.deltaTime * x;//    rotateXY.y -= speedAngelY * Time.deltaTime * y;//    rotateXY.y = Mathf.Clamp(rotateXY.y, minAngleAtY, maxAngleAtY);//在最小值和最大值之间取值//    rotation = Quaternion.Euler(rotateXY.y, rotateXY.x, 0);//    transform.rotation = rotation;//    transform.position = transTarget.position + rotation * Vector3.back * distance; ;//}RaycastHit[] hits = Physics.RaycastAll(new Ray(vLooker, (transform.position - vLooker).normalized));distance = DISTANCE_DEAFULT;List<RaycastHit> listHits=new List<RaycastHit>(hits);foreach (RaycastHit hit in listHits){if (hit.collider.gameObject.tag == "Player"){listHits.Remove(hit);break;}}if (listHits.Count > 0){RaycastHit stand = listHits[0];//剔除人物身上点之后,距离人最近的点foreach (RaycastHit hit in listHits){//if (hit.collider.gameObject.tag == "terrain")//{//    if (hit.distance < stand.distance)//    {//        stand = hit;//    }//}if (hit.distance < stand.distance){stand = hit;}}Debug.Log(stand.point + " " + stand.collider.gameObject.tag);string tag = stand.collider.gameObject.tag;distance = Vector3.Distance(stand.point, vLooker);if (distance > DISTANCE_DEAFULT){distance = DISTANCE_DEAFULT;}}Debug.DrawRay(vLooker, transform.position - vLooker, Color.red);Vector3 position = transTarget.position + rotation * Vector3.back * distance;position.y += 1.5f;//为了不让摄像机看到地下的东西transform.position = Vector3.Lerp(transform.position, position, 0.3f);transform.LookAt(vLooker);}}
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部