欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Unity实现场景漫游相机

程序员文章站 2022-06-23 11:21:52
本文实例为大家分享了unity实现场景漫游相机的具体代码,供大家参考,具体内容如下前言拿到场景后总喜欢在场景里面玩一段时间,那这个脚本就是你的不二选择代码里加了注释,改起来也很方便。使用方法把脚本拖拽...

本文实例为大家分享了unity实现场景漫游相机的具体代码,供大家参考,具体内容如下

前言

拿到场景后总喜欢在场景里面玩一段时间,那这个脚本就是你的不二选择
代码里加了注释,改起来也很方便。

使用方法

把脚本拖拽到场景相机上,开箱即用。

  • wasd前后左右移动
  • qe为上下
  • shift加速
  • 鼠标右键按住旋转视角
  • esc退出游戏

源码

#if enable_input_system && enable_input_system_package
#define use_input_system
 using unityengine.inputsystem;
 using unityengine.inputsystem.controls;
#endif

using unityengine;

 public class simplecameracontroller : monobehaviour
 {
  #region 相机状态
  /// <summary>
  /// 相机状态
  /// </summary>
  class camerastate
  {
   public float yaw;
   public float pitch;
   public float roll;
   public float x;
   public float y;
   public float z;

   public void setfromtransform(transform t)
   {
    pitch = t.eulerangles.x;
    yaw = t.eulerangles.y;
    roll = t.eulerangles.z;
    x = t.position.x;
    y = t.position.y;
    z = t.position.z;
   }

   public void translate(vector3 translation)
   {
    vector3 rotatedtranslation = quaternion.euler(pitch, yaw, roll) * translation;

    x += rotatedtranslation.x;
    y += rotatedtranslation.y;
    z += rotatedtranslation.z;
   }

   public void lerptowards(camerastate target, float positionlerppct, float rotationlerppct)
   {
    yaw = mathf.lerp(yaw, target.yaw, rotationlerppct);
    pitch = mathf.lerp(pitch, target.pitch, rotationlerppct);
    roll = mathf.lerp(roll, target.roll, rotationlerppct);
    
    x = mathf.lerp(x, target.x, positionlerppct);
    y = mathf.lerp(y, target.y, positionlerppct);
    z = mathf.lerp(z, target.z, positionlerppct);
   }

   public void updatetransform(transform t)
   {
    t.eulerangles = new vector3(pitch, yaw, roll);
    t.position = new vector3(x, y, z);
   }
  }
  #endregion

  camerastate m_targetcamerastate = new camerastate();
  camerastate m_interpolatingcamerastate = new camerastate();

  [header("movement settings 移动设置")]
  [tooltip("exponential boost factor on translation, controllable by mouse wheel. 平移的指数增强因子,可通过鼠标滚轮控制。")]
  public float boost = 3.5f;

  [tooltip("time it takes to interpolate camera position 99% of the way to the target. 将相机位置插值到目标位置99%所需的时间。"), range(0.001f, 1f)]
  public float positionlerptime = 0.2f;

  [header("rotation settings 旋转设定")]
  [tooltip("x = change in mouse position. 改变鼠标位置。\ny = multiplicative factor for camera rotation. 相机旋转的乘性因子。")]
  public animationcurve mousesensitivitycurve = new animationcurve(new keyframe(0f, 0.5f, 0f, 5f), new keyframe(1f, 2.5f, 0f, 0f));

  [tooltip("time it takes to interpolate camera rotation 99% of the way to the target. 插值相机旋转99%到目标所需的时间。"), range(0.001f, 1f)]
  public float rotationlerptime = 0.01f;

  [tooltip("whether or not to invert our y axis for mouse input to rotation. 是否将鼠标输入的y轴反转为旋转。")]
  public bool inverty = false;

  void onenable()
  {
   m_targetcamerastate.setfromtransform(transform);
   m_interpolatingcamerastate.setfromtransform(transform);
  }

  vector3 getinputtranslationdirection()
  {
   vector3 direction = new vector3();
   if (input.getkey(keycode.w))
   {
    direction += vector3.forward;
   }
   if (input.getkey(keycode.s))
   {
    direction += vector3.back;
   }
   if (input.getkey(keycode.a))
   {
    direction += vector3.left;
   }
   if (input.getkey(keycode.d))
   {
    direction += vector3.right;
   }
   if (input.getkey(keycode.q))
   {
    direction += vector3.down;
   }
   if (input.getkey(keycode.e))
   {
    direction += vector3.up;
   }
   return direction;
  }
  
  void update()
  {
   vector3 translation = vector3.zero;

#if enable_legacy_input_manager

   // exit sample 按下esc键退出游戏
   if (input.getkey(keycode.escape))
   {
    application.quit();
 #if unity_editor
 unityeditor.editorapplication.isplaying = false; 
 #endif
   }
   // hide and lock cursor when right mouse button pressed 按下鼠标右键时隐藏并锁定光标
   if (input.getmousebuttondown(1))
   {
    cursor.lockstate = cursorlockmode.locked;
   }

   // unlock and show cursor when right mouse button released 松开鼠标右键时解锁并显示光标
   if (input.getmousebuttonup(1))
   {
    cursor.visible = true;
    cursor.lockstate = cursorlockmode.none;
   }

   // rotation 旋转
   if (input.getmousebutton(1))
   {
    var mousemovement = new vector2(input.getaxis("mouse x"), input.getaxis("mouse y") * (inverty ? 1 : -1));
    
    var mousesensitivityfactor = mousesensitivitycurve.evaluate(mousemovement.magnitude);

    m_targetcamerastate.yaw += mousemovement.x * mousesensitivityfactor;
    m_targetcamerastate.pitch += mousemovement.y * mousesensitivityfactor;
   }
   
   // translation 移动
   translation = getinputtranslationdirection() * time.deltatime;

   // speed up movement when shift key held 按住shift键时加速移动
   if (input.getkey(keycode.leftshift))
   {
    //原速度*10为按下shift后的速度
    translation *= 10.0f;
   }

   // modify movement by a boost factor (defined in inspector and modified in play mode through the mouse scroll wheel) 通过增强因子修改移动(在检查器中定义,通过鼠标滚轮在播放模式下修改)
   boost += input.mousescrolldelta.y * 0.2f;
   translation *= mathf.pow(2.0f, boost);

#elif use_input_system 
   // todo: make the new input system work 使新的输入系统正常工作
#endif

   m_targetcamerastate.translate(translation);

   // framerate-independent interpolation 帧率无关插值
   // calculate the lerp amount, such that we get 99% of the way to our target in the specified time 计算lerp的数量,这样我们就可以在指定的时间内到达目标的99%
   var positionlerppct = 1f - mathf.exp((mathf.log(1f - 0.99f) / positionlerptime) * time.deltatime);
   var rotationlerppct = 1f - mathf.exp((mathf.log(1f - 0.99f) / rotationlerptime) * time.deltatime);
   m_interpolatingcamerastate.lerptowards(m_targetcamerastate, positionlerppct, rotationlerppct);

   m_interpolatingcamerastate.updatetransform(transform);
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

相关标签: Unity 相机