> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/playcanvas-plugin/first-person-view.md).

# 第一人称视角

### 为飞机添加物理组件

1. 放大飞机并为其添加物理组件。添加碰撞和刚体。
2. 导入 Ammo Js（启用物理）。根据飞机大小放大碰撞组件。

<figure><img src="/files/30f92b51a4ff65b1a36cc0814f0ea6463e4da700" alt=""><figcaption><p>飞机上的物理组件</p></figcaption></figure>

### 玩家主体

1. **创建新实体**
   * 在 PlayCanvas 编辑器中，在层级面板内右键单击并选择“创建新实体”。
2. **添加物理组件**
   * 选中新实体后，点击编辑器右上角的“添加组件”按钮。
   * 搜索“Physics”，并将“Physics”组件添加到实体。
3. **添加碰撞胶囊组件**
   * 在实体仍然被选中的情况下，再次点击“添加组件”。
   * 搜索“Collision”，并将“Collision Capsule”组件添加到实体。
4. **调整实体的 Y 位置**
   * 调整 Translation 的“Y”值，将实体放置在平面上方。
5. **添加刚体组件**
   * 在实体仍然被选中的情况下，再次点击“添加组件”。
   * 搜索“Rigidbody”，并将“Rigidbody”组件添加到实体。
   * 将刚体的“Type”设置为“Dynamic”。
6. **调整角度因子**
   * 在 Rigidbody 组件中，找到“Angular Factor”部分。
   * 将 Angular Factor 的“X”、“Y”和“Z”值都设为 0。

<figure><img src="/files/27a6b7da853c5a5d8c04e265b54f71ee58a8d21d" alt=""><figcaption><p>玩家组件的物理组件</p></figcaption></figure>

### 第一人称视角的摄像机控制

创建一个 FirstPersonView\.js 脚本并添加以下代码。你可以在以下位置找到实现摄像机控制的示例 [PlayCanvas 文档](https://api.playcanvas.com/) 以及示例。将此脚本附加到 Player 胶囊体。

```javascript
var FirstPersonMovement = pc.createScript('firstPersonMovement');
var fpsCamera = null
var overChat = false
FirstPersonMovement.attributes.add('power', {
    type: 'number',
    default: 2500,
    description: '调整玩家移动速度'
});

FirstPersonMovement.attributes.add('lookSpeed', {
    type: 'number',
    default: 0.07,
    description: '调整视角灵敏度'
});
// 每个实体只调用一次的初始化代码
FirstPersonMovement.prototype.initialize = function() {
    this.force = new pc.Vec3();
    this.eulers = new pc.Vec3();

    var app = this.app;
    app.mouse.on("mousemove", this._onMouseMove, this);
    app.mouse.on("mousedown", function () { 
        if(!overChat){
            app.mouse.enablePointerLock();
        }   
    },this);
    // 检查所需组件
    if (!this.entity.collision) {
        console.error("First Person Movement 脚本需要有一个 'collision' 组件");
    }

    if (!this.entity.rigidbody || this.entity.rigidbody.type !== pc.BODYTYPE_DYNAMIC) {
        console.error("First Person Movement 脚本需要有一个 DYNAMIC 'rigidbody' 组件");
    }
};

// 每帧调用的更新代码
FirstPersonMovement.prototype.update = function(dt) {
// 如果没有从编辑器分配摄像机，则创建一个
    if (!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;

    // 移动 
    var x = 0;
    var z = 0;

    const convaiFormEl = document.getElementById("convai-input");
    // 使用 w-a-s-d
    if(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;
    }

    // 使用按键方向为角色施加力
    if (x !== 0 || z !== 0) {
        force.set(x, 0, z).normalize().scale(this.power);
        this.entity.rigidbody.applyForce(force);
    }

    // 根据鼠标事件更新摄像机角度
    this.camera.setLocalEulerAngles(this.eulers.y, this.eulers.x, 0);
};

FirstPersonMovement.prototype._onMouseMove = function (e) {
    // 如果指针被禁用
    // 如果按下鼠标左键，则根据鼠标移动更新摄像机
    if (pc.Mouse.isPointerLocked() || e.buttons[0]) {
        this.eulers.x -= this.lookSpeed * e.dx;
        this.eulers.y -= this.lookSpeed * e.dy;
    }

    const convaiChat = document.getElementById("convai-chat")
    convaiChat.addEventListener("mouseover",()=>{
    overChat = true;
    })

    convaiChat.addEventListener("mouseout",()=>{
    overChat = false;
    })
};

FirstPersonMovement.prototype._createCamera = function () {
    // 如果用户尚未分配摄像机，则创建一个新的
    this.camera = new pc.Entity();
    this.camera.setName("第一人称摄像机");
    this.camera.addComponent("camera");
    this.entity.addChild(this.camera);
    this.camera.translateLocal(0, 0.5, 0);
};
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/web-plugins/playcanvas-plugin/first-person-view.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
