当前位置:   article > 正文

Unity开发技巧之摄像机跟随_摄像机跟随目标物体 目标旋转 求摄像机的位置

摄像机跟随目标物体 目标旋转 求摄像机的位置

前言

游戏开发中,不可避免地会涉及摄像机的跟随和控制,摄像机的位置以及角度朝向都需要在不断的调试中,以确认出对玩家比较友好的方案。本篇中将讨论几种在Unity3D中摄像机跟随的方案。

方案一:作为目标的子物体跟随目标的进行空间坐标变换

如字面意思,将摄像机作为需要跟随的目标的子物体,在操纵目标进行移动旋转时,摄像机也会跟随父物体进行移动旋转。

    

优点:简单直观,不需要写代码。

不足:由于是跟随父物体一起运动,会随着父物体的旋转而旋转,当父物体的旋转不当时,摄像机的角度无法进行调整。

方案二:利用三角函数关系求得摄像机位置,并时刻跟随目标

这里有几个参数需要介绍一下

水平偏移角度:摄像机在x轴和z轴平面中,与目标位置形成的角度

垂直偏移角度:摄像机在x轴和y轴平面中,与目标位置形成的角度

距离:摄像机与目标之间的距离

现在我们分别从水平平面和垂直平面中求得摄像机的x、y、z坐标。

垂直平面

height = distance * Mathf.Sin(roll)

temp= distance * Mathf.Cos(roll)

在垂直平面中,我们求得摄像机距目标的相对高度,即摄像机的y坐标,和求x、z坐标的一个中间值

水平平面

cameraPos.x = targetPos.x + temp * Mathf.Cos(rot);
cameraPos.z = targetPos.z + temp * Mathf.Sin(rot);

通过中间值temp,我们便可以求得摄像机的x、z坐标

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class CameraFollow : MonoBehaviour {
  5. //距离
  6. public float distance = 8;
  7. //横向角度
  8. public float rot = 0;
  9. //纵向角度
  10. private float roll = 30f * Mathf.PI * 2 / 360;
  11. //目标物体
  12. private GameObject target;
  13. //横向旋转速度
  14. public float rotSpeed = 0.2f;
  15. //纵向角度范围
  16. private float maxRoll = 70f * Mathf.PI * 2 / 360;
  17. private float minRoll = -10f * Mathf.PI * 2 / 360;
  18. //纵向旋转速度
  19. private float rollSpeed = 0.2f;
  20. //距离范围
  21. public float maxDistance = 22f;
  22. public float minDistance = 5f;
  23. //距离变化速度
  24. public float zoomSpeed = 0.2f;
  25. void Start() {
  26. //找到坦克
  27. //SetTarget(GameObject.Find("tank"));
  28. }
  29. void LateUpdate() {
  30. //一些判断
  31. if (target == null)
  32. return;
  33. if (Camera.main == null)
  34. return;
  35. //目标的坐标
  36. Vector3 targetPos = target.transform.position;
  37. //用三角函数计算相机位置
  38. Vector3 cameraPos;
  39. float d = distance * Mathf.Cos(roll);
  40. float height = distance * Mathf.Sin(roll);
  41. cameraPos.x = targetPos.x + d * Mathf.Cos(rot);
  42. cameraPos.z = targetPos.z + d * Mathf.Sin(rot);
  43. cameraPos.y = targetPos.y + height;
  44. Camera.main.transform.position = cameraPos;
  45. //对准目标
  46. Camera.main.transform.LookAt(target.transform);
  47. //横向旋转
  48. Rotate();
  49. //纵向旋转
  50. Roll();
  51. //调整距离
  52. Zoom();
  53. }
  54. //设置目标
  55. public void SetTarget(GameObject target) {
  56. if (target.transform.Find("cameraPoint") != null)
  57. this.target = target.transform.Find("cameraPoint").gameObject;
  58. else
  59. this.target = target;
  60. }
  61. //横向旋转
  62. void Rotate() {
  63. float w = Input.GetAxis("Mouse X") * rotSpeed;
  64. rot -= w;
  65. }
  66. //纵向旋转
  67. void Roll() {
  68. float w = Input.GetAxis("Mouse Y") * rollSpeed * 0.5f;
  69. roll -= w;
  70. if (roll > maxRoll)
  71. roll = maxRoll;
  72. if (roll < minRoll)
  73. roll = minRoll;
  74. }
  75. //调整距离
  76. void Zoom() {
  77. if (Input.GetAxis("Mouse ScrollWheel") > 0) {
  78. if (distance > minDistance)
  79. distance -= zoomSpeed;
  80. } else if (Input.GetAxis("Mouse ScrollWheel") < 0) {
  81. if (distance < maxDistance)
  82. distance += zoomSpeed;
  83. }
  84. }
  85. }

 优点:比较严谨摄像机跟随方案,可进行进一步的摄像机控制,例如视角的操控

缺点:实现过程稍麻烦,需要理解摄像机与跟随目标的三角函数关系

方案三:利用向量的插值运算与四元数

  • 先计算出摄像机与目标的相对位置

Vector3 TargetPos = new Vector3(0, 3f, -3f);
transform.position = Vector3.Lerp(transform.position, playerTransform.position + TargetPos, speed * Time.deltaTime);

使用Lerp函数是为了摄像机移动的更平滑些。

  • 然后通过四元素进行视角的注视

Quaternion TargetRotation = Quaternion.LookRotation(playerTransform.position - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, TargetRotation, speed * Time.deltaTime);

使用Slerp函数与使用Lerp函数同理

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class FollowPlayer : MonoBehaviour
  5. {
  6. public float speed = 2f;
  7. private Transform playerTransform;
  8. void Start ()
  9. {
  10. playerTransform = GameObject.FindGameObjectWithTag("Player").transform;
  11. }
  12. void Update ()
  13. {
  14. if (playerTransform == null)
  15. return;
  16. Vector3 TargetPos = new Vector3(0, 3f, -3f);
  17. transform.position = Vector3.Lerp(transform.position, playerTransform.position + TargetPos, speed * Time.deltaTime);
  18. Quaternion TargetRotation = Quaternion.LookRotation(playerTransform.position - transform.position);
  19. transform.rotation = Quaternion.Slerp(transform.rotation, TargetRotation, speed * Time.deltaTime);
  20. }
  21. }

优点:代码实现简单,可以做出不错的摄像机跟随效果。

不足:不便于进行视角的操控

总结

由于博主能力有限,在学习过程中,总结了这三种摄像机跟随的实现方案,实现是比较简单的,而且能满足基本的需求。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/122989
推荐阅读
相关标签
  

闽ICP备14008679号