28 U3D 相机跟随

 相机跟随是Unity开发中比重相当大的一部分,许多地方都要相机跟随某一游戏物体进行追踪拍摄 固定相机跟随 这种相机有一个参考对象,它会保持与该参考对象固定的位置,跟随改参考对象发生移动.

using UnityEngine;
using System.Collections;

public class CameraFlow : MonoBehaviour
{
//相机跟随的目标
    public Transform target;
//相机在跟随过程中与跟随目标之间的距离
    private Vector3 offset;
  
    void Start()
    {
//初始化相机与跟随对象之间的距离
        offset = target.position - this.transform.position;

    }

    void Update()
    {
//在游戏过程中,摄像机始终保持在玩家的某个位置
        this.transform.position = target.position - offset;
    }
}

固定相机跟随,带有角度旋转 这一种相机跟随是对第一种相机跟随的改进,在原有基础上面,添加了跟随角度的控制

using UnityEngine;
using System.Collections;

public class CameriaTrack : MonoBehaviour {
    private Vector3 offset = new Vector3(0,5,4);//相机相对于玩家的位置
    private Transform target;
    private Vector3 pos;

    public float speed = 2;

    // Use this for initialization
    void Start () {
        target = GameObject.FindGameObjectWithTag("Player").transform;

    }

    // Update is called once per frame
    void Update () {
        pos = target.position + offset;
        this.transform.position = Vector3.Lerp(this.transform.position, pos, speed*Time.deltaTime);//调整相机与玩家之间的距离
        Quaternion angel = Quaternion.LookRotation(target.position - this.transform.position);//获取旋转角度
        this.transform.rotation = Quaternion.Slerp(this.transform.rotation, angel, speed * Time.deltaTime);

    }
}

第三人称相机 这种相机跟随,是第三人称角度看向对象的,也就是一直看向对象的后面,如一直显示玩家的后背

using UnityEngine;
using System.Collections;
//相机一直拍摄主角的后背
public class CameraFlow : MonoBehaviour {

    public Transform target;

    public float distanceUp=15f;
    public float distanceAway = 10f;
    public float smooth = 2f;//位置平滑移动值
    public float camDepthSmooth = 5f;
   
    void Start () {

    }

   
    void Update () {
       // 鼠标轴控制相机的远近
        if ((Input.mouseScrollDelta.y < 0 && Camera.main.fieldOfView >= 3) || Input.mouseScrollDelta.y > 0 && Camera.main.fieldOfView <= 80)
        {
            Camera.main.fieldOfView += Input.mouseScrollDelta.y * camDepthSmooth * Time.deltaTime;
        }

    }

    void LateUpdate()
    {
       //相机的位置
        Vector3 disPos = target.position + Vector3.up * distanceUp - target.forward * distanceAway;
        transform.position=Vector3.Lerp(transform.position,disPos,Time.deltaTime*smooth);
        //相机的角度
        transform.LookAt(target.position);
    }


}

相机跟随,鼠标控制移动和缩放 相机与观察对象保持一定距离,可以通过鼠标进行上下左右旋转,通过鼠标滚轮进行放大和缩小操作

using UnityEngine;
using System.Collections;

public class CameraFlow : MonoBehaviour
{
    public Transform target;
    Vector3 offset;
   
    void Start()
    {
        offset = transform.position - target.position;
    }

    void Update()
    {
        transform.position = target.position + offset;
        Rotate();
        Scale();
    }
    //缩放
    private void Scale()
    {
        float dis = offset.magnitude;
        dis += Input.GetAxis("Mouse ScrollWheel") * 5;
        Debug.Log("dis=" + dis);
        if (dis < 10 || dis > 40)
        {
            return;
        }
        offset = offset.normalized * dis;
    }
    //左右上下移动
    private void Rotate()
    {
        if (Input.GetMouseButton(1))
        {
            Vector3 pos = transform.position;
            Vector3 rot = transform.eulerAngles;

            //围绕原点旋转,也可以将Vector3.zero改为 target.position,就是围绕观察对象旋转
            transform.RotateAround(Vector3.zero, Vector3.up, Input.GetAxis("Mouse X") * 10);
            transform.RotateAround(Vector3.zero, Vector3.left, Input.GetAxis("Mouse Y") * 10);
            float x = transform.eulerAngles.x;
            float y = transform.eulerAngles.y;
            Debug.Log("x=" + x);
            Debug.Log("y=" + y);
            //控制移动范围
            if (x < 20 || x > 45 || y < 0 || y > 40)
            {
                transform.position = pos;
                transform.eulerAngles = rot;
            }
            //  更新相对差值
            offset = transform.position - target.position;
        }
    }
}

使用Input.GetAxis("Mouse X") * 10)或Input.GetAxis("Mouse Y") * 10)一定在Unity编辑其中要有设置设置步骤为Edit -> Project Setting -> Input 设置

