在学习游戏开发中,不同的游戏会有不同的摄像机跟随。本人学习了一段时间,封装出了几种摄像机的跟随脚本,基本都是可以直接挂载到摄像机上设置参数后即可直接使用的。
1.最简单的跟随模式
仅仅只是与player的位置保持不变,无法旋转,适用于直线型的无尽跑酷游戏中。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowPlayer : MonoBehaviour {
public Transform Player;
Vector3 offset;
void Start()
{
offset = transform.position - Player.position;
}
void Update()
{
transform.position = offset + Player.position;
}
}
2.FPS模式
能够始终保持在player头上的某一点上,始终以第一人称的视角观看,承接了上一个的保持与player的相对位置不变的情况下添加了摄像机的旋转,可以进行鼠标交互做出摄像机相应的变化,上下滑动,左右滑动等。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 第一人称射击游戏主角的摄像机跟随
/// </summary>
public class FollowPlayerFPS: MonoBehaviour
{
public Transform Player;
[HideInInspector]
public Transform Tran;
Vector3 offset;
//摄像机跟随鼠标的上下左右移动而旋转
Vector3 camRot;
public float RotSpeed = 10; //滚动的速度,越大滚动鼠标时摄像机的旋转的也越快。
public Vector3 RotClamp; //摄像机旋转的临界点在这里修改
void Start()
{
offset = transform.position - Player.position;
Tran = transform;
Tran.rotation = Player.rotation;
}
void Update()
{
Tran.position = offset + Player.position;
CamRotate();
}
void CamRotate()
{
float hr = -Input.GetAxis("Mouse Y");
float vr = Input.GetAxis("Mouse X");
if (hr != 0)
{
camRot.x += hr;
}
if (vr != 0)
{
camRot.y += vr;
}
Vector3 newAngles = camRot * RotSpeed;
newAngles.x = Mathf.Clamp(newAngles.x, RotClamp.x, -RotClamp.x);
newAngles.y = Mathf.Clamp(newAngles.y, -RotClamp.y, RotClamp.y);
Tran.eulerAngles = newAngles; //通过eulerAngles来修改Transform的rotation值
}
}
3.第三人称模式
可以指定与player的相对水平距离以及高度,通过线性插值来更新与player的相对距离,始终看向player,所以旋转值会因为player的变化而变化。
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
/***
* Title:
* Description:
*/
public class CameraMoverRpg:MonoBehaviour
{
public Transform PlayerTran;
public float SmoothingValue = 1f;
public float DistanceUp; //高度
public float DistanceAway; //水平
Vector3 m_TargetPos;
[HideInInspector]
public Transform Tran;
private void Start()
{
Tran = transform;
}
private void LateUpdate()
{
m_TargetPos = PlayerTran.position+Vector3.up*DistanceUp-PlayerTran.forward*DistanceAway;
Tran.position = Vector3.Lerp(Tran.position,m_TargetPos,SmoothingValue*Time.deltaTime);
Tran.LookAt(PlayerTran);
}
}
4.UI上摄像机的跟随
适用于大地图上时候的鼠标向上拉,向下拉,滑轮向前滚和向后滚。默认UI视图刚开始时就是景深最大,观察范围最远,x,y边界值最小的时候。
/***
* Title:
* TD
* Description:
移动摄像机
按住鼠标左键移动摄像机
并且确保摄像机一直看住一个地方(观察点不变)
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class MoveCamera : MonoBehaviour {
float m_VX;
float m_VY;
[HideInInspector]
public Transform Tran;
public Transform TargetTran;
public Boundary Boundary;
public Vector3 m_Rot = new Vector3(55,0,0); //确保摄像机在移动的过程中不会发生自己的旋转
Vector3 m_Offset;
public float MaxLookDis= 15.32971f; //深度看的最远处
public float MinLookDis= 3; //深度看的最近处
float m_Distance;
public float ScrollSpeed = 10; // 滚动速度
public float MoveSpeed = 10; //移动速度
Camera m_Cam;
float m_InitScrollX;
float m_InitScrollY;
private void Awake()
{
Tran = transform;
}
private void Start()
{
m_Cam = Tran.GetComponent<Camera>();
m_Offset = Tran.position-TargetTran.position;
Follow();
m_InitScrollX = Boundary.xMin;
m_InitScrollY = Boundary.yMin;
}
private void Update()
{
Control();
//ScrollView();
ScrollViewFromPro();
Follow();
}
void Follow()
{
Tran.position = TargetTran.position+m_Offset;
Tran.LookAt(TargetTran);
Tran.eulerAngles = m_Rot;
}
void Control()
{
if (Input.GetMouseButton(0)&&!EventSystem.current.IsPointerOverGameObject(0))
{
float mx = Input.GetAxis("Mouse X");
float my = Input.GetAxis("Mouse Y");
if (mx != 0 || my != 0)
{
TargetTran.Translate(new Vector3(-mx, -my, 0)*MoveSpeed, Space.World);
}
}
}
//根据深度 z值
void ScrollView()
{
m_Distance = m_Offset.magnitude;
m_Distance -= Input.GetAxis("Mouse ScrollWheel")*ScrollSpeed;
m_Distance = Mathf.Clamp(m_Distance,MinLookDis,MaxLookDis);
m_Offset = m_Distance * m_Offset.normalized;
}
//根据摄像机属性景深
void ScrollViewFromPro()
{
m_Cam.fieldOfView-= Input.GetAxis("Mouse ScrollWheel") * ScrollSpeed;
m_Cam.fieldOfView = Mathf.Clamp(m_Cam.fieldOfView,30,60);
float factor = m_Cam.fieldOfView / 60;
Boundary.xMin = m_InitScrollX*factor; //根据相似三角形可得比例相等
Boundary.xMax = m_InitScrollX*2-Boundary.xMin;
Boundary.yMin = m_InitScrollY* factor;
Boundary.YMax = m_InitScrollY*2-Boundary.yMin;
DetectBoundary();
}
void DetectBoundary()
{
Vector3 temp = TargetTran.position;
if (temp.y > Boundary.YMax)
{
temp.y = Boundary.YMax;
TargetTran.position = temp;
}
if (temp.y < Boundary.yMin)
{
temp.y = Boundary.yMin;
TargetTran.position = temp;
}
if (temp.x > Boundary.xMax)
{
temp.x = Boundary.xMax;
TargetTran.position = temp;
}
if (temp.x < Boundary.xMin)
{
temp.x = Boundary.xMin;
TargetTran.position = temp;
}
}
}
本人新手,如有不对,欢迎指出。
我爱路飞... 发布了66 篇原创文章 · 获赞 7 · 访问量 1万+ 私信 关注