three.jspointerlock

Difficulty incorporating pointer lock controls API in three.js using es6 classes that are not modules


As the title states, I am using es6 classes, but because they are all not modules apart from the main.js file, it makes it difficult to use API's because I cannot make use of import modules.

I used the code from this link's answer: How to add in Three.js PointerLockControl? and pasted the code into a js file, calling it up in my HTML, but I get an error stating:

Uncaught ReferenceError: PointerLockControls is not defined

It is not picking up the class when I reference it. I tried to link it to the GitHub raw code, and it didn't pick it up either.

This is my index.html code (only one line referencing the GitHub raw code):

<!-- This html file is what the browser shows when we run index.js on port 5000. Therefore our display of our game-->
<!DOCTYPE html>
<html>
    <head>
        <title>Aftermath</title>

        <!-- SCRIPTS-->
        <!--Loads three.js into our game-->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.js"> </script>
        <!--Loads orbit controls around player-->
        <script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>
        <!--Loads gltf files (our blender files)-->
        <script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/loaders/GLTFLoader.js"></script>
        <!--Pointer lock controls-->
        <script src="https://github.com/mrdoob/three.js/blob/dev/examples/js/controls/PointerLockControls.js"></script>
       


        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body { margin: 0; height: 100%; width: 100%; overflow: hidden}
        </style>

      </head>

    <body>
        <canvas id="canvas"></canvas>
        <!--MOVEMENT-->
        <script src="./important/THREEx.KeyboardState.js" ></script>
        <script src="./important/FirstPersonControls.js" ></script>
        <script src="./js/CharacterControls.js" ></script>
        <!--========================================-->


        <!--Lighting models-->
        <script src="./js/sceneSubjects/lighting/GeneralLights.js" ></script>

        <!--add models to scene-->
        <!--Subject (model) scripts-->

        <!--This is our main blender house-->
        <script src="./js/sceneSubjects/House.js" ></script>
        <!--Our character model file (not complete due to loading issues with fbx)-->
        <script src="./js/sceneSubjects/characters/MainChar.js"  ></script>

        <!--Just a demo for you to see how this works-->
        <script src="./js/sceneSubjects/objects/SceneSubject.js" ></script>

        <!--Block to test raycasting -->
        <script src="./js/sceneSubjects/characters/TestBlock.js" ></script>


        <!--MANAGERS-->
        <!--Load the scene manager-->
        <script src="./js/EntityManager.js" ></script>
       <script src="./js/SceneManager.js" ></script>
            <script src = "./js/Time.js" ></script>
        <!--Load our main.js function-->
        <script type="module" src="./js/main2.js"></script>
    </body>
</html>

This is my Scene Manager, which controls the whole scene. I just tested the initialization, which failed:

//Global Variables
var generalLights = new GeneralLights();
var house = new House();
var sceneSubject = new SceneSubject();
var testBlock = new TestBlock();
var mainChar = new MainChar(testBlock);

class SceneManager {

    constructor(canvas) {
        //this entire function renders a scene where you can add as many items as you want to it (e.g. we can create the house and add as
        //many items as we want to the house). It renders objects from other JavaScript files
        //------------------------------------------------------------------------------------------------------------------------------------------
        //These are supposed to act like constants. DO NOT CHANGE
        this.GAME_PAUSE = "pause";
        this.GAME_RUN = "run";
        //------------------------------------------------------------------------------------------------------------------------------------------

        //we use (this) to make variables accessible in other classes
        this.time = new Time();



        this.game_state = this.GAME_RUN;


        this.screenDimensions = {
            width: canvas.width,
            height: canvas.height
        };

        //the essentials for rendering a scene
        this.scene = this.buildScene();
        this.renderer = this.buildRender(this.screenDimensions);
        this.camera = this.buildCamera(this.screenDimensions);
        controls = new PointerLockControls( this.camera, document.body );
       // this.scene.add(controls.getObject());
        this.managers = this.createManagers();
        this.loadToScene(this.managers[0].entities);


        //Allow camera to orbit target (player) - OrbitPlayer Controls

        //this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
        //this.controls.target.set(0, 20, 0);
        //this.controls.update();



    }

