我有不同的functions
我希望彼此调用。它们都是UI动画,一个用于旋转,一个用于缩放,一个用于移动,依此类推。我希望链接它们,所以在coroutine
结束时,如果订阅了其他内容,则会触发一个事件。目前,我必须为所有创建delegates
,这会使代码的扩展无法忍受。如何创建委托 - 或代表集合? - 谁的活动可以解雇各种功能?
修改
这些功能并不相互依赖。仅移动移动。仅旋转旋转,依此类推。
只有Move
或Rotate
的一个实例可以对一个组件产生影响。
class MoveClass : MonoBehaviour
{
#region Move
//to ensure only one mover coroutine can be active.
public IEnumerator moveRoutine = null;
/// <summary>
/// Moves a UnityEngine.GameObject from position A to position B over timeToReachDestination.
/// Uses Coroutines.
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
/// <param name="overTime"></param>
public void Move(Transform from, Transform to, float overTime)
{
//pull off this shit to ensure only once it will be executed.
if (moveRoutine != null)
{
StopCoroutine(moveRoutine);
}
moveRoutine = _Move(from, to, overTime);
StartCoroutine(moveRoutine);
//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;
}
if(event != null)
{
event(/*parameters*/);
//or loop through the events?
}
}
#endregion
}
答案 0 :(得分:2)
好像你想在你的协程结束时回调一次。
IEnumerator _Move(Transform from, Transform to, float overTime, Action /*<Parameter>*/ onCompletion = null)
{
// Your current code
if(onCompletion!= null)
{
onCompletion(/*parameters*/);
//or loop through the events?
}
}
编辑:添加了onCompletion = null,因此它具有默认参数。
考虑到你可能有不同的回调参数列表,你会想出各种重载。公共代码将移动到在所有不同重载中调用的方法,只有最后一部分会有所不同:
void MoveItem(Transform from, Transform to, float overTime)
{
float step = Vector2.Distance(original, to.position) * (Time.deltaTime / overTime);
from.position = Vector2.MoveTowards(from.position, to.position, step);
}
IEnumerator _Move(Transform from, Transform to, float overTime, Action onCompletion = null)
{
Vector2 original = from.position;
float timer = 0.0f;
while (timer < overTime)
{
MoveItem(from, to, overTime);
timer += Time.deltaTime;
yield return null;
}
if(event != null)
{
event();
}
}
IEnumerator _Move(Transform from, Transform to, float overTime, Action <float>onCompletion = null)
{
Vector2 original = from.position;
float timer = 0.0f;
while (timer < overTime)
{
MoveItem(from, to, overTime);
timer += Time.deltaTime;
yield return null;
}
if(event != null)
{
event(10.0f);
}
}
您可以灵活地为MoveItem方法提供委托,以便您可以传递任何移动方法(移动的形状可以是线性,指数等)。
答案 1 :(得分:1)
以更详细的形式解释我的评论。
您可以从代码中触发全局(一)EventHandler
:
public delegate void MeEventHandler(object sender, MeEventArgs e);
然后如你所料,你应该建立基础MeEventArgs
类:
public abstract class MeEventArgs
{
// nothing in here or some common fields/properties
}
接下来,您可以通过各种方式获得:
public sealed class MeTransformEventArgs
: MeEventArgs
{
public bool SuccesfullyTransformed { get; set; }
public Vector3 PreviousPosition { get; set; }
public Vector3 NewPosition { get; set; }
}
与旋转事件相同:
public sealed class MeRotationEventArgs
: MeEventArgs
{
public bool Successfull { get; set; }
public Quaternion FromAngle { get; set; }
public Quaternion ToAngle { get; set; }
}
和其他人一样......
现在您可以将您的活动设为:
public event MeEventHandler MeEvent;
无论何时你想发动这个事件:
MeEvent(this, (MeEventArgs)new MeTransformEventArgs() { SuccesfullyTransformed = false, PreviousPosition = Vector3.zero, NewPosition = Vector3.zero });
然后你用这些来抓住这些:
void WhenEventFired(object sender, MeEventArgs e)
{
if(e is MeTransformEventArgs)
{
MeTransformEventArgs eArgs = (MeTransformEventArgs)e;
// do something with event.
}
}
答案 2 :(得分:0)
如何创建委托 - 或代表集合? - 谁的活动可以解雇各种各样的功能?
多播代表。
Action onCompletion = SomeMethod;
onCompletion += SomeOtherMethod;
// Now the delegate will call both methods when invoked.
StartCoroutine(_Move(..., onCompletion));
或者你可以简单地制作代表的集合,I.E。 List<Action>
。