自动找到最近的目标点并停在那里
Automatically find nearest target point & stop there
我有 3 个立方体,它们堆叠在一起。在他们面前,我有 3 个目标点(即,立方体要到达的目标位置)。我使用 Move.Towards() 函数手动完成了此操作。我将每个目标点分别分配给每个立方体。但现在不是我手动设置它。我希望这个过程自动化。我已经考虑过这个但我现在 confused.And 这些立方体和目标点在我手动拖放之前在运行时生成。因此,立方体应该在运行时自动分配其最近的目标点,而且如果一个立方体已经到达目标点,它应该停在那里并且没有其他立方体应该重叠或坐在那个 stop/targetpoint 上。它应该跳过那个点并找到下一个目标点。我很困惑,但我想使用矢量并找到短距离或继续检查并保持距离。但是这些似乎不是一个好的方法。
所以我在这里发布这个是为了从你们那里获得关于我可以解决这个问题的想法。
谢谢大家 <3
对,所以你说你已经有了像
这样的组件
public class TargetPoint : MonoBehaviour
{
public bool isFilled;
}
所以为了获得最近的自由点,你可以做例如
// Linq provides some handy SQL-like query extension methods for IEnumerable types
using System.Linq;
...
private bool TryFindClosestTargetPoint(out TargetPoint targetPoint)
{
// Find all active and enabled instances of TargetPoint in your scene
// Filter out the "isFilled" ones and only keep the "!isFilled" ones
// Order them by the distance between you and the target
// Take the first item -> closest target that is not filled yet
// If this returns null it means there was either no TargetPoint in your scene at all
// or they are all already "isFilled"
targetPoint = FindObjectsOfType<TargetPoint>().Where(t => !t.isFilled).OrderBy(t => (t.transform.position - transform.position).sqrMagnitude).FirstOrDefault();
// Implicit conversion to bool
// -> returns true if targetPoint != null
return targetPoint;
}
然后使用它,例如喜欢
// Move speed in Unity unit / second
public float speed = 0.5;
public void StartMove()
{
// First check if you can get a closest point
if(!TryFindClosestTargetPoint (out var targetPoint))
{
// Nope -> Sad Panda!
Debug.LogWarning("Couldn't find a free target!", this);
return;
}
// Got a closest point -> mark it occupied
targetPoint.isFilled = true;
// And start moving towards it
StartCorouine (MoveTo(targetPoint.transform.position));
}
// Example Coroutine
// This will move with a linear speed towards the given target
// Adjust according to your needs
private IEnumerator MoveTo(Vector3 target)
{
// Move smooth until the position matches with a precision of 0.00001
while(transform.positon != target)
{
// Each frame move the object one step towards the target
transform.position = Vector3.MoveTowards(transform.position, target, speed * Time.deltaTime):
// "Pause" the Coroutine here, Redner this frame
// and continue from here in the next frame
yield return null;
}
// Just to be sure to end with clean values (due to the mentioned precision of 0.00001) set the target hard when done
transform.position = target;
}
因此,如果您有多个立方体,它们将分别选择前一个立方体尚未占据的下一个最近的免费目标,并开始朝它移动,然后停止。
我有 3 个立方体,它们堆叠在一起。在他们面前,我有 3 个目标点(即,立方体要到达的目标位置)。我使用 Move.Towards() 函数手动完成了此操作。我将每个目标点分别分配给每个立方体。但现在不是我手动设置它。我希望这个过程自动化。我已经考虑过这个但我现在 confused.And 这些立方体和目标点在我手动拖放之前在运行时生成。因此,立方体应该在运行时自动分配其最近的目标点,而且如果一个立方体已经到达目标点,它应该停在那里并且没有其他立方体应该重叠或坐在那个 stop/targetpoint 上。它应该跳过那个点并找到下一个目标点。我很困惑,但我想使用矢量并找到短距离或继续检查并保持距离。但是这些似乎不是一个好的方法。
所以我在这里发布这个是为了从你们那里获得关于我可以解决这个问题的想法。 谢谢大家 <3
对,所以你说你已经有了像
这样的组件public class TargetPoint : MonoBehaviour
{
public bool isFilled;
}
所以为了获得最近的自由点,你可以做例如
// Linq provides some handy SQL-like query extension methods for IEnumerable types
using System.Linq;
...
private bool TryFindClosestTargetPoint(out TargetPoint targetPoint)
{
// Find all active and enabled instances of TargetPoint in your scene
// Filter out the "isFilled" ones and only keep the "!isFilled" ones
// Order them by the distance between you and the target
// Take the first item -> closest target that is not filled yet
// If this returns null it means there was either no TargetPoint in your scene at all
// or they are all already "isFilled"
targetPoint = FindObjectsOfType<TargetPoint>().Where(t => !t.isFilled).OrderBy(t => (t.transform.position - transform.position).sqrMagnitude).FirstOrDefault();
// Implicit conversion to bool
// -> returns true if targetPoint != null
return targetPoint;
}
然后使用它,例如喜欢
// Move speed in Unity unit / second
public float speed = 0.5;
public void StartMove()
{
// First check if you can get a closest point
if(!TryFindClosestTargetPoint (out var targetPoint))
{
// Nope -> Sad Panda!
Debug.LogWarning("Couldn't find a free target!", this);
return;
}
// Got a closest point -> mark it occupied
targetPoint.isFilled = true;
// And start moving towards it
StartCorouine (MoveTo(targetPoint.transform.position));
}
// Example Coroutine
// This will move with a linear speed towards the given target
// Adjust according to your needs
private IEnumerator MoveTo(Vector3 target)
{
// Move smooth until the position matches with a precision of 0.00001
while(transform.positon != target)
{
// Each frame move the object one step towards the target
transform.position = Vector3.MoveTowards(transform.position, target, speed * Time.deltaTime):
// "Pause" the Coroutine here, Redner this frame
// and continue from here in the next frame
yield return null;
}
// Just to be sure to end with clean values (due to the mentioned precision of 0.00001) set the target hard when done
transform.position = target;
}
因此,如果您有多个立方体,它们将分别选择前一个立方体尚未占据的下一个最近的免费目标,并开始朝它移动,然后停止。