Unity学习01-unity物体移动三种方式

1. unity物体移动方式之坐标变换(可能会出现穿过刚体的情况,但是简单快捷)

1.1直接对物体坐标进行操作

Transform.Translate(Vector3 translation),Space relativeTo)
  • 前一个变量是物体的移动速度,这里的速度是一个矢量,既包含大小写包含方向。

  • 后一个变量是相对坐标系,这里的相对坐标系有两个值,一个是世界坐标,一个是自身坐标,如果第一个坐标不填写的话,默认为自身坐标系。

  • Transform.Translate()的内部实现其实也是 transform.position += 这种方式

  • 写在Update里面

    transform.Translate(Vector3.up * Time.deltaTime, Space.Self);
    transform.Translate(new Vector3 (1,1,1) * Time.deltaTime, Space.World);
    
  • Time.deltaTime代表后一帧时间减去前一帧时间,相当于每一帧时间的间隔,不加Time.deltaTime代表每帧的移动速度,加了就代表每秒的移动速度,可用于平衡不同电脑不同帧数导致的差异。

  • 因为 Update 的帧间隔与电脑性能有关,而物体受力和帧间隔时间有关会导致物体受力不均匀从而导致物体异常抖动(不是很理解这句话)

  • 可以写在 Fixupdate(固定物理帧) 中解决,因为 Update 帧间隔不固定,而 Fixupdate
    固定0.02s Fixupdate里建议使用Time.fixedDeltaTime

1.2或者直接修改transform的position的值

transform.position +=  (target - gameObject.transform.position) * moveSpeed * Time.deltaTime;
transform.position +=  (target - gameObject.transform.position).normalized * moveSpeed * Time.deltaTime;
  • Vector3.normalized就是把一个方向向量变成单位向量(平方和为一),忽略两个点之间的距离的影响,强调方向

  • 不加这个归一化向量的话,当目标离我越远,我移动越快,越靠近目标就我的移动就越慢
    加了归一化就我的坐标变化速度就主要受moveSpeed影响

1.3 通过一个函数得到下一帧物体要到达的位置再进行移动

1.3.1 以固定的速度移动到目标位置
public static Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta)
  • 将物体从current位置沿直线移动到target位置。
  • maxDistanceDelta是每次调用移动的距离。
  • 返回值是current + maxDistanceDelta,如果这个值超过了target,返回值就是target。(就是说每次调用只往target方向移动 maxDistanceDelta 这么远)
  • 如果要实现匀速运动那就得多次调用(写在Updata或者FixeUpdata里)
transform.position = Vector3.MoveTowards(transform.position, target.transform.position, Time.deltaTime * speed);
1.3.2 平滑一点到达目标位置
public static Vector3 SmoothDamp(Vector3 current, Vector3 target, ref Vector3 currentVelocity, float smoothTime, float maxSpeed)
  • 将物体从current位置沿直线移动到target位置。
  • currentVelocity 当前速度
  • smoothTime 平滑时间
  • maxSpeed 最大速度(不需要Time.deltaTime 底层实现已解决帧数问题)
  • 返回值是
transform.position = Vector3.SmoothDamp(transform.position, target.transform.position, ref velocity,smoothTime,speed);
1.3.3 在规定时间内到达地点
public static float Lerp(float a, float b, float t)  //每次走ab直接距离的t倍
{
	return a + (b - a) * Clamp01(t);
}
public static float Clamp01(float value)			//限制是小数
{
	if (value < 0f)
		return 0f;

	if (value > 1f)
		return 1f;

	return value;
}

 public static Vector3 Lerp(Vector3 a, Vector3 b, float t)   
 {
 		t = Mathf.Clamp01(t);
    	return new Vector3(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t);
 }
  • 将物体从current位置沿直线移动到target位置。
  • t 是一个百分比 详情看下面例子
  • 返回值是下一帧我应该在的位置
    Vector3 target;
    float lerpDuration = 4;     //完成运动所需时间
    float _timeElapsed = 0;     //记录运行时间

    private void Update()
    {
        _timeElapsed += Time.deltaTime;     //计算时间的比例
        if (_timeElapsed < lerpDuration)    //如果在规定时间内 第一次走距离的 1/4 第二次走剩下距离的 2/4
            transform.position = Vector3.Lerp(transform.position, target, _timeElapsed / lerpDuration);
        else                                //如果超出时间就直接到达  如果不这样写会永远到不了
            transform.position = target;
    }

2. unity物体移动方式之刚体力的添加(涉及物理引擎的移动方法)

在刚体上添加不同方向的力,从而实现物体的移动,还可以添加力的方式(移动速度与物理特性有关如质量、阻力和重力),但每执行一次只能添加一次力,要想持续运动还得持续调用该方法

  • Vector3 force:力(矢量)
  • Vector3 position:施加力的位置
  • ForceMode mode :力的方式
public void AddForce(Vector3 force)
public void AddForceAtPosition(Vector3 force, Vector3 position,ForceMode mode);

关于作用力方式 ForceMode 的功能注解

ForceMode 为枚举类型,用来控制力的作用方式,有4个枚举成员

  1. ForceMode.Force:默认方式,使用刚体的质量计算,以每帧间隔时间为单位计算动量。
  2. ForceMode.Acceleration:在此种作用方式下会忽略刚体的实际质量而采用默认值1.0f,时间间隔以系统帧频间隔计算(默认值为0.02s)
  3. ForceMode.Impulse:此种方式采用瞬间力作用方式,即把时间的值默认为1,不再采用系统的帧频间隔。
  4. ForceMode.VelocityChange:此种作用方式下将忽略刚体的实际质量,采用默认质量1.0,同时也忽略系统的实际帧频间隔,采用默认间隔1.0。

2D中ForceMode2D只有Force和Impulse
3D中有Force、Acceleration、Impulse和VelocityChange

gameObject.GetComponent<Rigidbody>().AddForce(fore);

3. unity物体移动方式之刚体速度变换(涉及物理引擎的移动方法)

3.1对刚体速度进行操作,赋予物体一个持续不变的速度

功能说明: 此属性用于设置或返回刚体的速度值,其使用说明如下。

  1. 在脚本中无论是给刚体赋予一个Vector3类型的速度向量v,还是获取当前刚体的速度v,v的方向都是相对世界坐标系而言的。

  2. velocity的单位是米每秒,而不是帧每秒,其中米是Unity默认的长度单位。

public Vector3 velocity{get;set;}

r1.velocity=new Vector3(0.0f,0.0f,-15.0f);

3.2 使用MovePosition() (2D的)

public void MovePosition(Vector2 position)

在Rigidbody2D的BodyType为Kinematic是不会受到重力和AddForece()等相关函数影响的 ,直接把物体移动到目标位置但是有物理效果

  • Vector2 position:目标位置
    private void FixedUpdate()
    {
        var pos = dir * (speed * Time.fixedTime);		//dir 目标方向  speed速度
        gameObject.GetComponent<Rigidbody2D>().MovePosition(transform.position+ pos);
    }

详情:
UnityAPI:velocity属性——刚体速度
Unity中的ForceMode——纠正《UnityAPI解析——陈泉宏》一书 关于ForceMode的注解
unity物体移动三种方式之——AddForceAtPosition(一)
物体移动——三种方法
Unity Movetowards方法
【Unity】如何优雅地移动物体?8种方式

  • 2
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值