“Mouse Y”的设置与其相同,只是将获得的值所在轴改为Y axis 相机跟随玩家拍摄,当有障碍物时相机会自动检测移动到可以拍到玩家的位置。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 该脚本事项让摄像机跟随玩家移动,如果摄像机不能检测到玩家
/// 摄像机就会不停移动,值到拍摄到玩家为止
/// </summary>
public class CameraMoveScript13 : MonoBehaviour
{

    //摄像机移动的速度
    public float moveSpeed = 3f;
    //摄像机旋转的速度
    public float turnSpeed = 10f;
    //玩家的位置
    Transform player;
    //摄像机和玩家之间的方向向量
    Vector3 direction;
    //射线碰撞信息
    RaycastHit hit;
    //当摄像机拍摄不到玩家时,需要移动的点
    Vector3[] currentPoints;
    //摄像机与玩家之间的最小距离
    float distance;

    void Awake ()
    {
        //初始化
        player = GameObject.FindGameObjectWithTag (Tags.Player).transform;
        currentPoints = new Vector3[5];
    }

    void Start ()
    {
        //计算摄像机和玩家之间的距离
        distance = Vector3.Distance (transform.position, player.position) - 0.5f;
        //游戏开始时,玩家和摄像机之间的方向向量
        direction = player.position - transform.position;
    }

    //处理摄像机的位置、旋转
    void LateUpdate ()
    {
        //根据五点画线法,通过五个点就可以任意一条弧线

        //第一个点
        //看是位置相对于玩家一直是固定的
        Vector3 startPoint = player.position - direction;
        //最后一个点
        Vector3 endPoint = player.position + Vector3.up * distance;
        //第二个点
        currentPoints [1] = Vector3.Lerp (startPoint, endPoint, 0.25f);
        //第三个点
        currentPoints [2] = Vector3.Lerp (startPoint, endPoint, 0.5f);
        //第四个点
        currentPoints [3] = Vector3.Lerp (startPoint, endPoint, 0.75f);
        //将开始点和结束点放到数组中
        currentPoints [0] = startPoint;
        currentPoints [4] = endPoint;

        //定义一个点,假设这个点是摄像机可以看到玩家的点
        //假设这个点是第一个点(也就是说假设一开始没有障碍物)
        Vector3 viewPoint = currentPoints [0];

        //循环检测该点
        for (int i = 0; i < currentPoints.Length; i++) {
            if (CheckView (currentPoints [i])) {
                //更新能够看到玩家的点
                viewPoint = currentPoints [i];
                break;
            }
        }
        //摄像机移动到可以看到玩家的位置那个点上
        transform.position = Vector3.Lerp (transform.position, viewPoint, Time.deltaTime * moveSpeed);
        //旋转
        SmoothRotate ();


    }

    //对某个点进行检测,判断该点是否可以看到玩家
    bool CheckView (Vector3 pos)
    {
        //玩家到摄像机的方向向量,这里pos是摄像机移动到的点
        Vector3 dir = player.position - pos;
        //从pos的位置发出一条射线
        if (Physics.Raycast (pos, dir, out hit)) {
            //如果射线碰到的是玩家,说明当前可以看到玩家
            if (hit.collider.tag == Tags.Player) {
                return true;
            }
        }
        return false;
    }

    //摄像机到达目标点后旋转
    void SmoothRotate ()
    {
        //摄像机拍摄到玩家身上的位置(设置为玩家位置上方0.2的位置)
        //获得摄像机到拍摄点的方向
        Vector3 dir = player.position + Vector3.up * 0.2f - transform.position;

        //摄像机的旋转角度
        Quaternion qua = Quaternion.LookRotation (dir);

        //平滑旋转
        transform.rotation = Quaternion.Lerp (transform.rotation, qua, Time.deltaTime * turnSpeed);

        //优化Y轴和Z轴上的旋转(这里摄像机只让它在X轴上旋转)
        transform.eulerAngles = new Vector3 (transform.eulerAngles.x, 0, 0);

    }
}

(  万象解锁的方法)

 public static CameraControllerScriptc Instance;

    void Awake ()
    {
        Instance = this;
    }

    public Transform m_lookAt;
    //朝向
    public void LookTarget (Vector3 position)
    {
        m_lookAt.LookAt (position);
    }
    //跟随
    public void FollowTarget (Vector3 position)
    {
        transform.position = position;
    }

          万象解锁设置

在玩家身上添加代码
   //实现摄像机的跟随
        CameraControllerScriptc.Instance.LookTarget (transform.position);
        CameraControllerScriptc.Instance.FollowTarget (transform.position);

猜你喜欢

转载自www.cnblogs.com/zpy1993-09/p/13206116.html