First Person View - PlayCanvas Plugin Guide for Convai integration.
Adding Physics components to plane
Scale up the plane and add physics component to it. Add both collision and rigidbody.
Import Ammo Js (enables physics). Scale up the Collision component according to the plane size.
Player Body
Create a New Entity
In the PlayCanvas Editor, right-click in the Hierarchy panel and select "Create New Entity".
Add Physics Component
With the new entity selected, click the "Add Component" button in the top-right corner of the Editor.
Search for "Physics" and add the "Physics" component to the entity.
Add Collision Capsule Component
With the entity still selected, click "Add Component" again.
Search for "Collision" and add the "Collision Capsule" component to the entity.
Adjust Entity Y-Position
Adjust the "Y" value of the Translation to position the entity above the plane.
Add Rigidbody Component
With the entity still selected, click "Add Component" again.
Search for "Rigidbody" and add the "Rigidbody" component to the entity.
Set the "Type" of the rigidbody to "Dynamic".
Adjust Angular Factors
In the Rigidbody component, locate the "Angular Factor" section.
Set the "X", "Y", and "Z" values of the Angular Factor to 0.
Camera controls for first person view
Create a FirstPersonView.js script and add the bellow code. You can find examples for implementing camera controls on PlayCanvas documentation and examples as well. Attach this script to Player capsule.
var FirstPersonMovement =pc.createScript('firstPersonMovement');var fpsCamera =nullvar overChat =falseFirstPersonMovement.attributes.add('power', { type:'number', default:2500, description:'Adjusts the speed of player movement'});FirstPersonMovement.attributes.add('lookSpeed', { type:'number', default:0.07, description:'Adjusts the sensitivity of looking'});// initialize code called once per entityFirstPersonMovement.prototype.initialize=function() {this.force =newpc.Vec3();this.eulers =newpc.Vec3();var app =this.app;app.mouse.on("mousemove",this._onMouseMove,this);app.mouse.on("mousedown",function () { if(!overChat){app.mouse.enablePointerLock(); } },this);// Check for required componentsif (!this.entity.collision) {console.error("First Person Movement script needs to have a 'collision' component"); }if (!this.entity.rigidbody ||this.entity.rigidbody.type !==pc.BODYTYPE_DYNAMIC) {console.error("First Person Movement script needs to have a DYNAMIC 'rigidbody' component"); }};// update code called every frameFirstPersonMovement.prototype.update=function(dt) {// If a camera isn't assigned from the Editor, create oneif (!this.camera) {this._createCamera(); }var force =this.force;var app =this.app; fpsCamera =this.camera;var forward =this.camera.forward;var right =this.camera.right;// movement var x =0;var z =0;constconvaiFormEl=document.getElementById("convai-input");// use w-a-s-dif(app.keyboard.isPressed(pc.KEY_A) &&!(document.activeElement === convaiFormEl)){ x -=right.x; z -=right.z; }if (app.keyboard.isPressed(pc.KEY_D) &&!(document.activeElement === convaiFormEl)) { x +=right.x; z +=right.z; }if (app.keyboard.isPressed(pc.KEY_W) &&!(document.activeElement === convaiFormEl)) { x +=forward.x; z +=forward.z; }if (app.keyboard.isPressed(pc.KEY_S) &&!(document.activeElement === convaiFormEl)) { x -=forward.x; z -=forward.z; }// use direction from keypresses to apply a force to the characterif (x !==0|| z !==0) {force.set(x,0, z).normalize().scale(this.power);this.entity.rigidbody.applyForce(force); }// update camera angle from mouse eventsthis.camera.setLocalEulerAngles(this.eulers.y,this.eulers.x,0);};FirstPersonMovement.prototype._onMouseMove=function (e) {// If pointer is disabled// If the left mouse button is down update the camera from mouse movementif (pc.Mouse.isPointerLocked() ||e.buttons[0]) {this.eulers.x -=this.lookSpeed *e.dx;this.eulers.y -=this.lookSpeed *e.dy; }constconvaiChat=document.getElementById("convai-chat")convaiChat.addEventListener("mouseover",()=>{ overChat =true; })convaiChat.addEventListener("mouseout",()=>{ overChat =false; })};FirstPersonMovement.prototype._createCamera=function () {// If user hasn't assigned a camera, create a new onethis.camera =newpc.Entity();this.camera.setName("First Person Camera");this.camera.addComponent("camera");this.entity.addChild(this.camera);this.camera.translateLocal(0,0.5,0);};