Player models 🧍🏽‍♀️🧍‍♀️

Hi
I am trying to make a small online game, but my knowledge of Three is quite limited.
I need to connect a 3d character to every connecting player. What I have to know:

  1. Please give me advice on what is the best 3d format to use
  2. How to load an instance with textures and animations
  3. How to then connect it to the user instance for a user to be able to move it separately (and script to be able to trigger animations separately)

I hope someone could help me.

GLTF

Search for “GLTFLoader” in the docs, and “extensions” in the example to find the gltf / extensions example. Check out the source code with the button at bottom right.

Looks like you have a lot of learning to do regarding web development in general.

I would first leave Three.js alone for now, and go do the tutorials at http://meteor.com to learn about full stack web development first.

1 Like

Sneaky plug for the meteor framework? :stuck_out_tongue:

TBH I think recommending someone learn web dev via Meteor is unfair. I’ve just read skimmed an entire what is meteor article and I’m still not sure what it does. EJSON, DPP, Cordova, fibers/futures, Mongoose mongo driver. What the hell?

If you’re learning web dev, start with pure HTML, CSS, JavaScript, and a simple development server. Build a couple of simple apps that way. Later, you can make an informed decision about what framework (if any) to use.

7 Likes

TBH, that does not really help guys)

I do not have problems with networking.

From the Three docs I don’t get how to unpack GLTF file into separate geometry, materials and animations. Hence the question on how it is possible to create a separate instance of a loaded object.

@AzazaMaster Hello :slight_smile:
Regarding loading 3D models, please have a look at:
https://threejs.org/docs/index.html#manual/en/introduction/Loading-3D-models
! three.js docs !

And for animation:
https://threejs.org/docs/index.html#manual/en/introduction/Animation-system

Feel free to also look at Examples.

Once you load the GLTF file, gltf.scene will be the an instance of THREE.Group and it’s children are all the models and objects from your scene. GLTF Loader will construct ready to use instances of THREE.Mesh out of your models, with properties of .geometry and .material. Materials will contain textures.

As for animations - gltf.animations will be an array of Animation Clips, which can be used as demonstrated in docs linked above.

2 Likes

@DolphinIQ omg, dude, you’re the guy! Thanks so much.

Do you think you could help me with an example?
This is an object I get upon logging gltf.scene and I don’t neither .geometry, nor .material in there. However when I load the whole thing it shows up correct.

Group {uuid: "2F9F0492-F95E-4C94-8D82-49209E1668FB", name: "defaultScene", type: "Group", parent: null, children: Array(1), …}
castShadow: false
children: [Object3D]
frustumCulled: true
layers: Layers {mask: 1}
matrix: Matrix4 {elements: Array(16)}
matrixAutoUpdate: true
matrixWorld: Matrix4 {elements: Array(16)}
matrixWorldNeedsUpdate: false
name: "defaultScene"
parent: null
position: Vector3 {x: 0, y: 0, z: 0}
quaternion: Quaternion {_x: 0, _y: 0, _z: 0, _w: 1, _onChangeCallback: ƒ}
receiveShadow: false
renderOrder: 0
rotation: Euler {_x: 0, _y: 0, _z: 0, _order: "XYZ", _onChangeCallback: ƒ}
scale: Vector3 {x: 1, y: 1, z: 1}
type: "Group"
up: Vector3 {x: 0, y: 1, z: 0}
userData: {}
uuid: "2F9F0492-F95E-4C94-8D82-49209E1668FB"
visible: true
eulerOrder: (...)
id: 18
modelViewMatrix: Matrix4 {elements: Array(16)}
normalMatrix: Matrix3 {elements: Array(9)}
useQuaternion: (...)
__proto__: Object3D

No prob :cowboy_hat_face:
GLTF Loader wraps everything up into a THREE.Group (the gltf.scene, which you are logging/inspecting). Only instances of THREE.Mesh will contain geometry and material.

You need to dig a little deeper - if you look through gltf.scene.children you will find the models you’re looking for. Three.js also provides a couple of useful methods to search through scene graphs, for example:

  • .traverse, which you can use like so:
    gltf.scene.traverse( ( object ) => { console.log( object.name ); })
  • .getObjectByName if your models are named appropriately in the 3D app, you can use this to quickly find an object you want:
    let headModel = gltf.scene.getObjectByName('head');
  • and some other methods, which you can find in the Object3D docs
