using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DropDown : MonoBehaviour
{
public GameObject dropdownPrefab;
public int numberOfObjects;
public float speed = 1.5f;
public float duration = 5f;
public Vector3 startPos;
public Vector3 endPos;
public float distanceToMove = 2f;
public float gap;
private List<GameObject> dropDownObjects = new List<GameObject>();
private List<Vector3> endPositions = new List<Vector3>();
private void Start()
{
for (int i = 0; i < numberOfObjects; i++)
{
dropDownObjects.Add(Instantiate(dropdownPrefab, transform.parent));
endPositions.Add(new Vector3(dropDownObjects[i].transform.position.x,
dropDownObjects[i].transform.position.y + i + 2,
dropDownObjects[i].transform.position.z) - Vector3.up * distanceToMove);
}
startPos = dropDownObjects[0].transform.position;
}
private void OnMouseDown()
{
StartCoroutine(StartDropObjects());
}
private IEnumerator StartDropObjects()
{
for (int i = 0; i < dropDownObjects.Count; i++)
{
// Random wait period before rotation starts
if (i == 0)
{
//yield return new WaitForSeconds(0);
}
else
{
//yield return new WaitForSeconds(Random.Range(0, 2f));
}
yield return new WaitForSeconds(2f);
StartCoroutine(Drop(dropDownObjects[i].transform, duration, endPositions[i]));
}
}
private IEnumerator Drop(Transform objectToDrop, float duration, Vector3 endpos)
{
float t = 0.0f;
while (t < duration)
{
t += Time.deltaTime;
objectToDrop.transform.position = Vector3.MoveTowards(objectToDrop.transform.position, endpos, speed * Time.deltaTime);
yield return null;
}
}
}
对象应该向下移动,但是在这种情况下,当我添加间隙时,间隙为i + 2,例如,如果I = 0,则间隙为2,则I = 1,因此间隙将为3,则I = 2的差距是4。
endPositions.Add(new Vector3(dropDownObjects[i].transform.position.x,
dropDownObjects[i].transform.position.y + i + 2,
dropDownObjects[i].transform.position.z) - Vector3.up * distanceToMove);
但是我希望对象之间具有相等的间隙。例如,如果我将间隙值设置为1,则对象之间将有相等的间距/间隙,如果间隙值为5,则每两个对象之间的间隙/间隙将等于5。
现在的问题是我每次都增加1,所以差距不相等。
在执行操作时,对象也在向上移动而不是向下移动:+ i + 2
在屏幕快照中,对象向上移动而不是向下移动,顶部的两个对象看起来彼此太近了。差距并不相等。
但是想法是,当对象移动到目标目的地endPositions时,每个对象将根据间隙移动到其on endPosition。
所以最终对象应该是这样的:
第一个是最底部的那个。最后一个是顶部的那个。 第一个dropDownObjects [0]对象移到了最远的endPosition的endPosition。在这种情况下,distanceToMove设置为2。
然后dropDownObjects 1移至他的distanceToMove-差距。等等。这是逻辑,最终所有对象移动之后,它们将具有相等的间隙。
第一个移动的对象是应该到达distnaceToMove的对象。
答案 0 :(得分:1)
问题不在这里:
endPositions.Add(new Vector3(dropDownObjects[i].transform.position.x,
dropDownObjects[i].transform.position.y + i + 2,
dropDownObjects[i].transform.position.z) - Vector3.up * distanceToMove);
但是这里:
private IEnumerator Drop(Transform objectToDrop, float duration, Vector3 endpos)
{
float t = 0.0f;
while (t < duration)
{
t += Time.deltaTime;
objectToDrop.transform.position = Vector3.MoveTowards(objectToDrop.transform.position, endpos, speed * Time.deltaTime);
yield return null;
}
}
因为所有对象都使用相同的持续时间,但是它们的距离不同。最后的对象没有时间完成它们的移动。
您可以通过将方法Drop(...)更改为以下代码来进行检查:
private IEnumerator Drop(Transform objectToDrop, float duration, Vector3 endpos)
{
while (objectToDrop.transform.position != endpos)
{
objectToDrop.transform.position = Vector3.MoveTowards(objectToDrop.transform.position, endpos, speed * Time.deltaTime);
yield return null;
}
}
答案 1 :(得分:0)
我将更改您确定endPositions
的方式,以使其更易于配置。
我将定义一个起始距离和一个最大距离,您可以使用minDistanceToMove
和maxDistanceToMove
在起始距离和Mathf.Lerp
t
之间进行插值,从而以编程方式计算间隙之(float)i/(numberOfObjects-1)
:
public float minDistanceToMove = 0.5f;
public float maxDistanceToMove = 2f;
private void Start()
{
for (int i = 0; i < numberOfObjects; i++)
{
dropDownObjects.Add(Instantiate(dropdownPrefab, transform.parent));
float t = (float)i/(numberOfObjects-1);
float distDown = Mathf.Lerp(minDistanceToMove,maxDistanceToMove,t);
endPositions.Add(new Vector3(dropDownObjects[i].transform.position.x,
dropDownObjects[i].transform.position.y,
dropDownObjects[i].transform.position.z) - Vector3.up * distDown);
}
startPos = dropDownObjects[0].transform.position;
}
或者,您可以仅设置minDistanceToMove
和间隙大小,然后以这种方式计算distDown
:
public float minDistanceToMove = 0.5f;
public float gapSize = 0.5f;
private void Start()
{
for (int i = 0; i < numberOfObjects; i++)
{
dropDownObjects.Add(Instantiate(dropdownPrefab, transform.parent));
float distDown = minDistanceToMove + gapSize * i;
endPositions.Add(new Vector3(dropDownObjects[i].transform.position.x,
dropDownObjects[i].transform.position.y,
dropDownObjects[i].transform.position.z) - Vector3.up * distDown);
}
startPos = dropDownObjects[0].transform.position;
}
无论哪种方式,您都需要将Drop
更改为持续很长时间才能将面板放到目的地:
private IEnumerator Drop(Transform objectToDrop, float duration, Vector3 endpos)
{
// duration is unused. It is in the method signature here to avoid
// confusion when swapping with the alternative below
while (objectToDrop.transform.position != endPos)
{
objectToDrop.transform.position = Vector3.MoveTowards(
objectToDrop.transform.position, endpos, speed * Time.deltaTime);
yield return null;
}
}
或者,您可以使每个面板采用给定的持续时间,并计算遍历该距离所需的速度:
private IEnumerator Drop(Transform objectToDrop, float duration, Vector3 endpos)
{
float mySpeed = Vector3.Distance(
objectToDrop.transform.position, endpos) / duration;
while (objectToDrop.transform.position != endPos)
{
objectToDrop.transform.position = Vector3.MoveTowards(
objectToDrop.transform.position, endpos, mySpeed * Time.deltaTime);
yield return null;
}
}