来回移动物体

时间:2017-09-04 03:16:32

标签: c# unity3d unity5

我正在尝试移动多个对象,同时从A点移动到B点再向后移动,循环以阻挡玩家。

我试过

StartCoroutine(Oscillate(OscillationFunction.Sine, 1f));
  public IEnumerator Oscillate(OscillationFunction method, float scalar)
  right = GameObject.FindGameObjectsWithTag("MovingObs2");
                foreach (GameObject r in right)
                {
                    startPos = r.transform.position;    
                    v = startPos;
                    v.x = (r.transform.position.x + (Mathf.Cos(Time.time) * scalar));
                    r.transform.position = v;
                    yield return new WaitForSeconds(2);
                    r.transform.position = startPos;
                }

和其他人,但他们都很难在起始位置的理想距离和速度内包含。它太快了,而且太远了。

我尝试了一条看似简单的系列,这对我来说更容易理解。

 v.x = l.transform.position.x + speed * Time.deltaTime;
            l.transform.position = v;

但是因为我在foreach循环中使用了一个数组,所以我不知道如何保留每个GameObjects的transform.position,这样它就可以作为一个条件来反转每个对象的运动方向时间到达A点或B点。

   if (l.transform.position.x <= startPos.x || l.transform.position.x >= startPos.x + endPos.x)
        {
            speed *= -1;
        }

编辑:如果我问了一个重复的问题,我很抱歉,我认为由于数组中涉及的对象数量而有所不同。

2 个答案:

答案 0 :(得分:1)

我试图解决您的所有问题,请参阅下面的代码。

不需要Time.deltaTime,因为你的代码(和我的)使用Time.time来计算每次对象的位置。

我还建议(如果可能的话)不要全部放入脚本,但是给每个对象一个swing脚本,并尝试不使用CoRoutine。但是要回答你的问题,我会告诉你如何去做。

我创建了一个内部类,存储在&#34; Init&#34;列表中的目标游戏对象及其startPosition。稍后您可以通过此列表循环,并始终具有起始位置。

你需要在&#34; Osciallate&#34;例程,需要等待每一个回合。在你的例子中,你把等待放在错误的地方,所以它在移动每个对象后等待,并在第一次运行所有这些对象后停止。

这里是代码:

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

public class OscilateObs : MonoBehaviour {

    // internal class where all gameobjects and their startposition will be saved
    internal class OscGameObjects
    {
        public GameObject gameObject;
        public Vector3 startPosition;
    }

    // Here the information of all gameObjects stored in a list
    private List<OscGameObjects> objectList;

    public float updateSpeed = 0.05f;
    public float oscScalar = 2f;

    public enum OscillationFunction {
        Sine = 1
    }

    void Start () {
        // First, the gameobjects have to saved to our internal List
        InitializeOscGameObjects();

        // Start the Corotine
        StartCoroutine(Oscillate(OscillationFunction.Sine, oscScalar));
    }

    private void InitializeOscGameObjects()
    {
        var objects = GameObject.FindGameObjectsWithTag("MovingObs2");

        objectList = new List<OscGameObjects>();
        foreach (var o in objects)
        {
            var oscObject = new OscGameObjects();
            oscObject.gameObject = o;
            oscObject.startPosition = o.transform.position;

            objectList.Add(oscObject);
        }
    }

    public IEnumerator Oscillate(OscillationFunction method, float scalar)
    {
        // Loop forever
        while(true)
        {
            foreach (var element in objectList)
            {
                var currentPosition = element.gameObject.transform.position;
                currentPosition.x = element.startPosition.x + Mathf.Cos(Time.time) * scalar;
                element.gameObject.transform.position = currentPosition;

            }
            yield return new WaitForSeconds(updateSpeed);
        }

    }

}

编辑:

我忘记了意思:

1)我建议使用&#34;动画&#34;移动的组件,根本不使用C#,因此您可以根据需要更改行为,并且更灵活。

2)我还建议尽可能制作父母&#34; GameObject&#34;并且只移动它并放置&#34; MovingOb2&#34;只是作为儿童对象。

EDIT2:

为每个对象添加延迟增量,因此它们不运行syncron:

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

public class OscilateObs : MonoBehaviour {

    // internal class where all gameobjects and their startposition will be saved
    internal class OscGameObjects
    {
        public GameObject gameObject;
        public Vector3 startPosition;
        public float waitCount;
    }

    // Here the information of all gameObjects stored in a list
    private List<OscGameObjects> objectList;

    public float updateSpeed = 0.05f;
    public float oscScalar = 2f;
    public float waitIncrementTime = 0.01f;

    public enum OscillationFunction {
        Sine = 1
    }

    void Start () {
        // First, the gameobjects have to saved to our internal List
        InitializeOscGameObjects();

        // Start the Corotine
        StartCoroutine(Oscillate(OscillationFunction.Sine, oscScalar));
    }

    private void InitializeOscGameObjects()
    {
        var objects = GameObject.FindGameObjectsWithTag("MovingObs2");

        objectList = new List<OscGameObjects>();

        float i = 0;
        foreach (var o in objects)
        {
            i += waitIncrementTime;
            var oscObject = new OscGameObjects();
            oscObject.gameObject = o;
            oscObject.startPosition = o.transform.position;
            oscObject.waitCount = i;
            objectList.Add(oscObject);
        }
    }

    public IEnumerator Oscillate(OscillationFunction method, float scalar)
    {
        // Loop forever
        while(true)
        {
            foreach (var element in objectList)
            {
                var currentPosition = element.gameObject.transform.position;
                currentPosition.x = element.startPosition.x + Mathf.Cos(Time.time + element.waitCount) * scalar;
                element.gameObject.transform.position = currentPosition;

            }
            yield return new WaitForSeconds(updateSpeed);
        }

    }

}

答案 1 :(得分:0)

  从起始位置起,它们都难以包含在理想的距离和速度范围内。它太快了,太远了

在开始使用代码结构进行编辑之前,我建议你坚持使用余弦函数,但要教会自己(非常简单)处理输出频率和幅度的方法。这些知识将很好地为您服务(如果这个问题是您平均项目的典型问题),并且可以轻松解决问题。

如果速度过快,可以通过将输入(总是绝对时间)乘以0.0到+1.0之间的常数系数(不包括在内)来降低频率(或增加波长/周期)。

如果距离太远,可以通过将输出乘以0.0到+1.0之间的常数系数(不包括在内)来减小幅度。

你只需要选择两个常数并通过运行程序调整品味,看看你喜欢它。