https://blog.csdn.net/qq_31411825/article/details/61623857

Unity 3d 实现物体跟随摄像机视野运动
Created by miccall (转载请注明出处 miccall.tech )
1. VR实现机器人导航
-
项目里要求一个机器人跟随在角色旁边,一直飞着,就像一个精灵一样,总在主角的身边,移动,转头,都要移动到合适的位置 。还得让他面向主角,今天就来实现这个样例 。
-

2. 问题思考
- 1. 物体移动到某个给定的位置(target)
- 2. 物体转动到面向摄像机
- 3. 出现在相机的视野当中
- 4. 自定义物体在摄影机的Screen中的位置

3.实现以及方法
-
移动的话 ,本来可以用动画来实现 ,因为动画还没有做好,我就用一个cube当作那个机器人做样例了 。
首先有个cube之后 ,给他放一个移动的脚本。这里我给他命名为PlayerTank 。
我们的目的就是让他运动到某个target ,所以我们得给他指定一个followTransform 。 同时还有他的移动速度和转动速度 。
为了使他移动不是很突兀,我的思路是他先转动到面向follow物体,然后在直线移动到给物体 。所以算法很快写好了 。

void LookTransform(Transform Mtransform)
{
Vector3 tarPos = Mtransform.position;
Vector3 dirRot = tarPos - transform.position;
Quaternion tarRot = Quaternion.LookRotation(dirRot);
transform.rotation = Quaternion.Slerp(transform.rotation, tarRot, rotSpeed * Time.deltaTime);
}

-
简单解释一下,就是先确定物体的位置,然后求出指向他的方向,并用插值的方法,让物体转动到面向指定的物体 。
好了,既然有了朝向的运动方向,那么走到这方向,就很简单了。
-

transform.Translate(new Vector3(0, 0, movementSpeed * Time.deltaTime));
1
-
那么什么时候停止运动呢 ,我想了一下,决定用位置的差来判断
就是
-

Vector3.Distance(transform.position, followTransform.position);
1
-
好了,既然停止的方法也有了,最后要解决的问题就是朝向摄像机了。
突然一想,这是问题么,对,这不是问题 ,哈哈,刚刚写的那个算法,给一个摄像机就解决了嘛 。
然后给出具体的判断逻辑 。
-

//该物体 接近要 到达的目标 指定位置后就停止
if (Vector3.Distance(transform.position, followTransform.position) < 3f)
{
//当物体道到位置时 让物体面 向摄像机
LookTransform(Camre);
return;
}
else
{
//让物体转向 将要运动 的方向
LookTransform(followTransform);
transform.Translate(new Vector3(0, 0, movementSpeed * Time.deltaTime));
}

-
这样就解决了物体移动到target了,下一步就是固定target的位置,让他在摄像机的固定位置了 。
新建一个脚本文件CameraView,挂在摄像机上。为了方便调试,我又用了FPS脚本,就是第一人称视角跟随鼠标转动,就跟cs里面的玩法一样,(百度一大推代码)。
第二个调试算法是一个国外大牛写的 ,他可以给定一个距离,画出摄像机的视野范围
-

-
这里我画了两个边 ,一个是距离摄像机8.5米 用黄色表示,距离摄像机12米的用红色表示。
应为篇幅问题和详略问题,这里不多解释这个算法,有兴趣的可以去研究一下,这里我们引用一下就行了。
-

