В то время как он все еще движется, я могу навести на нее еще раз, в этом случае я хочу его перезапустить , поэтому он останавливает функцию, влияющую на ту же самую кнопку , и перезапускает другую. Я просто не знаю, как идентифицировать , вызывающий ту же функцию для моего данного компонента. Или я должен добавить этот скрипт к каждому объекту, чтобы он мог влиять только на этот?
Одно из решений состоит в закреплении сценарий, содержащий функцию сопрограммы каждого геймобжекты. Если вы не хотите этого делать, есть еще один способ сделать это.
Прежде всего, просто хранить IEnumerator
недостаточно, чтобы на самом деле это сделать. Вам нужен способ идентифицировать GameObject, запущенный в последней сопрограмме.
. Получите значение, которое можно использовать для идентификации объекта. В этом случае идентификатор экземпляра с GetInstanceID()
должен быть точным.
. Создайте простой файл struct
, который будет содержать информацию старого сопроцессора.
.Finally, Сделать словарь, который будет содержать как идентификатор экземпляра (ключ) и эту структуру из # 2 в качестве значения.
С этими тремя вещами вы можете запустить сопрограмму, добавить ее в Dictionary
. Когда сопрограмма завершена, снимите instance ID
с Dictionary
.
В приведенном ниже коде один объект управления сопрограммой будет содержать много объектов, не помещая функцию сопрограммы в свой собственный скрипт. Большая разница в том, что при вызове новой cororutine на одну и ту же функцию она останавливает старую на этом объекте только, затем создает новую и запускает ее.
Это то, что я использую. Это очень хорошо прокомментировано, чтобы вы знали, что происходит.
Dictionary<int, MoveInfo> movingObject = new Dictionary<int, MoveInfo>();
public void Move(Transform from, Transform to, float overTime)
{
MoveInfo moveInfo;
//Check if the Object exist in the Dictionay
if (movingObject.TryGetValue(from.GetInstanceID(), out moveInfo))
{
//This Object exist and therefore, the coroutine function is already running. Stop it
//Remove it from the Dictionary
movingObject.Remove(from.GetInstanceID());
//Stop the old coroutine
StopCoroutine(moveInfo.currentCoroutine);
}
//Create a new coroutine
moveInfo = createMoveInfoInstance(from);
//Add it to the dictionary
movingObject.Add(from.GetInstanceID(), moveInfo);
//Get instance of the new coroutine we are about to start
moveInfo.currentCoroutine = _Move(moveInfo, from, to, overTime);
//Modify the dictionary because the Add function does not update the currentCoroutine reference
movingObject[from.GetInstanceID()] = moveInfo;
//Start the coroutine
StartCoroutine(moveInfo.currentCoroutine);
}
MoveInfo createMoveInfoInstance(Transform from)
{
MoveInfo moveInfo = new MoveInfo();
moveInfo.instanceID = from.GetInstanceID();
return moveInfo;
}
IEnumerator _Move(MoveInfo moveInfo, Transform from, Transform to, float overTime)
{
Vector2 original = from.position;
float timer = 0.0f;
Debug.Log("New Coroutine Started");
while (timer < overTime)
{
float step = Vector2.Distance(original, to.position) * (Time.deltaTime/overTime);
from.position = Vector2.MoveTowards(from.position, to.position, step);
timer += Time.deltaTime;
yield return null;
}
//Remove it from the Dictionary if it exist
if (movingObject.ContainsKey(from.GetInstanceID()))
{
movingObject.Remove(from.GetInstanceID());
}
}
public struct MoveInfo
{
public IEnumerator currentCoroutine;
public int instanceID;
public MoveInfo(IEnumerator currentCoroutine, int instanceID)
{
this.currentCoroutine = currentCoroutine;
this.instanceID = instanceID;
}
}
Вы можете взглянуть на http://gamedev.stackexchange.com/ –
не может быть плохой идеей. На данный момент, мой вопрос ясен? Или изменить? – hei
Ваш вопрос ясен и уместен на этом сайте. – Programmer