SQLite در یونیتی
با سلام
توی این آموزش قراره یکسری اطلاعات بازیمون رو به جای اینکه روی فایل یا PlayerPrefs ذخیره کنیم ، روی دیتابیس Local ذخیره کنیم .
سورس فایل ها و پروژه یونیتی کامل
این پروژه با یونیتی ۵ تست شده است .
قراره که از پلاگینی به اسم SQLite4Unity3d استفاده کنیم . به گفته نویسنده این پلاگین ، روی موبایل هم کار می کنه .
برای این که اطلاعات دیتابیس مون رو مرور کنیم و بتونیم جداول مون رو بسازیم از یک نرم افزار ساده و محانی به اسم DB Browser for SQLite استفاده کردم .
گام اول :
یک پروژه جدید یونیتی ایجاد کنید .
گام دوم :
این لینک رو دانلود کنید و بازش کنید . پس از اکسترکت کردن باید یک فولدر ببینید به اسم Plugins که این فولدر رو عینا کپی می کنید توی فولدر Assets پروژه خودتون(اگه قبلا فولدر Plugins داشتید این با اون باید یکی بشه) . فایل SQLite.cs رو هم کپی کنید توی پروژه تون هر کجا که خواستید.
گام سوم :
توی فولدر Assets بازیتون یک فولدر به اسم StreamingAssets درست کنید .
گام چهارم :
با استفاده از نرم افزار DB Browser for SQLite یک دیتابیس توی فولدر StreamingAssets درست کنید .
تا اینجا گام های عمومی بود . یعنی اگه برای پروژه خودتون می خواهید از SQLite استفاده کنید باید این مراحل رو برید . از این جا به بعد مخصوص این مثال خاص ما خواهد بود .
من در دیتابیسم یک جدول به اسم Team ساختم که ۳ تا فیلد داره . Id ، Name ، Score .
حالا عینا توی کلاس هام هم یک کلاس به اسم Team درست کردم . به این کلاس در حقیقت مدل می گن . یعنی عینا یک مدل از شکل داده هامون توی دیتابیسمون هستش .
using UnityEngine; using System.Collections; using SQLite4Unity3d; public class Team { [PrimaryKey, AutoIncrement] public int _Id { get; set; } public string Name { get; set; } public int Score { get; set; } public override string ToString () { return string.Format ("[Id: Id={0}, Name={1}, Score={2}]", _Id, Name, Score); } }
برای اینکه با دیتابیس هم ارتباط بر قرار کنیم از این کلاس استفاده کردم.
using UnityEngine; #if !UNITY_EDITOR using System.Collections; using System.IO; #endif using SQLite4Unity3d; using System.Collections.Generic; public class DatabaseHandler { private SQLiteConnection _connection; public DatabaseHandler(string DatabaseName){ #if UNITY_EDITOR var dbPath = string.Format(@"Assets/StreamingAssets/{0}", DatabaseName); #else // check if file exists in Application.persistentDataPath var filepath = string.Format("{0}/{1}", Application.persistentDataPath, DatabaseName); if (!File.Exists(filepath)) { Debug.Log("Database not in Persistent path"); // if it doesn't -> // open StreamingAssets directory and load the db -> #if UNITY_ANDROID var loadDb = new WWW("jar:file://" + Application.dataPath + "!/assets/" + DatabaseName); // this is the path to your StreamingAssets in android while (!loadDb.isDone) { } // CAREFUL here, for safety reasons you shouldn't let this while loop unattended, place a timer and error check // then save to Application.persistentDataPath File.WriteAllBytes(filepath, loadDb.bytes); #elif UNITY_IOS var loadDb = Application.dataPath + "/Raw/" + DatabaseName; // this is the path to your StreamingAssets in iOS // then save to Application.persistentDataPath File.Copy(loadDb, filepath); #elif UNITY_WP8 var loadDb = Application.dataPath + "/StreamingAssets/" + DatabaseName; // this is the path to your StreamingAssets in iOS // then save to Application.persistentDataPath File.Copy(loadDb, filepath); #elif UNITY_WINRT var loadDb = Application.dataPath + "/StreamingAssets/" + DatabaseName; // this is the path to your StreamingAssets in iOS // then save to Application.persistentDataPath File.Copy(loadDb, filepath); #endif Debug.Log("Database written"); } var dbPath = filepath; #endif _connection = new SQLiteConnection(dbPath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create); Debug.Log("Final PATH: " + dbPath); } public void addTeam(Team _team) { _connection.BeginTransaction(); _connection.Insert(_team); _connection.Commit(); } public void updateTeam(Team newTeam) { _connection.Update(newTeam); } public List<Team> getTeams() { _connection.BeginTransaction(); var Teams = _connection.Table<Team>(); List<Team> _teams = new List<Team>(); foreach (var item in Teams) { _teams.Add(item); } _connection.Commit(); return _teams; } }
حالا دست آخر برای تست کار کردن باید یک کلاس دیگه درست کنم که این ها رو تست کنه من اسمش رو می ذارم Test.cs . پس اول یکسری داده توی دیتابیسمون می ریزم ، با استفاده از DB Browser for SQLite ، بعد توی این کلاس Test اول لیست تیم ها رو میگیرم ، بعد یک تیم اضافه می کنم ، اطلاعات یک تیم رو آپدیت می کنم و دوباره لیست تیم ها رو چاپ می کنم .
اینم کلاس تست :
using UnityEngine; using System.Collections; public class Test : MonoBehaviour { public DatabaseHandler dataHandler; // Use this for initialization void Start () { dataHandler = new DatabaseHandler("TestDB"); Debug.Log("---------------------Teams---------------------"); var teams = dataHandler.getTeams(); foreach (var item in teams) { Debug.Log(item.ToString()); } Debug.Log("---------------------AddTeam---------------------"); var team = new Team(); team.Name = "new Team"; team.Score = 0; dataHandler.addTeam(team); Debug.Log("---------------------UpdateScoreOfTeam---------------------"); teams[1].Score = 200; dataHandler.updateTeam(teams[1]); Debug.Log("---------------------Teams---------------------"); teams = dataHandler.getTeams(); foreach (var item in teams) { Debug.Log(item.ToString()); } } }
سلام عالی بود دستت درنکنه
بازم ادامه بده ما هواتو داریم
در پناه حق..
خیلی ممنون .
سلام آقا امین از بابت کارت تشکر میکنم
یه سوال چرا وقتی از پروژه کامل استفاده میکنیم این ارور میده DllNotFoundException: sqlite3
ممنون
ممنون 🙂
من پروژه رو همین الان از گیت هاب دانلود کردم و ران کردم مشکلی نبود . این فایل dll که شما گفتی باید توی مسیر Assets/Plugins/x86 باشه ، چک کنید ببینید اینو دارید یا نه.
آره دارم آقا امین واقعا دلیل ارور نمیفهمم
روی چه پلتفرمی اجراش می کنید ؟
پلاگین SQLite4Unity3d رو دانلود کنیدو نصب کنید ، شاید آپدیتی بهش داده باشن.
امین جان مشکلی از پلتفرم و…نیست
مشکل اینه که این پلاگین آپدیت شده مخصوصا برای Unity5 که بنده استفاده میکنم و این Tutorial باید مثالش تغییر کنه
چون Sample که در GitHub برای Unity وجود دارد کاملا کار میکند
ممنون باتشکر
تا شما اطلاعات ندید من نمی تونم ارور شما رو ایجاد کنم ، من سورس پروژه خودم رو دانلود کردم و با یونیتی ۵ تستش کردم . کار می کرد . پلتفرمی که خودم روش تست کردم مک هستش . من پلاگین رو آپدیت می کنم و تست می کنم ببینم مشکلی می بینم یا نه . این طور که الان من فهمیدم اگه طبق آموزش پیش برم باید به مشکل بخورم درسته ؟
آره یه تیکه از کد در Script DatabaseHandler خط 11 -15 باید درست بشود ارور میده طبق آموزش
خیلی ممنون که خبر دادید 🙂
اصلاح شد.
سلام
ممنون از اموزش فقط چرا برای خروجی pc کار نمیکنه ؟!
ممنون میشم جواب بدین
به صفحه اصلی پلاگین در Github مراجعه کنید، احتمالا پلاگین آپدیت شده.
سلام. ممنون از آموزش خوبتون
آیا با این پلاگین میتونم رمز روی بانک بزارم؟
سلام، لطف دارین. چند تا راه حل هست، فکر کنم خود SQLite امکان رمز گذاری رو داره، اینو نمی دونم که این پلاگین این قابلیت رو به شما می ده یا نه. ولی اگه راه حل دیگه ای خواستید می تونید خودتون دیتا ها رو به صورت رمز شده وارد دیتابیس کنید و موقع خوندن رمز گشایی کنید.
سلام ممنون از پست خوبتون
می خواستم بدونم این دیتا بیس روی ios هم جواب میده؟
ممنون
سلام خواهش می کنم لطف دارین،
حقیقتش من تست نکردم بهتره برای اینکه مطمئن بشید به گیت هاب سازنده پلاگین مراجعه کنید.
SQLite4Unity3d
با سلام و تشکر
ببخشید لینکی که برای پلاگین دادید ارور404 میده…
از جای دیگه ای میشه دانلود کرد؟؟
لینک اصلاح شد.
با تشکر از شما
سپاس فراوان
ببخشید فقط من یک سوال دارم و حقیقتش در این مدتی که درباره اش تحقیق کردم به نتیجه ای نرسیدم.
راستش من این آموزش رو برای استفاده در اپلیکیشن واقعیت افزوده با یونیتی دنبال کردم. الان راستش به مشکل خوردم و قسمتهایی از کار برام مبهمه. مثلا کد اسکریپتی که باید برای اتصال به پایگاه داده استفاده بشه رو میدونم و دارم. مشکلم در قسمتی هست که اشیا رو فرزند تصویر هدف قرار میدیم. چون هدف من این هست که اشیای ar کاملا از پایگاه داده گرفته بشن و دیگه تو محیط ادیتور نباشند اما نمیدونم برای اون قسمت فرزند قرار دادن چه کار میشه کرد . میشه اگر آموزشی سراغ دارید یا جوابش رو میدونید یک راهنمایی بدید؟ من خیلی ممنون میشم.
اگه درست متوجه شده باشم راه حلی که به شما پیشنهاد می کنم اینه که آبجکت ها تون رو به صورت Prefab در فولدر Resources قرار بدید و سپس لینک به موقعیت اون ها(مثلا “Resources/Objects/1”) رو در دیتابیس ذخیره کنید و در موقع لزوم اون ها رو با استفاده از Resources.Load لود کنید و به کمک transform.SetParent فرزند آبجکت مد نظر تون قرار بدید.
خوب من میخوام وقتی اپلیکیشن رو درست کردم واشیای ar رو داخلش قرار دادم اگر خواستم این اشیا رو تغییر بدم یا بهشون چیزی اضافه کنم مجبور نباشم کل فایل apk رو تغییر بدم، قبلی رو پاک کنم، فایل جدیدو دوباره نصب کنم و….
هدفم اینه که اگر خواستم اشیای ar رو اضافه یا کم کنم بدون اینکه به اپلیکیشنم دست بزنم این کار رو با استفاده از پایگاه داده انجام بدم طوریکه دیگه نیاز نباشه برنامه رو تغییر بدم . اشیا رو توی پایگاه تغییر بدم و دفعه ی بعد که گوشی رو روی تصویر هدف گرفتم همون چیزهای توی پایگاه داده رو نمایش بده.
فقط …این راه حلی که شما معرفی کردید کدهاش برای اتصال به sql server هم کاربرد داره؟ چون اون حالت برای شرایط من مطلوب تر هست. کدهای اتصال یونیتی به sql server رو هم از نت پیدا کردم منتها فقط با همین قسمت که باید اشیا فرزند تصویر هدف باشن مشکل دارم.
خیلی ممنونم
در مورد بخش اول : این کار نشدنی است یا حداقل من بلد نیستم، چون هر گیم آبجکتی که وارد موتور می شود دارای بخش های مختلف از جمله مش، متریال و یکسری تنظیمات Import هستش، نمیشه مستقیما بدون Import کردن و بدون متریال چیزی به فضای بازی اضافه کرد. در نتیجه گیم آبجکت را نمی شود در دیتابیس قرار داد و حتی هم اگر بشود کار خوبی نیست.
و اما در مورد بخش دوم : دیتابیسی که توی این آموزش در موردش صحبت شده یک دیتابیس لوکال هستش و در واقع این دیتابیس روی گوشی هست نه روی سرور! چیزی که شما می خواهید متفاوت است. به طور کلی وصل شدن مستقیم کلاینت به دیتابیس اصلا معماری درستی نیست و به شدت مشکل امنیتی دارد. کلاینت باید به یک برنامه در سمت سرور وصل شود و این برنامه سمت سرور هست که باید با دیتابیس صحبت کند.
در نهایت پاسخ به سوال اصلی شما :
شما یک سیستم AR می خواهید درست کنید که بشود تارگت ها و محتوای افزوده اون رو به صورت آنلاین عوض کرد بدون تغییر کلاینت. در هر صورت باید کلاینت تارگت ها و محتوا ها را دریافت کند منتها این کار باید به صورت نا محسوس انجام شود.
راه حل های پیش روی شما :
1- خود سیستم هایی که SDK واقعیت افزوده تولید می کنند این قابلیت رو به صورت جداگانه روی ابر خودشون ارائه می کنند با پرداخت هزینه این کار.
2- استفاده از Asset Bundle ها در یونیتی. به کمک Asset Bundle شما می توانید داده های بازی خود را اپدیت کنید(تقریبا شامل هر چیزی می شود).
3- راه های پیچیده تر که از نه بنده بلدم و نه شما حوصله اش رو دارید 🙂
نه…فکر کنم منظورم رو بد گفتم. نکته اول اینه که اشیای من به اون صورت رایج تو یونیتی نیست چیزای ساده ای که تو دیتا بیس میشه گذاشتشون متن و فیلم و عکسه. نکته دوم : من به سرور نمیخوام وصل بشم sql server رو روی لپتاپم دارم . کد اتصال یونیتی به sql server رو هم دارم. تصویر هدفم رو هم نمیخوام تغییر بدم فقط میخوام بشه محتوای نمایش داده شده رو تغییر داد. اما اگر برای این کار هم احتیاج به این راه حل ها هست من همین رو پیگیری میکنم.
خیلی ممنونم از شما
البته من به شخصه عکس رو هم توی دیتابیس نمی گذارم. از مطلب بعدی تون متوجه شدم که پروژه یک پروژه دانشجوییه 🙂 ، با توجه به شرایط برای قرار دادن عکس و متن کافیه که به اون آبجکتی که فرزند تصویر هدف هست چند تا کامپوننت مختلف (Text , SpriteRenderer) داد و با توجه به آیتمی که می خواهید لود کنید کامپوننت مد نظرتون رو فعال و باقی کامپوننت ها رو غیرفعال کنید تا محتوای مد نظرتون نمایش داده بشه.
بله پروژه دانشجویی هست ولی خوب دیتابیسش لازمه …خیلی ممنونم از راهنمایی شما. پس به هر حال من مجبورم فیلم و عکسها رو موقع ساخت برنامه تو محیط یونیتی بیارم برای اینکه فرزند تصویر هدف قرارش بدم؟ راهی نداره که به صورت داینامیک از دیتا بیس بگیره و فرزند تصویر هدفم قرار بده؟
آسون ترین راه همون Asset Bundle هستش
البته یه راه سخت هم هست که باید یک وب سرور راه اندازی کنید(لزوما نه روی سرور بلکه روی سیستم خودتون هم میشه) بعد فیلم ها و عکس ها را روی اون قرار بدید ، لینک اون ها رو در دیتابیس بگذارید، با یونیتی فایلها رو از فایل سرور دانلود کنید و تبدیل به محتوای مد نظر خودتون کنید.
خیلی خیلی ممنونم از راهنمایی شما و وقتی که گذاشتید. واقعا مفید بود.
متشکرم
خواهش می کنم، موفق باشید.
سلام . ببخشید من درباره ی راه حل شما تحقیق کردم فقط یک سوال کوچیک داشتم. الان برنامه ی من یک تصویر هدف داره و چند تا شی با button به صورت ترتیبی روش نمایش داده میشن. با استفاده از این روش asset bundle همچنان میشه این کارو انجام داد یا کلا فقط یک شی میتونم نمایش بدم؟ این رو متوجه نشدم
بله، Asset Bundle صرفا یک راهکار برای آپدیت بازی است. و ربطی به باقی موارد ندارد.
واقعا ممنوونم.کمک بزرگی بود.
متشکرم از شما.
سلام و خسته نباشید
ببخشید که من سوالم رو اینجا میپرسم با اونکه شاید بازم خیلی مرتبط نباشه…اگر سایت دیگه ای یا راه ارتباطی دیگری هست بفرمایید که من از همونجا سوالم رو مطرح کنم.
راستش من درباره ی همین بحث assetbundle ها سوال دارم. الان خیلی وقته که دارم تحقیق میکنم ولی متاسفانه به نتیجه ای نرسیدم. خود یونیتی یک پکیج داره برای اینکار که دانلود نمیشه و از محیط است استورش نمیشه تو یونیتی استفاده کرد به خاطر تحریم.
بعد یکسری آپدبت و کدهای دیگه مرتبط با است باندل پیدا کردم که بیشتر مربوط به برنامه های ویندوزی بودن اما اپلیکیشن واقعیت افزوده ی من برای اندروید هست . تو ووفوریا هم سرچ کردم برای است باندل و کدی که پیدا شد ( فکر میکنم که برای اندروید باشه با توجه به کاری که ووفوریا انجام میده) تو محیط یونیتی کار نمیکرد. و یا اگر هم اسکریپتش ارور نده موقع بیلد کردن ارور کامپایل میده. من میخواستم بپرسم که از این روش برای اپ های اندروید هم میشه استفاده کرد یا نه…چون واقعا گیج شدم و نمیدونم ایراد از کجا میتونه باشه.
خیلی ممنونم
سلام
ممنون از شما آقای سجودی
در مورد خذف باید چکار کنیم در کلاس تست یک نمونه delete را هم بگذارید یا همین جا در جواب بنویسید ممنون
سپاس از شما