技术标签: unity 游戏程序 游戏引擎 【Unity】300个小技巧
在游戏开发中,如何移动物体?是我们需要思考的事情。
Unity 引擎也提供了众多的方法,每个开发者的使用习惯也各不相同,所以往往不是很清楚在这种场景下哪种方式最好的或者最有效的。
那么,这篇文章,我想分享一下移动物体的一些方法和优缺点。
如何优雅地移动物体?8个方法
众所周知,我们可以给对象的Transform
组件赋予一个坐标来决定其位置。
transform.position = new Vector3(2, 1, 0);
当我们每一帧给对象赋予一个新的坐标,那么看起来,这个物体就是在运动的。
void Update()
{
var dir = new Vector3(0.02f, 0, 0);
transform.position += dir;
}
效果如下:
由于直接改变 Position 属性看起来不太优雅。所以 Transform
组件提供了一个更友好的方法:Transform.Translate()
。
void Update()
{
var dir = new Vector3(0.02f, 0, 0);
transform.Translate(dir);
}
其实,他的内部与 Transform.Position
无异。
public void Translate(Vector3 translation, [DefaultValue("Space.Self")] Space relativeTo)
{
if (relativeTo == Space.World)
this.position += translation;
else
this.position += this.TransformDirection(translation);
}
效果与 Transform.Position 一致
但是这种方法产生了一个问题。由于设备之间的差异或者动态数据的变化会导致每一帧之间的间隔是不相等的,因此,如果以帧数来控制物体移动,物体的移动距离就没办法准确把握。
效果如下
所以我们需要在原来的基础上乘以 Time.deltaTime
属性的值,从而保证每秒移动的距离是一致的。
void Update()
{
var dir = new Vector3(2f, 0, 0)*time;
transform.Translate(dir);
}
这样不同的帧数移动距离都会一致。
效果如下:
但这还不够优雅。在游戏中,我们经常需要改变物体的速度。为了方便实现,我们通常会使用单位向量来确定方向,增加一个浮点值来控制速度。
public float speed = 2;
void Update()
{
var dir = new Vector3(2,0,0)
transform.Translate(dir.normalized * speed * Time.deltaTime);
}
移动到指定位置,大概有两种方式。
以固定的速度移动到目标位置
public Vector3 targetPosition;
public float speed=10;
void Update()
{
transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime);
}
效果:
又或者,我们可以用平滑的方式到达目标位置。(平滑:到达位置前提前减速)
public Vector3 targetPosition;
public float smoothTime = 0.5f;
public float speed = 10;
Vector3 velocity ;
void Update()
{
transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime, speed);
}
效果:
该方法的意思是在调用方法期间,已经过的时间除以总持续时间,得到当前的位移目标。
// 终点
public Vector3 targetPosition;
// 开始位置
public Vector3 startPosition;
// 持续时间
public float lerpDuration = 4;
// 记录运行时间
private float _timeElapsed = 0;
void Start()
{
startPosition = transform.position;
}
void Update()
{
// 记录下一个位置
Vector3 valueToLerp;
_timeElapsed += Time.deltaTime;
if (_timeElapsed < lerpDuration)
{
valueToLerp = Vector3.Lerp(startPosition, targetPosition, _timeElapsed / lerpDuration);
}
else
{
valueToLerp = targetPosition;
}
transform.position = valueToLerp;
}
效果如下:
以上的这些方法足以让我们准确且随心的操纵物体移动。
但有一些场景,我们并不希望如此精确或始终如一的运动轨迹,我们想物体的移动受 Unity 的物理引擎影响或者其他物体影响。
同时如果用以上方法移动,在 Unity 的物理引擎下会出现抖动,穿过刚体等奇怪的现象。
那么接下来,我们就需要用到一些涉及到物理引擎的移动方式。
使用这个方法给物体添加一个方向力。在力的作用下,物体将会移动。那么移动速度和位移就会与物理特效有关,比如物体质量,阻力,甚至还有重力。
一般会有两种使用方式。
在初始时给物体一个力,让其顺着物理规律下运动。使用场景一般时跳跃或者碰撞。
// 赋予200的力
public float force = 200;
private Rigidbody2D _rigidbody2D;
// 移动方向
private Vector3 dir = Vector3.right;
void Start()
{
_rigidbody2D = GetComponent<Rigidbody2D>();
_rigidbody2D.AddForce(Vector2.right * force);
}
为了更好演示刚体的运动,我还给刚体的线性阻力改为1,这样没有持续施加外力的情况下,物体会因为摩擦力的存在而停下。
效果如下:
可以看到物体很快就停下了
第二种,会在每一帧持续给物体施加力,使物体可以持续运动。
// 赋予2的力
public float force = 2;
private Rigidbody2D _rigidbody2D;
// 移动方向
private Vector3 dir = Vector3.right;
void Start()
{
_rigidbody2D = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
_rigidbody2D.AddForce(Vector2.right * force);
}
效果如下:
从效果可以看到,在持续给外力的作用下,物体移送越来越快,但在阻挡物前会停下。
直接赋予 Velocity 属性一个向量,可以立即改变物体的速度。一般情况下,我们不需要直接修改速度,除非你非常明确需要立即改变物体的速度。
public float speed = 10;
private Rigidbody2D _rigidbody2D;
// 移动方向
private Vector3 dir = Vector3.right;
void Start()
{
_rigidbody2D = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
_rigidbody2D.velocity = dir * speed;
}
效果如下:
看到物体一开始就已经有速度,而通过AddForce
方法添加力的物体,速度时慢慢提高的。
该方法有比较局限的使用场景,当物体的刚体类型是 Kinematic 时,使用Rigidbody.MovePosition()
方法进行移动。
因为 Kinematic 类型下,不会受到重力和AddForce、AddTorque等力相关的函数的影响!!!
public float speed = 10;
private Rigidbody2D _rigidbody2D;
// 移动方向
private Vector3 dir = Vector3.right;
void Start()
{
_rigidbody2D = GetComponent<Rigidbody2D>();
}
private void FixedUpdate()
{
var positon = dir * (speed * Time.deltaTime);
_rigidbody2D.MovePosition(transform.position + positon);
}
效果如下:
刚体类型是 Kinematic 时 ,会对刚体类型为 Dynamic 施加力,而无视 static 类型。
在文末,欢迎在评论区发表你的见解。如果觉得写的不错,可以给我点赞,鼓励一下,谢谢。
文章浏览阅读300次。50道经典的JAVA编程题(41-45),苦逼的程序猿,晚上睡不着了编程吧~今天坚持做10道题!发现编程能是我快乐。。。O(∩_∩)O哈哈~能平静我烦乱的心,剩下5道题留到考试完了再做吧!该睡觉了、、、【程序41】 MonkeyPeach.java题目:海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子凭据分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分..._java编程题目小新同学爱睡觉
文章浏览阅读671次。iTextSharp 是用来生成 PDF 的一个组件,在 1998 年夏天的时候,Bruno Lowagie ,iText 的创作者,参与了学校的一个项目,当时使用 HTML 来生成报告,但是,使用 HTML 打印的效果很不理想。最后,他发现,使用 PDF 可以完美解决打印问题,为了能够在各个系统中使用,iText 组件库诞生了。最初的 iText 主要是支持 Java 語言。之後針對M..._basefont.addtoresourcesearch
文章浏览阅读174次。一、首先需要在项目中引入better-scroll1. 在package.json 直接写入 "better-scroll":"^1.11.1" 版本以github上为准(目前最新)2.cpnm install 在node_modules 可以查看版本是否安装3.直接在你的组件里面写入import BScroll from 'better-scroll';二、b..._better-scroll 自动触发水平滚动
文章浏览阅读221次。Ubuntu18.04 pip方法安装python-pclubuntu安装python-pcl有两种方法:源码编译、pip安装。源码编译比较麻烦,虽然我之前编译成功了,一旦环境有变,再次编译就很麻烦。这里就介绍怎么pip方法安装。pip安装很简单,直接在python环境中执行下面语句,下载源设置为豆瓣的pip install python-pcl -i http://pypi.douban.com..._ubuntu 18.04 python2.7如何安装pcl
文章浏览阅读154次。R语言deLong's test:通过统计学的角度来比较两个ROC曲线、检验两个ROC曲线的差异是否具有统计显著性_delong’s检验
文章浏览阅读2.2k次。Ajax什么是Ajax?AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。同步交互: 客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求。异步交互: 客户端发出一个请..._ajax语法
文章浏览阅读937次。环境搭建新建模块es-jd1.添加依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency&g..._searchrequest依赖
文章浏览阅读863次。点击下方卡片,关注“自动驾驶之心”公众号ADAS巨卷干货,即可获取点击进入→自动驾驶之心【多传感器融合】技术交流群后台回复【aiMotive】获取更多论文和数据集等更多信息!摘要自动驾驶是计算机视觉领域的一个研究热点。因为自动驾驶汽车对安全性要求很高 ,确保鲁棒性对现实世界的部署至关重要。虽然有几个公共多模态数据集可以访问,但它们主要包括两种传感器模态(照相机、激光雷达),它们不太适合不利的天气。..._多模态benchmark
文章浏览阅读1.3k次,点赞2次,收藏3次。oracle 11g ORA 12514错误,我的解决办法前言:网上有很多解决办法,删listener.ora也好,还是什么也好,都解决不了我这个问题,依然报12514错误,以下是我逐个尝试后成功的监听字符串。。listener.ora文件:# listener.ora Network Configuration File: d:\app\john\product\11.1.0\db_1\netw..._weblogic ora-12514
文章浏览阅读112次。package com.kuyun.document_class;import java.io.BufferedReader;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.Unsupp..._java word2vec
文章浏览阅读1.3k次,点赞18次,收藏20次。Dinky 是一个开箱即用、易扩展,以 Apache Flink 为基础,连接 OLAP 和数据湖等众多框架的一站式实时计算平台,致力于流批一体和湖仓一体的探索与实践。_dinky 下载
文章浏览阅读1.1k次。文章目录机器学习的相关算法了解和总结1、机器学习的一般步骤2、相关算法3、决策树4、支持向量机 SVM5、神经网络6、随机森林算法机器学习的相关算法了解和总结1、机器学习的一般步骤训练集训练 -> 提取特征向量 -> 结合一定的算法(比如决策树、KNN) -> 得到结果机器学习的几个核心主要是 分类、随机、决策、迭代、猜测其实就是一个通过经验总结进行结果猜测的过程,那么,提供的经验样本(训练数据)越多,优化(迭代)的越好,猜测的准确度就越高2、相关算法Adaboos_机器学习相关算法的进展和理解