zoukankan      html  css  js  c++  java
  • 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);
  • 相关阅读:
    lostash 正则
    Mysql 利用multiline 实现多行匹配
    java中byte, int的转换
    mysql perl 抓取update语句
    $/ 改变换行符
    mysql 匹配update
    perl binlog dml操作报告
    mysql 分区 按 PARTITION BY RANGE (TO_DAYS(startTime))
    Mysql explain 查看分区表
    写作的力道——北漂18年(番外篇一)
  • 原文地址:https://www.cnblogs.com/zpy1993-09/p/13206116.html
Copyright © 2011-2022 走看看