u3d中相机常用跟随模式

     在学习游戏开发中,不同的游戏会有不同的摄像机跟随。本人学习了一段时间,封装出了几种摄像机的跟随脚本,基本都是可以直接挂载到摄像机上设置参数后即可直接使用的。

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万+

猜你喜欢

转载自blog.csdn.net/Icecoldless/article/details/84778306