Code explanation
Some non relevant code is omitted.
BGCollectable.cs
- This script is attached to every collectable object. This script is hooked to a database by extending from BGM_Collectable class (generated by code generator), which in turn is extended from BGEntityGo- our component we use to connect GameObjects to database. When new collectable object is spawned in the scene byBGSpawner.cs
, Entity field is assigned- and object become linked to a particular table row.
This script has 4 tasks:- Show gold amount on the TextMesh component. This is done by this code
Text.text = "Gold:" + m_gold;
.m_gold
field reads/write data from/to database - Add some gold to the player
- Play sound effect when object's collected.
- Remove the object when it's collected from scene and from database.
public class BGCollectable : BGM_Collectable { //this callback is called then connected entity is changed public override void EntityChanged() { Text.text = "Gold:" + m_gold; } private void OnTriggerEnter(Collider other) { if (other.gameObject.CompareTag("Player")) { var player = other.GetComponent<BGPlayer>(); //add gold player.m_gold += m_gold; //play sound var audioSource = player.GetComponent<AudioSource>(); audioSource.clip = m_type.f_audio; audioSource.Play(); //remove from database & scene Entity.Delete(); Destroy(gameObject); } } }
- Show gold amount on the TextMesh component. This is done by this code
BGGoToScene.cs
- this script is attached to a portal to another scene. When the player collides with this portal, he's moved to another scene. This script is also hooked up to a database, namely toScene
row, pointing to a scene to load. When the player collides with this object, script read data about this scene from database, updates Player table with position and rotation from Scene table and loads target scene.public class BGGoToScene : BGM_Scene { private void OnTriggerEnter(Collider other) { if (other.gameObject.CompareTag("Player")) { //get reference to player var player = other.GetComponent<BGPlayer>(); //set player position & rotation to scene's spawn position & rotation player.m_position = m_spawnPosition; player.m_rotation = Quaternion.Euler(m_spawnRotation); //load the scene SceneManager.LoadScene(Entity.Name); } } }
BGSpawner.cs
- this script fills database with new objects and also spawn them to the scene. It hooked up toScene
table. It uses database events, to find the moment all objects are collected.public class BGSpawner :BGM_Scene { public override void Start() { base.Start(); Spawn(); //use database events to keep track the moment, when all collectables are gathered BGRepo.I.Events.AddAnyEntityDeletedListener(BGE_Collectable.MetaDefault.Id, CheckForNewSpawns); } public override void OnDestroy() { base.OnDestroy(); BGRepo.I.Events.RemoveAnyEntityDeletedListener(BGE_Collectable.MetaDefault.Id, CheckForNewSpawns); } //spawn unity's gameobjects - corresponding to Repo objects private void Spawn() { //fetch collectables from database var collectables = m_Collectable; //no collectables- no luck if (BGUtil.IsEmpty(collectables)) return; //spawn collectables objects foreach (BGEntity collectable in collectables) { //create collectable GameObject var newCollectable = Instantiate(collectable.f_type.f_prefab, collectable.f_position, Quaternion.identity); //we know - collectable prefab has BGCollectable script attached // so hook it up to table's row newCollectable.GetComponent<BGCollectable>().Entity = collectable; } } //This method create new collectables randomly for all scenes if all objects are collected public void CheckForNewSpawns(object sender, BGEventArgsAnyEntity args) { //there are still some collectables if (BGE_Collectable.CountEntities > 0) return; //ok, we gathered all objects- lets spawn new ones BGE_Scene.ForEachEntity(scene => { //number of collectables for one scene var count = Random.Range(3, 6); for (var i = 0; i < count; i++) { //nested meta has utility method, which auto assign new collectable to owner entity (scene) var newCollectable = BGE_Collectable.NewEntity(scene); //set gold newCollectable.f_gold = Random.Range(1, 10); //bounds determines scene's frontiers var bounds = scene.f_bounds; //set position newCollectable.f_position = new Vector3(Random.Range(bounds.min.x, bounds.max.x), bounds.center.y, Random.Range(bounds.min.z, bounds.max.z)); //set type newCollectable.f_type = BGE_CollectableType.GetEntity(Random.Range(0, BGE_CollectableType.CountEntities)); } }); //spawn GameObjects for current scene Spawn(); } }
BGPlayer.cs
- this script is attached to the player and hooked up to a first row ofPlayer
table via extending from BGM_Player.- It initializes its position and rotation from database in the Start method
- It implements
BGAddonSaveLoad.BeforeSaveReciever
interface to ensureOnBeforeSave
method is called before saving. In this method it saves its own position and amount of gold to the database, so while saving those values will be put to the save file.
public class BGPlayer : BGM_Player, BGAddonSaveLoad.BeforeSaveReciever { public override void Start() { base.Start(); //get pos and rotation from the table transform.position = m_position; transform.rotation = m_rotation; } //this method is called before saving void BGAddonSaveLoad.BeforeSaveReciever.OnBeforeSave() { //save current position, rotation and scene to the database m_position = transform.position; m_rotation = transform.rotation; m_scene = BGE_Scene.FindEntity(scene => string.Equals(scene.Name, SceneManager.GetActiveScene().name)); } }
-
BGSavingLoading.cs
It Provides Save/Load functions via SaveLoad addon. More information about Save/Load addon can be found herepublic class BGSavingLoading : MonoBehaviour { //... some code is omitted public void Save() { //save var bytes = BGRepo.I.Addons.Get<BGAddonSaveLoad>().Save(); File.WriteAllBytes(SaveFilePath, bytes); } public void Load() { //load if (!HasSavedFile) return; var content = File.ReadAllBytes(SaveFilePath); BGRepo.I.Addons.Get<BGAddonSaveLoad>().Load(content); //load saved scene SceneManager.LoadScene(R.Player.d_scene.Get(PlayerEntity).Name); } }