Added the new Space Carrier example - Yuka | Space Carrier - State Machine
In this example an autonomous State-driven agent (a small spaceship) collects red artefacts inside the sphere. After collecting 2 artefacts it goes to the base to unload cargo, then the process repeats.
thanks very much for doing this and SHARING it… wonderful contribution to the community. I’ve already enjoyed these examples a ton, and look forward to using the details. WOOT!
This is so cooooool GG
Hi, I played with the yuka a bit and its really nice so far. Very easy to use. I have one usecase in mind that I am not sure how to implement. My understanding is that you pass the mesh object into yuka entity to give it some sort of physical behaviour. What if I want my babylon mesh move around with yuka but have physical interactions with other objects that have physics attached. For example if yuka driven mesh falls on some platform or some physical ball falls on the yuka driven mesh.
I dont think you can have physics impostor attached to a mesh you pass to yuka.
One option I think it would work is to take yuka generated velocity vector and apply to a mesh with an impostor. But then you dont want the mesh passed to yuka so it would have to be some hidden shadow mesh? Any ideas? @labris @roland
Hello!
This something I was thinking about already and I came up with the same idea as yours. Basically YUKA tries to be as lightweight as it is possible so there is no full physics support as you already experienced.
What you might want to do is to update the positions/velocities of your YUKA vehicles before you call entityManager.update()
then you update the velocities on your physics bodies with the values from the YUKA vehicles and after these two steps you make a physicsEngine.step()
call. I suggest you to not to use the BabylonJS physics impostors but use the physics engine directly so you can fully control it. This is just theory at the moment and I didn’t try it out, but should work.
You don’t need to pass a mesh to YUKA (this is the case when you don’t need the bounding info), you don’t need to use the setRenderComponent
at all. You can move your vehicles in the YUKA virtual world and use the position/rotation/velocity information from the vehicles to position them on the BabylonJS scene.
I already started to make a helicopter scene with CANNON physics and YUKA nav points but didn’t get to the point of utilizng YUKA but the approach I was writing about should work. We’ll see
So to sum up I am not sure how it will be working together and how to use a fully fledged physics engine with YUKA but there is a showcase in YUKA which @labris (you do? ) is working on, it’s a football game and it uses it’s own physics in it’s MovingEntity
classes. Here is short video how is it working:
https://yuka.babylonjs.xyz/kickoff.mkv
Here you can see how it deals with the ball physics.
class Ball extends MovingEntity {
/**
* Constructs a new ball.
*
* @param {Pitch} pitch - A reference to the soccer pitch.
*/
constructor(pitch) {
super()
/**
* The bounding radius of the ball.
* @type {Number}
*/
this.boundingRadius = 0.1
/**
* The mass of the ball.
* @type {Number}
*/
this.mass = 0.44 // 440g
/**
* The maximum speed of the ball.
* @type {Number}
*/
this.maxSpeed = 42 // 42 m/s ~ 150km/h
/**
* A reference to the soccer pitch.
* @type {Pitch}
*/
this.pitch = pitch
/**
* The friction of the ball. This value decreases the velocity of the ball over time.
* @type {Number}
*/
this.friction = -0.8
// internals
/**
* Represents the previous position of the ball in a simulation step.
* @type {Vector3}
*/
this._previousPosition = new Vector3()
}
/**
* Updates the ball physics, checks for goals, tests for any collisions and
* adjusts the ball's velocity accordingly.
*
* @param {Number} delta - The time delta value.
* @return {Ball} A reference to this ball.
*/
update(delta) {
this._previousPosition.copy(this.position)
_brakingForce.copy(this.velocity).normalize().multiplyScalar(this.friction)
_acceleration.copy(_brakingForce).divideScalar(this.mass)
this.velocity.add(_acceleration.multiplyScalar(delta))
if (this.getSpeedSquared() < 0.0001) {
this.velocity.set(0, 0, 0)
}
super.update(delta)
if (this._isScored() === false) {
this._collisionDetection()
}
return this
}
/**
* Applies the given force to the ball. For simplicity we do no use a physical correct model here:
*
* 1. The ball is assumed to have a zero velocity immediately prior to a kick.
* 2. The force and the resulting acceleration of a kick is applied in a single simulation step.
* Hence, the lenght of the acceleration represents the new speed (and consequently the velocity) of the ball.
*
* @param {Vector3} force - The force.
* @return {Ball} A reference to this ball.
*/
kick(force) {
_acceleration.copy(force).divideScalar(this.mass)
this.velocity.copy(_acceleration)
return this
}
Thanks @roland , I didnt know you dont have to pass the mesh into yuka. This will be perfect for what I have in mind. Football game looks nice. Hopefully will post my usecase demo soon as well.
As for helicopter physics. I work on an airplane physics which I posted in demos while ago here. I need yuka for enemies and other stuff. Would be nice to add helicopters (easier to shoot down )
If you get the physics working share it with us please. I am really curious whether your/my idea will work.
My copter is a Super Cobra attack helicopter so good luck shooting it down
I cam share you the physics code now if you’re interested.
I will for sure.
Code for helicopter physics would be nice. Ive heard its harder to implement than airplane for some reason.
Ok, sharing in private. I’ll make the whole repo available for everyone after it’s finished.
In the follow path example I removed the line with setRenderComponent where the mesh and sync function is passed to yuka. It seems after doing that the velocity is not updating anymore (zero). The position property is changing fine. Are there any extra steps I should be doning in that case?
not sure if I am doing something wrong but velocity vector is zero even with the mesh loaded and moving. Position seems fine. I suppose I could calculate velocity from position change and time but I thought its internally calculated anyway.
ok, my bad, messed up the path. Its all good
Hey! I was more than two weeks off. So is it working for you?
yes it works fine as you said. No need to even pass the babylon mesh.
I have some other questions but I will create a separate thread for it.
@labris @roland When I say good job, I really, really mean it. There was so much stuff that I wanted to add to my awesome-babylonjs list that I had trouble not adding every single demo. I had to rework some of the structure to accommodate all the new links. Your work will be very helpful to many developers.
This is the kind of work I think is needed to take Babylon beyond simple rectangles and asset loading into creating real and engaging games.
Thanks dude! There should be more coming, but I am completely busy these weeks, barelly have time to sleep lol…
I played with yuka for a while and I am quite happy about it. Managed to use it to move my aircraft carrier following path and for bird flock I can now chase with my plane. Post with video here
Few comments on yuka:
-I think its not fully 3D as its meant mostly for FPS games. For example wander behavior is only x,y (there are others only 2D). I suppose its fine when combined with follow path. Fortunately its easy to extend.
-I had to add a behavior for limit sphere/box otherwise birds would just wander away.
-Not sure what is the physics aspect doing in there. For birds I added functions to adjust the speed based on up vector so it looks like it speeds up/down on climb/decent.
Amazing works !! Does Yuka Game AI include behaviour tree and Markov System ?
What you might want to do is to update the positions/velocities of your YUKA vehicles before you call
entityManager.update()
then you update the velocities on your physics bodies with the values from the YUKA vehicles and after these two steps you make aphysicsEngine.step()
call. I suggest you to not to use the BabylonJS physics impostors but use the physics engine directly so you can fully control it. This is just theory at the moment and I didn’t try it out, but should work.
I just saw this post. The date you posted this is roughly the same date I was hesitating if it makes sense to use ammo.js for collision detection and use YUKA for steering.
I used similar approach and it worked quite well. The physics engine simulate the world and the time ticks forward. The position info is sync back to YUKA world at every frame. YUKA computes the velocities for next tick and sends the new velocities to the physics engine. I also implemented flowfield path finding as a Steering Behavior in YUKA so it can be seamlessly combined with other build-in steering behaviors in YUKA: My first babylon.js hobby project - work in progress - #3 by slin
I added as example NavMesh with ReadyPlayer avatars walking - Yuka | Navmesh with Spatial Index and Tasks