Vector3[] GetCorners(float distance)
{
Vector3[] corners = new Vector3[4];

float halfFOV = (theCamera.fieldOfView * 0.5f) * Mathf.Deg2Rad;
float aspect = theCamera.aspect;

float height = distance * Mathf.Tan(halfFOV);
float width = height * aspect;

// UpperLeft
corners[0] = tx.position - (tx.right * width);
corners[0] += tx.up * height;
corners[0] += tx.forward * distance;

// UpperRight
corners[1] = tx.position + (tx.right * width);
corners[1] += tx.up * height;
corners[1] += tx.forward * distance;

// LowerLeft
corners[2] = tx.position - (tx.right * width);
corners[2] -= tx.up * height;
corners[2] += tx.forward * distance;

// LowerRight
corners[3] = tx.position + (tx.right * width);
corners[3] -= tx.up * height;
corners[3] += tx.forward * distance;

return corners;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void FindUpperCorners()
{
Vector3[] corners = GetCorners(upperDistance);
// for debugging
Debug.DrawLine(corners[0], corners[1], Color.yellow); // UpperLeft -> UpperRight
Debug.DrawLine(corners[1], corners[3], Color.yellow); // UpperRight -> LowerRight
Debug.DrawLine(corners[3], corners[2], Color.yellow); // LowerRight -> LowerLeft
Debug.DrawLine(corners[2], corners[0], Color.yellow); // LowerLeft -> UpperLeft
}
1
2
3
4
5
6
7
8
9
-
debug的时候,直接调用FindUpperCorners()就可以了 。
刚开始的时候 ,我就用的这个调试 ,给出一个位置,然后计算他的偏移量,调试了很久,没有一个良好的效果,我决定换个思路了 ,为了普遍大众 ,我还是把这个调试方法贴出来了,有需要的可以试试 。
第二个我就去翻api了 ,因为我貌似记得有个屏幕坐标和世界坐标转化的什么鬼方法来着。果然不出我所料,这个方法的确是相当的好用的呀 。
试了一下官方给的调试方法,画了一个点出来 。
-
1
2
3
4
5
6
void OnDrawGizmosSelected()
{
Vector3 p = theCamera.ScreenToWorldPoint(new Vector3(100, 200, 8));
Gizmos.color = Color.blue;
//target.position = p;
Gizmos.DrawSphere(p, 1F);
}
1
2
3
4
5
6
7
-
好了,就连我最后决定用的位置也标明了。
然后,我就写了一个很简单的方法来达到目的。
-
1
2
3
4
void maketarget()
{
Vector3 p = theCamera.ScreenToWorldPoint(new Vector3(RH, RV, upperDistance));
target.position = p;
}
1
2
3
4
5
-
写完我都吓了一跳 ,竟然如此简单。还是简单解释一下 ,RH 是水平偏移量,RV是垂直偏移量,upperDistance是距离摄像机的一个平面位置 。
接下来就是运行看效果了 。
-
1
2
3
4
4.中途出现的小BUG
-
莫名其妙的做圆周运动 ,然后我分析了线速度,角速度和半径的关系 ,然后总结出一个基本的规律,他应该是当运动到某个特定的位置 ,正好满足了圆周运动的关系,然后我们调整movementSpeed 和rotSpeed 的值,让他么尽可能的和Distance消除乘积关系,这样出现的几率就微乎其微了 。
感想 -- 其实unity和现实物理,理论物理 还是有很大的不同。
-
————————————————
版权声明:本文为CSDN博主「miccall」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_31411825/article/details/61623857

Unity 3d 实现物体跟随摄像机视野运动的更多相关文章

  1. Unity 3D还原Scene场景、市面多数游戏视角高度自定义、第三人称视角分离功能:平移、拖动、看向中心等

    Unity视角的高度自定义 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享. ...

  2. Unity 3D 简易制作摄像机围绕物体随鼠标旋转效果

    Unity 3D 简易制作摄像机围绕物体随鼠标旋转效果 梗概: 一. 摄像机围绕目标物体旋转, 即摄像机离目标物体有一定的距离且旋转轴心为该物体的位置. 二. 当目标物体被障碍物挡住后, 需要将摄像机 ...

  3. Unity3D实现摄像机视野的拉远拉近和跟随主角旋转效果

    在Unity官网教程SurvivalShooter(恶魔射手)中,只处理了主角跟随鼠标旋转,摄像机视野并没有旋转或通过滚轮实现视野的拉远拉近,一下是我的实现方法.   在教程中,主角的移动是通过    ...

  4. 3D FPS游戏中Player摄像机的运动

    最近遇到一些类似3D FPS的game play.针对这里面Player摄像机的运动的问题,随便总结一些东西以备参考.首先,对问题做一些的假设: Player摄像机在多数情况下在场景中的位置是固定的, ...

  5. Unity在UI界面上显示3D模型/物体,控制模型旋转

    Unity3D物体在UI界面的显示 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...

  6. Unity 3D使用GameObject创建一个简单的可移动物体

    于Unity 3D游戏的开发.游戏脚本需要3D模拟组合,该脚本将被写入阻力3D为了达到效果对象. 以下是一个小实例,使用Unity 3D实现一个可控制移动的小人.小人能够向前.向后.向左和向右移动. ...

  7. Unity 3D里相机的平滑跟随(转)

    1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 public class ...

  8. Unity 让物体朝摄像机观察方向移动,已摇杆方向转向

    using System.Collections;using System.Collections.Generic;using UnityEngine; [RequireComponent(typeo ...

  9. 【Unity】物体跟随鼠标移动

    需求:2D游戏中,需要物体跟随鼠标移动. 做法:其实思路也很简单,就是先获取到鼠标的坐标,然后赋值给目标物体即可. void Update(){ // 物体跟随鼠标移动 Vector2 mousePo ...

随机推荐

  1. 织梦dedecms是什么?

    织梦dedecms是什么?DedeCms是织梦内容管理系统(DedeCms)的简称, 以简单.实用.开源而闻名,是国内最知名的PHP开源网站管理系统,也是使用用户最多的PHP类CMS系统; DedeC ...

  2. 你再也不用使用 Redux、Mobx、Flux 等状态管理了

    Unstated Next readme 的中文翻译 前言 这个库的作者希望使用 React 内置 API ,直接实现状态管理的功能.看完这个库的说明后,没有想到代码可以这个玩.短短几行代码,仅仅使用 ...

  3. Linux 基础学习2

    目录 Linux 基础学习2 文件目录结构 文件命名规范 文件系统结构 linux应用程序的组成 绝对路径和相对路径 目录名和基名 切换目录 切换到家目录 切换到上一次的目录 显示当前的工作目录 列出 ...

  4. js两个变量互换值

    js两个变量交换值 这个问题看似很基础,但是有很多的实现方式,你知道的有多少呢,网上也有很多的方法,下面就来总结一下 中间变量(临时变量) 临时变量其实很好理解,通过一个中间变量进行交换值 var s ...

  5. gitlab异地备份并验证MD5值

    最近公司发生了蛮多事情的,唉,咱也不管问啊,好好干活吧 需求 把gitlab的备份文件异地备份一份,备份无论失败还是成功通知某邮箱 实现思路 先rsync文件过去,判断rsync这个步骤有没有成功,失 ...

  6. AutoMapper 初次使用心得

    本例以asp.net webform为例: 结构: 主要代码:AutoMapperConfig 类 public class AutoMapperConfig { public static void ...

  7. Python绘制拓扑图(无向图)、有向图、多重图。最短路径计算

    前言: 数学中,“图论”研究的是定点和边组成的图形. 计算机中,“网络拓扑”是数学概念中“图”的一个子集.因此,计算机网络拓扑图也可以由节点(即顶点)和链路(即边)来进行定义和绘制. 延伸: 无向图 ...

  8. 某位前辈的Image识图,,有点意思,先留存

    import PIL from PIL import Image def get_bin_table(threshold=155): ''' 获取灰度转二值的映射table 0表示黑色,1表示白色 ' ...

  9. 微信小程序 时间戳 转化为 日期格式

    util.js  : function transTime(unixtime) { var dateTime = new Date(parseInt(unixtime) * 1000) var yea ...

  10. Spring Boot 笔记 (2) - 使用 log4j2 记日志

    日志框架的选用 Spring 使用的默认日志框架是 logback, 默认情况下会采取默认的 autoconfiguration; 即便想对日志的一些配置进行修改也比较方便, 详细可以参考: Spri ...