C# Unity - 确定哪个方法正在影响游戏对象
C# Unity - identify which method is affecting a GameObject
我这里有这段代码:
public void Move(Transform from, Transform to, float overTime)
{
StartCoroutine(_Move(from, to, overTime));
}
IEnumerator _Move(Transform from, Transform to, float overTime)
{
Vector2 original = from.position;
float timer = 0.0f;
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;
}
}
这很简单。它所做的只是随着时间的推移将 GameObject
移动到目的地。我打算将它用于 UI 动画目的。
但是,当我想改变它的用途时,事情就变得有趣了。
例如,我将鼠标悬停在一个开始移动的按钮上。当它仍在移动时,我可能会再次将鼠标悬停在它上面,在这种情况下我希望它重新启动,因此它会停止影响完全相同按钮的 功能并重新启动另一个 。我只是不知道如何确定同一函数的哪个调用会影响我的给定组件。或者我应该将此脚本添加到每个对象以便它只影响那个对象吗?
这里有很多我想做的不同的事情。一方面,如果您的 Ui 对象已经受到协程的影响,您不希望另一个协程也开始作用于它,只是新的协程。为避免这种情况,声明一个协程变量:
IEnumerator myCoRoutine
当您第一次将鼠标悬停在上面时,像这样启动协程:
myCoRoutine = _Move(from, to, overTime);
Start Coroutine(_Move());
但是,您想检查一个协程是否已经 运行,如果是则停止它,然后启动一个新协程,对吗?所以,这样做:
if(myCoRoutine !=null) StopCoroutine(mtCoRoutine);
myCoRoutine = _Move(from, to, overTime);
Start Coroutine(_Move());
您可能希望使用 OnPointerEnter
启动协程
While it still moves, I may hover over it again, in that case I want
it to restart, so it stops the function affecting the exact same
button and restarts another one. I just have no clue how to identify
which call of the same function affects my given component. Or shall I
add this script to every object so it can affect only that one?
一种解决方案是将包含协程函数的脚本附加到 each 个游戏对象。如果您不想这样做,还有另一种方法可以做到这一点。
首先,简单地存储 IEnumerator
并不足以真正做到这一点。您需要一种方法来识别最后一个协程中的 GameObject 运行。
1.得到一个可以用来识别Object的值。在这种情况下,带有GetInstanceID()
的实例ID应该没问题。
2。制作一个简单的 struct
来保存旧协程信息。
3。最后,制作一个字典,将包含实例 ID(键)和来自 #2 的结构作为值.
有了这三个东西,你就可以启动一个协程,把它添加到Dictionary
。协程完成后,从 Dictionary
.
中删除 instance ID
下面的代码可以让一个协程控制多个对象,而无需将协程函数放在自己的脚本中。最大的区别在于,当在 the-same 函数上调用新协程时,它会停止该对象上的旧协程 仅 然后创建一个新协程并启动它。
这是我用的。评论很好,让你知道是怎么回事。
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;
}
}
我这里有这段代码:
public void Move(Transform from, Transform to, float overTime)
{
StartCoroutine(_Move(from, to, overTime));
}
IEnumerator _Move(Transform from, Transform to, float overTime)
{
Vector2 original = from.position;
float timer = 0.0f;
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;
}
}
这很简单。它所做的只是随着时间的推移将 GameObject
移动到目的地。我打算将它用于 UI 动画目的。
但是,当我想改变它的用途时,事情就变得有趣了。
例如,我将鼠标悬停在一个开始移动的按钮上。当它仍在移动时,我可能会再次将鼠标悬停在它上面,在这种情况下我希望它重新启动,因此它会停止影响完全相同按钮的 功能并重新启动另一个 。我只是不知道如何确定同一函数的哪个调用会影响我的给定组件。或者我应该将此脚本添加到每个对象以便它只影响那个对象吗?
这里有很多我想做的不同的事情。一方面,如果您的 Ui 对象已经受到协程的影响,您不希望另一个协程也开始作用于它,只是新的协程。为避免这种情况,声明一个协程变量:
IEnumerator myCoRoutine
当您第一次将鼠标悬停在上面时,像这样启动协程:
myCoRoutine = _Move(from, to, overTime);
Start Coroutine(_Move());
但是,您想检查一个协程是否已经 运行,如果是则停止它,然后启动一个新协程,对吗?所以,这样做:
if(myCoRoutine !=null) StopCoroutine(mtCoRoutine);
myCoRoutine = _Move(from, to, overTime);
Start Coroutine(_Move());
您可能希望使用 OnPointerEnter
启动协程While it still moves, I may hover over it again, in that case I want it to restart, so it stops the function affecting the exact same button and restarts another one. I just have no clue how to identify which call of the same function affects my given component. Or shall I add this script to every object so it can affect only that one?
一种解决方案是将包含协程函数的脚本附加到 each 个游戏对象。如果您不想这样做,还有另一种方法可以做到这一点。
首先,简单地存储 IEnumerator
并不足以真正做到这一点。您需要一种方法来识别最后一个协程中的 GameObject 运行。
1.得到一个可以用来识别Object的值。在这种情况下,带有GetInstanceID()
的实例ID应该没问题。
2。制作一个简单的 struct
来保存旧协程信息。
3。最后,制作一个字典,将包含实例 ID(键)和来自 #2 的结构作为值.
有了这三个东西,你就可以启动一个协程,把它添加到Dictionary
。协程完成后,从 Dictionary
.
instance ID
下面的代码可以让一个协程控制多个对象,而无需将协程函数放在自己的脚本中。最大的区别在于,当在 the-same 函数上调用新协程时,它会停止该对象上的旧协程 仅 然后创建一个新协程并启动它。
这是我用的。评论很好,让你知道是怎么回事。
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;
}
}