معماری Scriptable Object بخش سوم - پیاده سازی

متغیر های ScriptableObject

می توانیم اطلاعات را به صورت ScriptableObject در قالب Asset نگهداری کنیم


از این متغیر float که به صورت Asset است می توان به عنوان HitPoints ، مقدار دمیج و اطلاعات زمان استفاده کرد.


اگر بخواهیم این متغیر float را تکمیل کنیم می توانیم این حق انتخاب را بدهیم که مقدار constant را انتخاب شود و یا مقدار float که به صورت ScriptableObject است.

با این روش Data به راحتی بین prefab ها به صورت مستقیم به اشتراک گذاشته می شود و دیگر نیازی به یدک کشیدن Singleton نمی باشد.

یعنی دیگر مجبور نیستیم به کلاس Player یا PlayerManager مراجعه کنیم تا به PlayerHP دسترسی داشته باشیم در نتیجه وقتی PlayerHP تغییر کند همه جا مقدارش اعمال می شود.

معماری Event

در بخش های قبلی توضیح دادیم که چطور یک مقدار را بین سیستم ها به اشتراک بگذاریم

اما موارد زیادی وجود دارد که پاس دادن برای ما اهمیتی ندارد!

بلکه یک اتفاقی (Event) می افتد و می خواهیم به آن واکنش (Response) بدهیم.

ویژگی های معماری Event

ماژولار بودن

استفاده در پروژه های دیگر

وقتی چیزی با ایونت پیاده شده باشد ما دیگر برای تغییر آن مجبور به کدنویسی نیستیم و کافیست واکنش هایی که به ایونت ها داده شده است را عوض کنیم.

ایزوله کردن پریفب

حتی پریفب می تواند به یک ایونت پاسخ دهد و اهمیتی ندهد از کجا آمده

بهینه

فقط وقتی احتیاج شود صدا زده می شود.به عنوان مثال شما لازم نیست Player Health را هر ثانیه چک کنید می توانید بگویید وقتی صفر شد فلان ایونت Raise شود.

قابل اشکال زدایی

ایونت را می شود هم در بازی و هم در ادیتور صدا زد و آن را به راحتی تست کرد.

معرفی UnityEvent


با استفاده از UnityEvent بدون کدنویسی می توانید هر کاری کنید به عنوان مثال یک Game Object را غیر فعال کنید. که به صورت تابع Serialized شده فراخوانی می شود.

مزایای UnityEvent

استفاده آسان در ادیتور

با این روش ماژولار به راحتی می توانیم با چند کلیک ساده در ادیتور کاری که می خوایم را انجام دهیم

کد کمتر ، فرض های کمتر!

شما دیگر مجبور نیستید کدی بنویسید که آن را به سیستم دیگر متصل کند با استفاده از ایونت ها به راحتی می توانید این کار را انجام دهید.

پاس دادن آرگومان

به شما اجازه می دهد که آرگومان پاس بدهید.

توسعه جنریک <UnityEvent<T که به شما اجازه می دهد هر آرگومانی با هر نوعی را به صورت static/dynamic پاس بدهید.


مشکلات UnityEvent


سفت و سخت و غیر انعطاف پذیر!

رفرنس دادن سخت Button وقتی باید به آن واکنش دهد

چیز هایی که به آن واکنش میدهد باید از قبل مشخص شده باشد!

به عنوان مثال یک Button باید بداند که وقتی روی آن کلیک شد به چه چیزی واکنش دهد

در نتیجه نمی توان از آن در Prefab استفاده کرد و آن را به UI متصل کرد.

از آنجایی که نمی توان از Prefab استفاده کرد شما مجبورید همه جا یک کار تکراری را انجام دهید و بگید بعد از یک Event به چه چیزی واکنش داده شود.

سریالازیشن محدود

با استفاده از UnityEvent فقط می توان چیز های ساده مثل int , string ,bool را در Inspector مشاهده کرد و برای Type های دیگر این امکان وجود ندارد.

گاربیج الوکیشن

هر دفعه که آن را فراخوانی کنید Garbage تولید می کند.

ساخت ایونت های خودمان

داده محور

قابل ویرایش برای Designer

قابل اشکال زدایی

مثال ساخت ایونت

یک Scriptable Object می سازیم و با استفاده از یک حلقه for تمام ایونت های listener را Raise می کنیم!

حال کلاس listener را تعریف می کنیم و یک ایونت و یک واکنش در آن تعریف می کنیم.

و وقتی OnEnable می شود آن را Register Listener می کنیم

وقتی OnDisable می شود آن را UnRegister Listener می کنیم