BabyJS Posted November 22, 2016 Share Posted November 22, 2016 I'm using Construct2(C2) for my games. A developer is doing a plugin to use Babylon.js that allow us do 3D games. This was my first test, it's not a big thing but for something we have to start: Here to play: https://kronbits.itch.io/proto3d Preview: - The actual plugin is a "Scene Loader". You do the level on a 3D editor and export the .Babylon file to C2. There you set camera controls and actions using events to do the game. One of the problems is how to solve the action for a group of duplicate mesh objects that have different name. Now, for every mesh we have to create an object on C2 layout, set the 3D name on editor and add all the properties or behaviours we want. The problem is, if the level have 100 coins, each coin have a different mesh name, so we will have to add 100 objects on the layout to set the behaviours or actions, which will be pain. The unique thing we made is more a patch than a solution, some kind of array on we set: Name: Coin Start of index: 0 Ending Index: 100 Padding: (true) So for a Coin and Coin001, Coin002, etc... until Coin100 will set the properties or behaviours or whatever but limit other options to other plugins and other stuff in C2. Also only will works for Blender and 3Dmax, the Unity nomenclature breaks this solution. Here are how the Duplicate models looks in the 3D Editors Babylon can be exported: Blender: Coin, Coin.001, Coin.002, etc... 3Dmax : Coin, Coin001, Coin002, etc... Unity5 : Coin, Coin(1), Coin(2), etc... Maybe there is a solution that we not found, or a Babylon function that solve this, but if not i want to make a request if is possible. Request for Babylon exporters: ------------------------------------------------------------ Add some kind of ID for all the objects, maybe "Babylon_Mesh_ID" or whatever that are the same for all the mesh with the same properties. Then for: Coin, Coin.001, Coin.002,etc... will have the "Babylon_Mesh_ID=COIN". So in the C2 we only will have to create an unique object that refers to "COIN" and add an actions like: On Player collides with COIN > Destroy COIN / Add 1 to COIN.Counter, etc... When the player collides with a mesh with the ID "COIN" will do the events/actions no matter the mesh name. No arrays, patch or other stuff. Is possible? Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted November 23, 2016 Share Posted November 23, 2016 Hello first of all I really appreciate that you use Babylon.js for this We recently added mesh.metadata with support for serialization. So I would suggest to just use mesh.metadata = "COIN" Does it make sense? Quote Link to comment Share on other sites More sharing options...
Wingnut Posted November 23, 2016 Share Posted November 23, 2016 Hiya @Matriax, welcome to the forum! Ok, good questions. We have instances in BabylonJS and they would work great for your coins. Let's go that way, and we'll talk more about other options, later. When all the copies of a source... have the same material/texture, they are a perfect candidate to use instances. But yes, HOW do we get game logic on EACH instance, yet not have to code UPON each instance. Well, I know a way. Perhaps not the CORRECT way, but it is still a way. http://www.babylonjs-playground.com/#1AUY9H#3 There we have one sourceMesh and two instances. Pretend they are your coins. Let's look carefully at lines 2-4. Here I have overloaded the base class that BJS uses to create instanced mesh. I add a "talk" method to that base class. In your case, you might add a function called "disposeCoinInstance". No matter. With lines 2-4, you are adding a talk function to all future-made instances in your project. It calls (passes) to a function with the same name... on its source. So, now, all your coin instances... can automatically have a talk method on them, yet they still maintain light weight. They hand-off the work to their source. Source becomes a "super class" for its instances. A different form of inheritance, yes? You can call killMe() on any coin. The coin will hand-over the task to source.[somefunc]. You can already see that source.talk can determine WHICH instance is calling (an index number). Later in the demo above, you will see a call to instance1.talk(), and a good report from source.talk().... is seen at the console. You can add many "wrapper functions" onto the coin instances, if you like. But these wrappers must be put-onto the coins instances, and the actualy functions added to the source of those instances... in BJS, after import (just before game start). None of that magic can be exported from a modeler, or imported through the .babylon importer. 1. Generally, you would create the source coin in a modeler if you please, import THAT. 2. Then add the coin game logic to source. Full-power functions added to source. Those added functions are ready to do actions to ANY of the source's instances. (like my lines 22-25) Yours might be... source.disposeCoinInstance(whichInstance). 3. Then do something like my lines 2-4. You can put that code anywhere, as long as you do it BEFORE you createInstances of coins. 4. Then do as many masterCoin.createInstances() as you wish. Each instance will have a disposeMe() (or talk()) method... onboard, but it isn't very big. It only hands off the task to source. So source (the master coin) becomes a game logic repository for ALL coins. You will need to position and rotate all the instances you create. The powerful stuff... is on source. The instances themselves... are kept lightweight. No "fat" game logic on them. You have started to build your own "Instances Management System"... onto source coin. Cool, huh? Most of the game-logic (at least for the coin) is done in BJS, and not in modeling software. I hope that doesn't screw you up. You probably wanted to create all 100 coins in the modeler, and position them, etc. But because my idea overloads the BJS instance creation system, the instance-generating and instance positions and rotations... have to be done "late"... in game.init() or similar place. I did another playground... a little more sane. http://www.babylonjs-playground.com/#1AUY9H#4 After 20 seconds, I call instance1.killMe(), and then source.killInstance()... kills the instance. I didn't add the explodeSomeParticles(whichInstance.position); or playTwinkleSound(whichInstance);. I will let you add that game logic yourself. I see Deltakosh has replied. Let's go see what he has to say. (I peeked) He is telling you about the storage trunk called .metadata... that you can use to haul data into BJS -with. I did a console.log of instance1.metatdata. Null (empty). It is ready to haul-in outside data for standard mesh OR instances, apparently. You could put a serialized JSON object in there (a string)... which could be parsed back into an object after arriving in BJS land. That object could be packed-with cool tools (methods) for coins. But still, think about the instances and source system I have shown you, and try to use it as much as possible, even if you DO haul-in a game logic object in the coin's .metadata property. Just avoid creating instances in the modeler and putting game logic objects in EACH instance.metadata. That would be unnecessarily heavy/bloaty, I think. I hope I have been of some help. That's a nice looking game you have, there. Good luck with it! Party on, welcome again. Quote Link to comment Share on other sites More sharing options...
BabyJS Posted November 23, 2016 Author Share Posted November 23, 2016 Hey! thanks for the reply guys! We will try this solutions to see if fits with our problem . Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted November 24, 2016 Share Posted November 24, 2016 Check this link out: U3D - BabylonJS Toolkit - Proof Of Concept But basically we go thru the roll a ball demo from unity ... I do the same kind of coin collection thing... But i don't us mesh.metadata (Which i use in toolkit BTW ) Basically i put a "TAG" on all the pickups (coins in your case) called "Pickup"... then in game code": this.items = this.scene.getMeshesByTags("Pickup"); Then my update loop calls Update Pickup Collisions: private updatePickupCollisions(): void { if (this.items != null) { this.items.forEach((item)=>{ if (item != null && item.intersectsMesh(this.mesh)) { if (item.isEnabled()) { item.setEnabled(false); this.count = this.count + 1; this.updateCollectionCount(); } } }); } } Check out video for details Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.