1 Like

There is something to be aware of when creating multiple instances of one asset animated with skeletons. You must use THREE.SkeletonUtils.clone.

Look at how I did in Edelweiss :

Ah, ok. I thought that by

How to then connect it to the user instance for a user to be able to move it separately (and script to be able to trigger animations separately)

you meant you wanted to know how to connect the things on a network (like multiplayer with one player per browser). Meteor is a really good way to do it.

But yeah. Basically gltf.scene is a tree, and you can get anything you want out of there (one way is with gltf.scene.traverse to traverse the tree until you find what you need.

(Off topic: @looeee The official tutorials explain Meteor much better than that what-is-meteor article. The article is more like “what is inside Meteor”. I really believe Meteor is the easiest/simplest way to make full-stack apps in JavaScript. Try this tutorial, if you have a chance: Meteor Software - Build with Meteor.js, deploy on Meteor Cloud)

To clarify why the GLTF result is missing geometry and material.

GLTF describes whole scenes - there could be several lights for example (of diffferent types). There could be several different cameras in this scene as well (also with different types). Then it could be just one asset - with mesh and textures (ie. a Pine Tree), but the GLTF could be describing a pine forest (100 pine trees).

Mesh, Scene, Light, Camera are all Object3D so they can all be connected disconnected, and positioned.

If you export several lights out of your app, into GLTF, but no meshes, no objects will have .geometry and .material. All will have .position, and some will have .lightColor and lightIntensity.

If you export a whole scene, with a lot of assets lights and cameras, you will get many Object3D, all will have position but only some will have geometry, some will have fov others will have intensity.

Finally, imagine if you exported an entire car with a 1000 different geometries (wheel, windshield, door, etc). If these are in one GLTF, you will somehow have to have 1000 of different geometry. Each will belong to some Mesh and each Mesh will belong to one Object3D a Scene.

If you were looking for one particular geometry, you’d have 1000 to chose from. That’s why they cant be on that first node. As @trusktr explained, this is a tree, which has to be traversed.

@trusktr

I believe the issue that was raised is that you do not need a framework to make an UI because it’s more involved than doing it with “regular” HTML + CSS + JS. When suggesting a framework, there are many to choose from, so it can get very opinionated.

Regarding the tree in the GLTF export, yeah, I agree: it can have many different types of objects depending on what was exported. It may not be easy or simple to select everything from it. Where I work, the designer organizes things into top-level groups so that in the export I can easily pick what I need. It will depend on how the content before export is organized. If the designer changes the structure every time, then that’ll causes breaking changes to the code. TLDR: we gotta plan what structure needs to be exported.

Yeah, you don’t need a full-stack framework just for a UI. That’s why I explained that I suggested Meteor because based on the description it seemed that the OP wanted network connectivity with multiple users, which would be more than just a UI. But that may not have been the case. :slight_smile:

(Plus, I like Meteor. I’ve tried them all. It’s the best. :wink: :slight_smile:

1 Like

Hehehe that seems about the appropriate sized font for that kind of an opinion :slight_smile:

That is an excellent point about GLTF, how you organize it may really help with usage in something like three.js. Not all containers need to be spatial, some can be just to group certain things.

1 Like

If you’re intending to make a game, i suggest looking into a game engine. There are a few out there. Game engines abstract a lot of common tasks for you, such as animation, physics, user interface, input/output and more.

One such engine is meep, it handles animations and does use three.js as a rendering engine by default. It also supports GLTF as the default 3d model format.

disclosure: I’m the author of meep

Here’s a sample of what an animating a model looks like in meep:

const entityBuilder = new EntityBuilder()
	.add(Transform.fromJSON({
		position:{0,0,0}
	})) //gives position, scale and rotation
	.add(Mesh.fromJSON({
		url: "http://web.site/mode.gltf"
	}) // Actual 3D model
	.add(Animation.fromJSON({}) // Animation component is required to let a Mesh animate
	.add(AnimationController.fromJSON([
		{
			startEvent:"jump-event",
			loop: false,
			animation: "jump-animation"
		}
	])); // Event-driven animation controller	

entityBuilder.build(sceneData); //construct the entity onto the scene


document.body.addEventListener('click',()=>{
	sceneData.sendEvent(entityBuilder.entity, 'jump-event');
});

Here we assume that your GLTF model has an animation named “jump-animation”, when you click on the screen - that animation will be played.

2 Likes