You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
4.6 KiB
165 lines
4.6 KiB
# Weapon System Documentation |
|
|
|
## Overview |
|
|
|
The weapon system is a modular, multiplayer-friendly system that allows players to: |
|
- Pick up weapons from the world |
|
- Equip weapons to their right hand (WeaponPoint bone attachment) |
|
- Drop equipped weapons |
|
- Attack with weapon-specific stats (damage, range, cooldown) |
|
|
|
## Architecture |
|
|
|
### Core Components |
|
|
|
1. **WeaponData** (`level/scripts/weapon_data.gd`) - Resource |
|
- Stores weapon stats: name, damage, attack_range, attack_cooldown |
|
- References a mesh scene for visuals |
|
- Reusable across multiple weapon instances |
|
|
|
2. **BaseWeapon** (`level/scripts/base_weapon.gd`) - Node3D |
|
- Equipped weapon attached to player's hand |
|
- Handles attack logic and damage application |
|
- Networked properly for multiplayer |
|
|
|
3. **WorldWeapon** (`level/scripts/world_weapon.gd`) - RigidBody3D |
|
- Physics-based pickup object in the world |
|
- Can be picked up by players |
|
- Automatically creates collision and pickup area |
|
|
|
## Creating New Weapons |
|
|
|
### Step 1: Create a Mesh Scene |
|
|
|
Create a scene with your weapon's 3D model: |
|
``` |
|
[Node3D] - WeaponMesh |
|
└─ [MeshInstance3D] - Your mesh here |
|
``` |
|
|
|
Example: `level/scenes/weapons/sword_mesh.tscn` |
|
|
|
### Step 2: Create a WeaponData Resource |
|
|
|
Create a `.tres` file in `level/resources/`: |
|
|
|
```tres |
|
[gd_resource type="Resource" script_class="WeaponData" load_steps=3 format=3] |
|
|
|
[ext_resource type="Script" path="res://level/scripts/weapon_data.gd" id="1"] |
|
[ext_resource type="PackedScene" path="res://level/scenes/weapons/your_mesh.tscn" id="2"] |
|
|
|
[resource] |
|
script = ExtResource("1") |
|
weapon_name = "Your Weapon Name" |
|
description = "Weapon description" |
|
damage = 15.0 |
|
attack_range = 3.5 |
|
attack_cooldown = 0.6 |
|
attack_animation = "Attack1" |
|
mesh_scene = ExtResource("2") |
|
pickup_radius = 1.5 |
|
weight = 2.0 |
|
``` |
|
|
|
### Step 3: Create a WorldWeapon Scene (Optional) |
|
|
|
If you want to place weapons in the level: |
|
|
|
``` |
|
[RigidBody3D] - WorldWeaponYourWeapon |
|
└─ [CollisionShape3D] - Approximate weapon shape |
|
``` |
|
|
|
Set the script to `world_weapon.gd` and assign your WeaponData resource. |
|
|
|
Example: `level/scenes/weapons/world_weapon_sword.tscn` |
|
|
|
## Testing |
|
|
|
### In Godot Editor |
|
|
|
1. Open `level/scenes/level.tscn` |
|
2. Drag a WorldWeapon scene (e.g., `world_weapon_sword.tscn`) into the level |
|
3. Position it somewhere visible |
|
4. Run the game (F5) |
|
|
|
### Controls |
|
|
|
- **E** - Pick up weapon (when near one) or drop equipped weapon |
|
- **Left Mouse** - Attack with equipped weapon (or unarmed if none) |
|
|
|
### Multiplayer Testing |
|
|
|
1. Run the game and click "Host" |
|
2. Run another instance and click "Join" |
|
3. Both players can: |
|
- Pick up weapons |
|
- Attack each other with weapons |
|
- Drop weapons (creates a WorldWeapon others can pick up) |
|
|
|
## How It Works |
|
|
|
### Pickup Flow |
|
|
|
1. WorldWeapon creates an Area3D with pickup radius |
|
2. Player has a WeaponPickupArea that detects nearby WorldWeapons |
|
3. When player presses "E" near a weapon: |
|
- Client calls `try_pickup()` via RPC to server |
|
- Server validates distance and availability |
|
- Server tells player to `equip_weapon_from_world()` |
|
- Server removes the WorldWeapon from scene |
|
- All clients see the weapon disappear and equipped on player |
|
|
|
### Attack Flow |
|
|
|
1. Player presses attack button |
|
2. Player checks if `equipped_weapon` exists |
|
3. If yes, calls `equipped_weapon.perform_attack()` |
|
4. Weapon checks cooldown and attack range |
|
5. Weapon finds targets using physics query |
|
6. Weapon sends damage request to server |
|
7. Server validates and applies damage via BaseUnit system |
|
|
|
### Drop Flow |
|
|
|
1. Player presses "E" while holding a weapon |
|
2. Player calls `drop_weapon()` RPC |
|
3. Server spawns a WorldWeapon at player's position |
|
4. All clients see weapon unequip and appear in world |
|
5. Weapon becomes a physics object that can be picked up |
|
|
|
## Physics Layers |
|
|
|
- **Layer 1** (player) - Player collisions |
|
- **Layer 2** (world) - Environment collisions |
|
- **Layer 3** (weapon) - Weapon pickup objects |
|
|
|
WorldWeapons: |
|
- `collision_layer = 4` (layer 3) |
|
- `collision_mask = 2` (collides with world) |
|
|
|
Player WeaponPickupArea: |
|
- `collision_mask = 4` (detects layer 3) |
|
|
|
## Example Weapons |
|
|
|
### Iron Sword |
|
- **Damage**: 15 |
|
- **Range**: 3.5m |
|
- **Cooldown**: 0.6s |
|
- **Resource**: `level/resources/weapon_sword.tres` |
|
|
|
### Wooden Shield |
|
- **Damage**: 8 |
|
- **Range**: 2.5m |
|
- **Cooldown**: 0.8s |
|
- **Resource**: `level/resources/weapon_shield.tres` |
|
|
|
## Notes |
|
|
|
- All weapon spawning/pickup is server-authoritative |
|
- Weapon stats are synced via WeaponData resource |
|
- Meshes are instantiated locally on each client |
|
- The system supports any number of weapon types |
|
- You can extend BaseWeapon for special weapon behaviors (e.g., ranged weapons, magic weapons)
|
|
|