Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities

This article also participated in the “Digitalstar Project” to win a creative gift package and creative incentive money

preface

Believe play treasure can dream of sword and shield friend see tears lizard will be very kind, this period we can dream tears through a mouse control treasure lizard moving scene, for example, only about how to use the mouse to capture 3 d coordinates, and make roles perform run to make its move to coordinate point, the other scenario, introduction and use of resources and so on is not the theme of this content, So do not tell.

Let’s start with the Kangkang effect:

As you can see from the above effects, when clicking on any point of the mouse our little lacrimal lizards are very obedient. Next, we will talk about how this click event is achieved, and how it runs to the end, we are off ~

The body of the

The development process

First of all, I will briefly explain the development process of this case:

  1. Introduce three. Js, gltFloader.js, gsap.js, orbitControls.js.
  2. Initialize the main logic, create scenes, lights, cameras, load resources, and bind mouse events.
  3. After importing resources, create ground and teareye lizards, jump to size and coordinates and animate characters.
  4. Click the mouse to achieve the movement and running animation switch.

Coordinate capture and transformation

bindEvent() {
    // Other events to bind...
    window.addEventListener("mouseup".this.onMouseUp.bind(this));
}
Copy the code

We will bind the mouse lift event first, because we have the scene controller to drag and drop the view, so we can not directly use the mouse to press down, but bind the mouse lift, so that we can determine whether the camera moves (i.e., let the camera move or the character move).

onMouseUp(e){
    // Some logical judgment, if it passes then let him perform capture coordinates to make the character move...
    let vector = new THREE.Vector3();
    vector.set(
        (e.clientX / window.innerWidth) * 2 - 1,
        -(e.clientY / window.innerHeight) * 2 + 1.0.5);
    vector.unproject(this.camera);
    let raycaster = new THREE.Raycaster(this.camera.position, vector.sub(this.camera.position).normalize());
    let intersects = raycaster.intersectObjects(this.scene.children);
    if (intersects.length > 0) {
        // If there are coordinates, store them
        this.point = intersects[0].point;
        // Pokemon Run method
        this.pokemonRun(); }}Copy the code

This is the capture and transformation of mouse coordinates universal writing method. It’s actually using the mouse position value to convert a 3D coordinate point, to use the ray projection and it does a calculation based on the camera, which is to convert the mouse coordinate you click into a ray, and the 3D object that the ray runs through can be retrieved, and the point that runs through can also be retrieved. Since we’re only dealing with the ground, we can keep the Y-axis the same, so the little lacrimal lizard can just change the x and z coordinates.

Characters run and move

First of all, when the character is loaded, we have stored the animation and its animation mixer, and let it play waiting animation.

this.pokemon = gltf.scene;
this.animations = gltf.animations;
// ...
this.mixer = new THREE.AnimationMixer(this.pokemon);
this.mixer.clipAction(this.animations[0]).play()
// ...
Copy the code

The next step is to get him to run and move to the specified coordinates.

pokemonRun() {
    if (this.timer) this.timer.pause();
    this.mixer.stopAllAction();
    this.mixer.clipAction(this.animations[2]).play();
    this.timer = new gsap.timeline({
        defaults: {
            duration: 0}});let dx = this.pokemon.position.x - this.point.x;
    let dz = this.pokemon.position.z - this.point.z;
    let d = Math.sqrt(Math.pow(dx, 2) + Math.pow(dz, 2));
    let angle = Math.atan2(dx, dz) + Math.PI;
    this.pokemon.rotation.y = angle;
    this.timer.to(
        this.pokemon.position,
        {
            duration: d / this.speed,
            x: this.point.x,
            z: this.point.z,
            onComplete: () = > {
                this.mixer.stopAllAction();
                this.mixer.clipAction(this.animations[0]).play(); }}); }Copy the code

So what we’re going to do is stop his animation and we’re going to do 2 and that’s the running animation. And then you have to use trigonometry to figure out his direction and turn him around. It is recommended to use GSAP for the following movement. It is particularly convenient to produce displacement and transition by changing x and Z coordinates. Also, it’s worth noting that each of our Pokemon moves at a different speed and the distance assigned to it, so I calculated his time. Since we are only dealing with the plane, we calculate the distance by using the distance formula between two points, and write an initial speed for the character. The time after that is easy to calculate (i.e., time = distance/speed). Don’t forget to finish the run animation and put him on standby.

conclusion

I do not know you learned it, itself is through 2D mouse coordinate value and camera coordinate value conversion to the result, can be packaged directly to use later. And the character movement through the animation library GSAP to achieve, or very simple and practical. Have ambition to do 3DRPG game partners can through this case to join hands, a preliminary familiarity with, refueling duck ~


If you like it more than 100 times, it proves that you still like it very much. I will upload the source address of this issue (Github address, not Codepen) for you to further learn the process of completing it, so don’t control the like as much as you like it