zoukankan      html  css  js  c++  java
  • 在Unity3D中实现摄像机跟随的三种方法

    在设计第一人称射击游戏以及RPG游戏时,往往需要在主角身上或者近邻位置设置一个摄像机,使其能够跟随主角的移动,提升游戏体验,这里介绍三种实现摄像机跟随的方法。

           (一)固定摄像机方法,常用于RPG游戏

    第一种方法,在Unity的坐标系中,我将摄像机固定在主角头部上边靠后位置,这样,主角在移动过程中,摄像机也随着移动,最后在游戏场景中大概是这个样子:

            也就是说,摄像机相对于主角,总是在Vector3.forward方向上靠后一些,在Vector3.up方向上偏上一些。同时为了使摄像机的移动更加平滑,避免掉帧现象,引入差值函数Vector3.Lerp(),使摄像机的移动更加圆润。

             相关代码如下:

    1.  
      using UnityEngine;
    2.  
      using System.Collections;
    3.  
       
    4.  
      /// <summary>
    5.  
      /// Third person camera.
    6.  
      /// </summary>
    7.  
      public class TheThirdPersonCamera : MonoBehaviour
    8.  
      {
    9.  
      public float distanceAway=1.7f;
    10.  
      public float distanceUp=1.3f;
    11.  
      public float smooth=2f; // how smooth the camera movement is
    12.  
       
    13.  
      private Vector3 m_TargetPosition; // the position the camera is trying to be in)
    14.  
       
    15.  
      Transform follow; //the position of Player
    16.  
       
    17.  
      void Start(){
    18.  
      follow = GameObject.FindWithTag ("Player").transform;
    19.  
      }
    20.  
       
    21.  
      void LateUpdate ()
    22.  
      {
    23.  
      // setting the target position to be the correct offset from the
    24.  
      m_TargetPosition = follow.position + Vector3.up * distanceUp - follow.forward * distanceAway;
    25.  
       
    26.  
      // making a smooth transition between it's current position and the position it wants to be in
    27.  
      transform.position = Vector3.Lerp(transform.position, m_TargetPosition, Time.deltaTime * smooth);
    28.  
       
    29.  
      // make sure the camera is looking the right way!
    30.  
      transform.LookAt(follow);
    31.  
      }
    32.  
      }

         (二)摄像机替代主角方法,常用于第一人称射击

           如图所示,直接用摄像机替代主角视角,摄像机看到的便是玩家在游戏场景中看到的。首先在Hierachy视图中建立空物体作为Player,使其旋转方向与摄像机保持一致。

            相关代码如下:

    // 摄像机Transform
     
    1.  
      Transform m_camTransform;
    2.  
       
    3.  
      // 摄像机旋转角度
    4.  
      Vector3 m_camRot;
    5.  
       
    6.  
      // 摄像机高度(即表示主角的身高)
    7.  
      float m_camHeight = 1.4f;
    1.  
      void Start () {
    2.  
       
    3.  
      m_transform = this.transform;
    4.  
       
    5.  
       
    6.  
      // 获取摄像机
    7.  
      m_camTransform = Camera.main.transform;
    8.  
       
    9.  
      // 设置摄像机初始位置
    10.  
      m_camTransform.position = m_transform.TransformPoint(0, m_camHeight, 0); //摄像机初始位置从本地坐标转化成世界坐标,且在X-Z平面的初始位置
    11.  
       
    12.  
      // 设置摄像机的旋转方向与主角一致
    13.  
      m_camTransform.rotation = m_transform.rotation; //rotation为物体在世界坐标中的旋转角度,用Quaternion赋值
    14.  
      m_camRot = m_camTransform.eulerAngles; //在本游戏实例中用欧拉角表示旋转
    15.  
      }
    1.  
      void Control()
    2.  
          {
    3.  
       
    4.  
              //获取鼠标移动距离
    5.  
              float rh = Input.GetAxis("Mouse X");
    6.  
              float rv = Input.GetAxis("Mouse Y");
    7.  
       
    8.  
              // 旋转摄像机
    9.  
              m_camRot.x -= rv;
    10.  
              m_camRot.y += rh;
    11.  
              m_camTransform.eulerAngles = m_camRot; //通过改变XYZ轴的旋转改变欧拉角
    12.  
       
    13.  
              // 使主角的面向方向与摄像机一致
    14.  
              Vector3 camrot = m_camTransform.eulerAngles;
    15.  
              camrot.x = 0; camrot.z = 0;
    16.  
              m_transform.eulerAngles = camrot;
        }
     

          (三)类似于第一种方法

    此方法在学习制作一款坦克大战时用到,原理其实和第一种方法类似,只不过用到了正余弦函数。

        相关代码如下:

    1.  
      public float distance = 8;
    2.  
      //横向角度
    3.  
      public float rot = 0; //用弧度表示
    4.  
      //纵向角度
    5.  
      private float roll = 30f * Mathf.PI * 2 / 360; //弧度
    6.  
      //目标物体
    7.  
      private GameObject target;
    1.  
      void Start()
    2.  
      {
    3.  
      //找到坦克
    4.  
      target = GameObject.Find("Tank");
    5.  
       
    6.  
      }
     
    [html] view plain copy
     
     
    print?
    1. <code class="language-csharp">void LateUpdate()   
    2.     {  
    3.         //一些判断  
    4.         if (target == null)  
    5.             return;  
    6.         if (Camera.main == null)  
    7.             return;  
    8.         //目标的坐标  
    9.         Vector3 targetPos = target.transform.position;  
    10.         //用三角函数计算相机位置  
    11.         Vector3 cameraPos;  
    12.         float d = distance *Mathf.Cos (roll);  
    13.         float height = distance * Mathf.Sin(roll);  
    14.         cameraPos.x = targetPos.x +d * Mathf.Cos(rot);  
    15.         cameraPos.z = targetPos.z + d * Mathf.Sin(rot);  
    16.         cameraPos.y = targetPos.y + height;  
    17.         Camera.main.transform.position = cameraPos;  
    18.         //对准目标  
    19.         Camera.main.transform.LookAt(target.transform);  
    20.      }</code>  
  • 相关阅读:
    基础设计模式-04 复杂对象创建的建造器模式
    String,StringBuffer和StringBuilder
    js常用删除
    基础设计模式-03 从过滤器(Filter)校验链学习职责链模式
    基础设计模式-02 UML图
    注册全局方法,全局过滤器和全局组件
    py-faster-rcnn
    mac下编译cpu only caffe并用xCode建caffe工程
    OpenCV学习笔记(一)
    caffe生成voc格式lmdb
  • 原文地址:https://www.cnblogs.com/Dearmyh/p/9540573.html
Copyright © 2011-2022 走看看