Unity的几种移动和旋转方法

Unity的移动

在制作一款游戏的时候,经常需要对物体的位置进行移动,我们希望这个移动是具有多样性的,并且可操作的。

C#中提供了非常丰富的移动代码工具,通过这些工具我们可以实现:匀速移动、变速移动、自定义变速移动等移动方式。

基础框架

实现一个Unity中可以挂接的类包含的基本框架是:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class VecMove : MonoBehaviour
{
    private void Start()
    {
        //代码初始时调用
    }

    private void Update()
    {
        //每帧调用一次
    }

    // 本次博文中使用的
    private void OnGUI()
    {
        // 每帧调用一次,用于GUI操作的判断
    }

}

== 为了更加直观的展示移动,本次博文在OnGUI中调用移动方法,通过点击移动按钮查看移动过程 ==

更一般的情况,可能是在Updat()中调用。
注意!下面的方法填充在OnGUI()中。

匀速移动

if(GUILayout.RepeatButton("匀速移动"))
{
    this.transform.position = Vector3.MoveTowards(objectPos, targetPos, moveFactor);
}

点击移动按钮即可实现匀速移动,其中objectPos是当前物体的位置,targetPos是目的物体的位置,moveFactor是每一帧移动的距离。

变速移动

if(GUILayout.RepeatButton("变速移动"))
{
    this.transform.position = Vector3.Lerp(objectPos,targetPos, moveFactor);
}

从objectPos 移动到 -> targetPos ,每次移动的距离是二者distance*moveFactor的距离。

当前物体的位置一直在靠近目标位置,因此这个移动距离不断变小,并且永远不可达,只能无限靠近。

自定义变速运动

public AnimationCurve curve;        // x轴是移动时间,y轴是移动量
public float x;
if(GUILayout.RepeatButton("自定义变速"))
{
    x += Time.deltaTime / moveDalayTime;
    this.transform.position = Vector3.Lerp(objectPos, targetPos, curve.Evaluate(x));
}
if(GUILayout.RepeatButton("自定义变速2"))
{
    x += Time.deltaTime / moveDalayTime;
    this.transform.position = Vector3.LerpUnclamped(objectPos, targetPos, curve.Evaluate(x));
}

可以在Unity界面自定义移动曲线

  1. 其中curve设置为public,可以在unity界面进行设置曲线
    在这里插入图片描述
    2.这个曲线如果设置成如下的样子:(超过终点,再回来)
    在这里插入图片描述

使用Vector3.Lerp会默认到达目的地为最终结果
使用Vector3.LerpUnclamped会严格按照曲线运动,超过目的地再回来

最终代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 
/// </summary>
public class VecMove : MonoBehaviour
{
    private Vector3 targetPos = new Vector3(0, 0, 10);
    public float moveFactor = 0.1f;
    public AnimationCurve curve;        // x轴是移动时间,y轴是移动量
    public float moveDalayTime = 1.0f;  // 移动到目的地花费的时间
    private float x;
    private Vector3 objectPos;
    private Vector3 originPos;
    void Start()
    {
        objectPos = this.transform.position;
        originPos = this.transform.position;
    }

    void Update()
    {
    }
    void OnGUI()
    {
        if(GUILayout.RepeatButton("复位"))
        {
            objectPos = this.transform.position;
            this.transform.position = originPos;
            x = 0;
        }
        if(GUILayout.RepeatButton("匀速移动"))
        {
            objectPos = this.transform.position;
            this.transform.position = Vector3.MoveTowards(objectPos, targetPos, moveFactor);
        }
        if(GUILayout.RepeatButton("变速移动"))
        {
            this.transform.position = Vector3.Lerp(objectPos,targetPos,moveFactor);
        }
        // 起点固定,终点固定,运动根据曲线来
        if(GUILayout.RepeatButton("自定义变速"))
        {
            x += Time.deltaTime / moveDalayTime;
            this.transform.position = Vector3.Lerp(objectPos, targetPos, curve.Evaluate(x));
        }
        // 上面的是超过终点就算是终点,如果想要超过终点还能回来,就使用下面的方法
        if(GUILayout.RepeatButton("自定义变速2"))
        {
            x += Time.deltaTime / moveDalayTime;
            this.transform.position = Vector3.LerpUnclamped(objectPos, targetPos, curve.Evaluate(x));
        }
    }
}

Unity的几种旋转方法

接上一节的移动方法,这里列举几种常用的旋转方法
因为和移动用到的工具原理基本类似,不在赘述,感兴趣的同学可以自己将代码挂接在物体上实验

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 
/// </summary>
public class QuternionRotate : MonoBehaviour
{
    public Transform targetTF;

    private void OnGUI()
    {
        if(GUILayout.Button("让摄像机转向目标物体"))
        {
            Vector3 direction = targetTF.position - this.transform.position;
            this.transform.rotation = Quaternion.LookRotation(direction);
        }
        if(GUILayout.RepeatButton("使用Lerp控制旋转速度"))
        {
            Quaternion dir = Quaternion.LookRotation(targetTF.position - this.transform.position);
            this.transform.rotation = Quaternion.Lerp(this.transform.rotation, dir, 0.01f);
        }
        if(GUILayout.RepeatButton("匀速旋转"))
        {
            Quaternion dir = Quaternion.LookRotation(targetTF.position - this.transform.position);
            this.transform.rotation = Quaternion.RotateTowards(this.transform.rotation,dir,1f );
        }
        if(GUILayout.RepeatButton("right"))
        {
            this.transform.right = targetTF.position - this.transform.position;
            // Quaternion dir = Quaternion.LookRotation(targetTF.position - this.transform.position);
            // this.transform.rotation = dir;
        }
        if(GUILayout.RepeatButton("right2"))
        {
            Vector3 dir = targetTF.position - this.transform.position;
            this.transform.rotation = Quaternion.FromToRotation(Vector3.right, dir);
        }
    }


}
  • 7
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IMUHERO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值