    loadToScene(entities)
    {
        for (let i = 0 ; i < entities.length ; i++)
        {
            console.log("before" +i.toString());
            this.scene.add(entities[i].object);
            console.log("after");
        }
    }
        //this function creates our scene
        buildScene() {
            //create a new scene
            const scene = new THREE.Scene();

            //set the scene's background-> in this case it is our skybox
            const loader = new THREE.CubeTextureLoader();
            //it uses different textures per face of cube
            const texture = loader.load([
                '../skybox/House/posx.jpg',
                '../skybox/House/negx.jpg',
                '../skybox/House/posy.jpg',
                '../skybox/House/negy.jpg',
                '../skybox/House/posz.jpg',
                '../skybox/House/negz.jpg'
            ]);
            scene.background = texture;

            //if we wanted it to be a color, it would have been this commented code:
            //scene.background = new THREE.Color("#000");
            return scene;
        }

        //this creates a renderer for us
        buildRender({ width, height }) {

            const renderer = new THREE.WebGLRenderer({
                canvas: canvas,
                antialias: true, alpha: true
            });
            renderer.shadowMap.enabled = true;
            renderer.shadowMap.type = THREE.PCFSoftShadowMap;
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);

            return renderer;
        }

        //create a camera for the screen
        buildCamera({ width, height }) {

            //SETTING FIELD OF VIEW, ASPECT RATIO (which should generally be width/ height), NEAR AND FAR (anything outside near/ far is clipped)
            const aspectRatio = width / height;
            const fieldOfView = 60;
            const nearPlane = 1;
            const farPlane = 1000;

            //there are 2 types of cameras: orthographic and perspective- we will use perspective (more realistic)
            const camera = new THREE.PerspectiveCamera(fieldOfView, aspectRatio, nearPlane, farPlane);
            //Set camera initial position to main character
            let pos = mainChar.returnWorldPosition();
            camera.position.set(pos.x,pos.y,pos.z);

            return camera;
        }

        //add subjects to the scene
        createManagers() {

            const managers=[new EntityManager()];
            //can be altered so we can add multiple entities, and depending on which position
            //it is, certain ones won't be paused, and some will be

            //Note that these variables are declared globally before the class definition
            /*This is so that we can use any of these object's methods or values later somewhere else*/
            managers[0].register(generalLights);
            managers[0].register(house);
            managers[0].register(mainChar);
            managers[0].register(sceneSubject);
            managers[0].register(testBlock);

            return managers;
        }

        updateCameraPosition() {
          //Match camera position and direction to the character's position and direction
            let pos = mainChar.returnWorldPosition();
            let dir = mainChar.returnObjectDirection();
            //Set y to 10 to move camera closer to head-height
            this.camera.position.set(pos.x,10,pos.z);
            this.camera.rotation.set(dir.x,dir.y,dir.z);
        }

        //this updates the subject/model every frame
        update() {

            //won't call this loop if it's paused-> only for objects that need to be paused (managers that need to be paused)
            if (this.game_state == this.GAME_RUN)
            {
                const runTime = this.time.getRunTime();
                this.managers[0].update(runTime);
            }

            //update orbit controls
            //this.controls.update();


            this.updateCameraPosition();


            this.renderer.render(this.scene, this.camera);
        }

        //this resizes our game when screen size changed
        onWindowResize() {

            this.camera.aspect = window.innerWidth / window.innerHeight;
            this.camera.updateProjectionMatrix();

            this.renderer.setSize(window.innerWidth, window.innerHeight);

        }

        pause(){ //when pause mode is entered. The pause menu needs to be rendered.
            this.game_state = this.GAME_PAUSE;
            this.time.pause();

        }

        unpause(){
            this.game_state = this.GAME_RUN;
            this.time.unpause();

        }

}

Solution

  • I changed all my es6 classes into es6 modules, and used import. I don't think there was a solution for this with cdn or raw git scripts.