不可能使用父班的事件吗?
我有单独的课程来跳跃和跑步。可能还有其他动画动作,例如攀登,飞行,谁知道我会想到什么。因此,将所有这些移动类别从称为AnimAtableMovement的类中继承来是有意义的。它的唯一目的是设置事件。
请考虑:
public class AnimatableMovement : MonoBehaviour
{
public event AnimationStateDelegate OnAnimationStateChange;
public delegate void AnimationStateDelegate(string newState);
}
然后步行:
public class Movement : AnimatableMovement
{
public float speed = 5f;
protected Rigidbody2D body;
void Start()
{
body = transform.GetComponent<Rigidbody2D>();
}
void Update()
{
float horizontalInput = Input.GetAxis("Horizontal");
if (horizontalInput != 0)
{
body.velocity = new Vector2(horizontalInput * speed, body.velocity.y);
OnAnimationStateChange?.Invoke("walk");
} else
{
OnAnimationStateChange?.Invoke("idle");
}
}
}
如果代表在同一类中定义了与动作的同一类,一切都像魅力一样,但违反了干燥原则,因为我必须将相同的两行复制/粘贴到每个运动类型类别。因此,我认为这将是一个不明智的解决方案,但是这样做了,分为两个类,我会收到一个错误:
Assets \ Scripts \ Movems.cs.cs(30,13)(30,13):错误cs0070:事件的AnimatableMovement 。
I have separate classes for jumping and running. There could be other animatable movements, like climbing, flying, who knows what I'll come up with. Therefore it would make sense to make all these movement classes to inherit from a class called AnimatableMovement. Its only purpose is to setup the events.
Please consider:
public class AnimatableMovement : MonoBehaviour
{
public event AnimationStateDelegate OnAnimationStateChange;
public delegate void AnimationStateDelegate(string newState);
}
Then the walking:
public class Movement : AnimatableMovement
{
public float speed = 5f;
protected Rigidbody2D body;
void Start()
{
body = transform.GetComponent<Rigidbody2D>();
}
void Update()
{
float horizontalInput = Input.GetAxis("Horizontal");
if (horizontalInput != 0)
{
body.velocity = new Vector2(horizontalInput * speed, body.velocity.y);
OnAnimationStateChange?.Invoke("walk");
} else
{
OnAnimationStateChange?.Invoke("idle");
}
}
}
If the delegate is defined in the same class as the movement, everything works like a charm, but violates the DRY principle, because I have to copy/paste the same two lines to each movement type class. So I thought this would be a no-brainer solution, but done like this, separated into two classes, I get an error:
Assets\Scripts\Movement.cs(30,13): error CS0070: The event 'AnimatableMovement.OnAnimationStateChange' can only appear on the left hand side of += or -= (except when used from within the type 'AnimatableMovement')
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这就是事件的工作方式:唯一允许举办活动的课程是定义该事件的类。
将事件重命名以删除“ On”前缀,然后添加一个专门的方法来提高它 - 通常可以理解“ On”前缀以确定一种提高事件的方法(或者根据您的命名约定,可以处理事件的方法 - 但是事件本身不应具有任何前缀方案):
然后,继承的类可以访问并调用此方法以提高事件。
That's how events work: the only class that's allowed to raise an event, is the class that defines that event.
Rename the event to drop the "On" prefix, then add a dedicated method to raise it - the "On" prefix is usually understood to identify a method that raises an event (or one that handles an event, depending on your naming convention - but the event itself shouldn't have any prefixing scheme):
Inherited classes can then access and invoke this method to get the event raised.
尝试这种方法:
和:
Try this approach:
And:
调用事件时,请与无效的合并操作员一起进行。如果您调用
onAnimationStateChange.Invoke(...)
,如果onAnimationStateChange
没有任何订户,则将获得null异常。而是将所有类似的事件调用:onAnimationStateChange?.invoke(“ idle”)
使用您的当前代码,该事件将被调用每个帧。您是否希望动画状态改变每个帧?
如果要调用继承事件,只需将其设置为仅在派生类型中才能访问的基类中的方法。只需将此行添加到
AnimAtableMovement
:When invoking events, do it with a null coalescing operator. If you call
OnAnimationStateChange.Invoke(...)
, you will get null exceptions ifOnAnimationStateChange
doesn't have any subscribers. Call all events like this instead:OnAnimationStateChange?.Invoke("idle")
With your current code, the event is going to be called each and every frame. Do you expect the animation state to change every frame?
If you want to invoke an inherited event, just set it up as a method in the base class that is only accessible to derived types. Just add this line to
AnimatableMovement
: