RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1104286
Accepted
danil2283376
danil2283376
Asked:2020-04-02 16:02:29 +0000 UTC2020-04-02 16:02:29 +0000 UTC 2020-04-02 16:02:29 +0000 UTC

如何将物体从 A 点移动到 B 点,到达该点后,等待一定时间,再次移动

  • 772

如何将物体从 A 点移动到 B 点,到达该点后,等待一段时间,然后再从 B 点移动到新的点。

我想让物体移动到一个点然后静止一段时间,然后再移动到另一个点,这无法理解,我为此折磨了很长时间。请帮帮我。对象只是逐点传送。物体必须顺利到达目的地,在那里等待一段时间,然后再次移动

公共类协程:MonoBehavior

{

// стартовая позиция
private Vector3 startPosition;
// новая позиция объекта
private Vector3 newPoint;

private void Start()
{
    // даю начальную позицию
    startPosition = transform.position;
}

private void Update()
{
    // указываю новую точку рандомными координатами, от начальной точки
    newPoint = new Vector3(
        Random.Range(startPosition.x - 5, startPosition.x + 5),
        startPosition.y,
        Random.Range(startPosition.z + 5, startPosition.z - 5)
        ); 
    // запускаю корутину
    StartCoroutine(MoveCoroutine(newPoint));
}

private IEnumerator MoveCoroutine(Vector3 moveTo)
{
    // жду 2 сек
    yield return new WaitForSeconds(2f);
    // если позиция объекта не равна конечной точки
    if (transform.position != newPoint)
    {
        // телепортирую объект по отрезку, создавая иллюзию перемещения
        transform.position = Vector3.Lerp(transform.position, newPoint, Time.time / 0.5f);
    }
}

}

c#
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Yaroslav
    2020-04-02T21:57:12Z2020-04-02T21:57:12Z

    使用协程,运动不会很流畅,所以Update.

    将移动和延迟分离为不同的能力。

    TimeAction你可以在任何地方使用它,并且MoveAction基于你TimeAction如何MoveAction编写很多各种各样的动作。

    public class Test : MonoBehaviour {
    
        private void Start () {
            MoveToRandomPosition();
        }
    
        private void MoveToRandomPosition () {
            Vector3 NewPos = new Vector3(Random.Range(-5, 5), Random.Range(-5, 5), Random.Range(-5, 5));
            //gameObject.AddComponent<MoveAction>().MoveWithTime(1, NewPos, DelayRandomTime);
            gameObject.AddComponent<MoveAction>().MoveWithSpeed(3, NewPos, DelayRandomTime);
        }
    
        private void DelayRandomTime () {
            float DelayTime = Random.Range(0, 5);
            gameObject.AddComponent<TimeAction>().Delay(DelayTime, MoveToRandomPosition);
        }
    }
    
    public delegate void TimeActionFinish();
    
    public class TimeAction : MonoBehaviour {
        protected float ActionTime, ActionTimer;
        protected TimeActionFinish Finish;
    
        public virtual void Delay (float time, TimeActionFinish finish) {
            ActionTimer = 0;
            ActionTime = time;
            Finish = finish;
        }
    
        private void Update () {
            ActionTimer += Time.deltaTime;
            float Way = ActionTimer/ActionTime;
            if (Way < 1)
                UpdateWay(Way);
            else {
                UpdateWay(1);
                if (Finish != null)
                    Finish();
                Destroy(this);
            }
        }
    
        protected virtual void UpdateWay (float way) { }
    }
    
    public class MoveAction : TimeAction {
        private Vector3 _moveFrom, _moveTo;
    
        public void MoveWithTime (float time, Vector3 target, TimeActionFinish finish) {
            _moveFrom = gameObject.transform.localPosition;
            _moveTo = target;
            base.Delay(time, finish);
        }
    
        public void MoveWithSpeed (float speed, Vector3 target, TimeActionFinish finish) {
            MoveWithTime(Vector3.Distance(gameObject.transform.localPosition, target)/speed, target, finish);
        }
    
        protected override void UpdateWay (float way) {
            transform.localPosition = Vector3.Lerp(_moveFrom , _moveTo , way);
        }
    }
    
    • 1
  2. Alteracia
    2020-04-03T20:03:01Z2020-04-03T20:03:01Z

    移动并不顺畅,因为 Lerp 在协程结束时被处理一次。在Update中做这样的举动更正确,因为 该操作将每帧执行一次。如果移动的对象与其他对象(物理)交互,则需要以不同的方式移动它 - 通过 Velocity 或 Force 并在 FixedUpdate 中处理。可以在协程中进行平滑的运动,但从优化的角度来看这是错误的。您需要将现有的协程分成两部分:

    public class Coroutine : MonoBehaviour
    {
        // булин для таймера
        private bool moved;
        // булин для движения
        private bool time_out;
        // стартовая позиция
        private Vector3 startPosition;
        // новая позиция объекта
        private Vector3 newPoint;
    
        private void Start()
        {
            // даю начальную позицию
            startPosition = transform.position;
            time_out = false;
            moved = true;
        }
    
        private void Update()
        {
            // указываю новую точку рандомными координатами, от начальной точки
            newPoint = new Vector3(
                Random.Range(startPosition.x - 5, startPosition.x + 5),
                startPosition.y,
                Random.Range(startPosition.z + 5, startPosition.z - 5)
                );
            if (moved)
                StartCoroutine(Timer());
            // запускаю корутину
            if (time_out)
                StartCoroutine(MoveCoroutine(newPoint));
        }
    
        private IEnumerator Timer()
        {
            moved = false;
            // жду 2 сек
            yield return new WaitForSeconds(2f);
            time_out = true;
        }
    
        private IEnumerator MoveCoroutine(Vector3 moveTo)
        {
            time_out = false;
            // если позиция объекта не равна конечной точки
            if (Vector3.Distance(transform.position, moveTo) != float.Epsilon)
            {
                WaitForEndOfFrame wait = new WaitForEndOfFrame();
                // Двигаем объект пока он не передвинется на новую позицию
                do
                {
                    // телепортирую объект по отрезку, создавая иллюзию перемещения
                    transform.position = Vector3.Lerp(transform.position, moveTo, Time.deltaTime);
                    // ждем до конца кадра
                    yield return wait;
                } while (Vector3.Distance(transform.position, moveTo) < float.Epsilon);
            }
            moved = true;
        }
    }
    
    • 1

相关问题

  • 使用嵌套类导出 xml 文件

  • 分层数据模板 [WPF]

  • 如何在 WPF 中为 ListView 手动创建列?

  • 在 2D 空间中,Collider 2D 挂在玩家身上,它对敌人的重量相同,我需要它这样当它们碰撞时,它们不会飞向不同的方向。统一

  • 如何在 c# 中使用 python 神经网络来创建语音合成?

  • 如何知道类中的方法是否属于接口?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5