最近在把另一個第三方插件 - GameObject Grids Pro放進uFrame裏。本身在uFrame以外寫了一個繼承了GridBehaviour的腳本
public class GSHexGridManager : GridBehaviour{
//Game Logic
}
大概是這樣,然後在uFrame裏建立一些玩家(Player)和敵人(Enemy)的東西,希望想在GSHexGridManager用一些玩家和敵人的數據和邏輯,但發覺不把GSHexGridManager轉成uFrameComponent是無法找到玩家和敵人的東西!也就是uFrame這個系統會一直不知道GSHexGridManager這個腳本的存在!
所以,我的 GSHexGridManager要同時繼承GridBehaviour和uFrameComponent兩個類別(Class),但這是C# 不准許的事情!然後想用Interface (介面)的方法去處理這個問題!
然後發覺有人問過這樣的問題:
http://forum.unity3d.com/threads/gamelogic-grids-a-library-for-hex-tri-polar-and-square-grids.189866/page-7#post-1780947
以下是原文的解答重點,大家有興趣可在以上連結自己爬文看看!
Define an interface IGridBehaviour, with method InitGrid with the same signature as InitGrid defined in GridBehaviour. If you want, you can implement the methods defined in GridBehaviour as extension methods for GridBehaviour.You can now let your grid behaviours implement the IGridBehaviour interface, and have them extend from anything you want.
大概就是定義一個Interface IGridBehaviour然後Implement GridBehaviour本身的方法(Methods)。雖然C#本身不支持多重繼承(Multiple inheritance),但是Interfaces的話,實作多少個也沒關係,所以GSHexGridManager就可以好像同時繼承了uFrameComponent和GridBehaviour,代碼如下:
public class GSHexGridManager : uFrameComponent, IGridBehaviour{
//Game Logic
}
然後我跟上了以上連結的方法照做了。可惡!結果還是不行!小弟無能,找不到原因所在,最後還得跑到Slack的uFrame群組求救!
感謝aahz大大出手相助,問題最終解決了,以下為大家送上方法!
答案就是自己做一個類別(Class)包含GridBehaviour和uFrameComponent兩個類別(Class) -
uFrameGridBehaviour<TPoint>
以下是代碼:
using UnityEngine;
using System.Collections;
using Gamelogic.Grids;
using UniRx;
using uFrame.Kernel;
public class uFrameGridBehaviour<TPoint> : GridBehaviour<TPoint>
, IDisposableContainer where TPoint : IGridPoint<TPoint> {
private CompositeDisposable _disposer;
CompositeDisposable IDisposableContainer.Disposer {
get { return _disposer ?? (_disposer = new CompositeDisposable()); }
set { _disposer = value; }
}
protected virtual void OnDestroy() {
if (_disposer != null) {
_disposer.Dispose();
}
}
protected IEventAggregator EventAggregator {
get { return uFrameKernel.EventAggregator; }
}
/// Wait for an Event to occur on the global event aggregator.
///
/// this.OnEvent<MyEventClass>().Subscribe(myEventClassInstance=>{ DO_SOMETHING_HERE });
///
public IObservable OnEvent() {
return EventAggregator.GetEvent();
}
/// Publishes a command to the event aggregator. Publish the class data you want, and let any "OnEvent" subscriptions handle them.
///
/// this.Publish(new MyEventClass() { Message = "Hello World" });
///
public void Publish(object eventMessage) {
EventAggregator.Publish(eventMessage);
}
protected virtual IEnumerator Start() {
KernelLoading();
while (!uFrameKernel.IsKernelLoaded) yield return null;
KernelLoaded();
}
///
/// Before we wait for the kernel to load, even if the kernel is already loaded it will still invoke this before it attempts to wait.
///
public virtual void KernelLoading() {
}
///
/// The first method to execute when we are sure the kernel has completed loading.
///
public virtual void KernelLoaded() {
}
}
看上去好像很煩惱,但其實裏頭所以的代碼都是uFrameComponent的代碼,也就是其實uFrameGridBehaviour 只是繼承了 GridBehaviour的 uFrameComponent!好啦,我放uFrameComponent的代碼給自己參考一下:
https://github.com/InvertGames/uFrameKernel/blob/master/uFrameComponent.cs
「呀!!!!!」
原來整件事這麽簡單就解決了!!!這樣就可以了:
public class GSHexGridManager : uFrameGridBehaviour{
//Game Logic
}
所以下次遇到這個情況可以考慮自己寫一個uFrame腳本包含uFrameComponent和你想繼承的腳本。
沒有留言:
發佈留言