来回移动物体
Moving objects back and forth
我正在尝试移动多个对象,同时从 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 循环中使用数组,我不知道如何保留每个游戏对象的 transform.position,以便它可以用作反转方向的条件物体每次到达 A 点或 B 点时的移动。
if (l.transform.position.x <= startPos.x || l.transform.position.x >= startPos.x + endPos.x)
{
speed *= -1;
}
编辑:如果我问了一个重复的问题,我深表歉意,我认为由于数组中涉及的对象数量不同而有所不同。
我试着假设解决了你所有的问题,请看下面的代码。
不需要 Time.deltaTime,因为您的代码(和我的)使用 Time.time 来计算每次对象的位置。
我还建议(如果可能的话)不要将所有内容都放在脚本中,而是给每个对象一个 swing 脚本,并且尽量不要使用 CoRoutine。但为了回答你的问题,我会告诉你如何去做。
我创建了一个内部 class,用于将目标游戏对象及其 startPosition 存储在 "Init" 列表中。稍后您可以简单地遍历此列表并始终具有起始位置。
你需要在"Osciallate"例程中无限循环并且需要等待每一轮。在您的示例中,您将 Wait 放在了错误的位置,因此它在移动每个对象后等待并在所有这些对象的第一个 运行 之后停止。
这里是代码:
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) 我建议使用 "Animation" 组件进行移动而不使用 C#,这样您可以根据需要更改行为并且更加灵活。
2) 如果可能的话,我还建议创建一个父对象 "GameObject" 并仅移动它并将 "MovingOb2" 简单地作为子对象。
编辑2:
为每个对象添加延迟增量,因此它们不会 运行ning 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);
}
}
}
they're all difficult to contain within a desirable distance and speed from the starting position. It's too fast, and too far
在您开始修改代码结构之前,我建议您坚持使用余弦函数,但要了解(非常简单的)操作输出频率和振幅的方式。这些知识将为您提供很好的帮助(如果这个问题是您的一般项目的典型问题)并且可以轻松解决问题。
如果速度太快,您可以通过将输入(始终是绝对时间)乘以 0.0 到 +1.0(不含)之间的常数系数来降低频率(或增加 wavelength/period)。
如果太远,您可以通过将输出乘以 0.0 到 +1.0(不含)之间的常数系数来减小幅度。
您只需要选择两个常量,然后根据 运行 程序进行调整,然后看看您是否喜欢它。
我正在尝试移动多个对象,同时从 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 循环中使用数组,我不知道如何保留每个游戏对象的 transform.position,以便它可以用作反转方向的条件物体每次到达 A 点或 B 点时的移动。
if (l.transform.position.x <= startPos.x || l.transform.position.x >= startPos.x + endPos.x)
{
speed *= -1;
}
编辑:如果我问了一个重复的问题,我深表歉意,我认为由于数组中涉及的对象数量不同而有所不同。
我试着假设解决了你所有的问题,请看下面的代码。
不需要Time.deltaTime,因为您的代码(和我的)使用 Time.time 来计算每次对象的位置。
我还建议(如果可能的话)不要将所有内容都放在脚本中,而是给每个对象一个 swing 脚本,并且尽量不要使用 CoRoutine。但为了回答你的问题,我会告诉你如何去做。
我创建了一个内部 class,用于将目标游戏对象及其 startPosition 存储在 "Init" 列表中。稍后您可以简单地遍历此列表并始终具有起始位置。
你需要在"Osciallate"例程中无限循环并且需要等待每一轮。在您的示例中,您将 Wait 放在了错误的位置,因此它在移动每个对象后等待并在所有这些对象的第一个 运行 之后停止。
这里是代码:
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) 我建议使用 "Animation" 组件进行移动而不使用 C#,这样您可以根据需要更改行为并且更加灵活。
2) 如果可能的话,我还建议创建一个父对象 "GameObject" 并仅移动它并将 "MovingOb2" 简单地作为子对象。
编辑2:
为每个对象添加延迟增量,因此它们不会 运行ning 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);
}
}
}
they're all difficult to contain within a desirable distance and speed from the starting position. It's too fast, and too far
在您开始修改代码结构之前,我建议您坚持使用余弦函数,但要了解(非常简单的)操作输出频率和振幅的方式。这些知识将为您提供很好的帮助(如果这个问题是您的一般项目的典型问题)并且可以轻松解决问题。
如果速度太快,您可以通过将输入(始终是绝对时间)乘以 0.0 到 +1.0(不含)之间的常数系数来降低频率(或增加 wavelength/period)。
如果太远,您可以通过将输出乘以 0.0 到 +1.0(不含)之间的常数系数来减小幅度。
您只需要选择两个常量,然后根据 运行 程序进行调整,然后看看您是否喜欢它。