Component that manages available weapons and equips them. It defines weapon metadata, initializes a list of weapon prefabs on start, allows buying/unlocking via a MetaProgression component, and spawns/attaches a prefab instance to the player model or camera when equipping.
using Sandbox;
using System;
using System.Collections.Generic;
using System.Linq;
public sealed class WeaponManager : Component
{
public static WeaponManager Instance { get; private set; }
public class WeaponData
{
public string Id { get; set; }
public string NameRu { get; set; }
public string NameEn { get; set; }
public int Cost { get; set; }
public PrefabFile Prefab { get; set; }
public bool IsUnlocked { get; set; } = false;
}
[Property] public PrefabFile UspPrefab { get; set; }
[Property] public PrefabFile Mp5Prefab { get; set; }
[Property] public PrefabFile M4A1Prefab { get; set; }
[Property] public PrefabFile M700Prefab { get; set; }
public List<WeaponData> Weapons { get; private set; } = new();
public WeaponData CurrentWeapon { get; private set; }
private GameObject _spawnedWeaponInstance;
protected override void OnStart()
{
Instance = this;
Weapons = new List<WeaponData>
{
new WeaponData { Id = "usp", NameRu = "🔫 USP", NameEn = "🔫 USP", Cost = 50, Prefab = UspPrefab },
new WeaponData { Id = "mp5", NameRu = "💥 MP5", NameEn = "💥 MP5", Cost = 120, Prefab = Mp5Prefab },
new WeaponData { Id = "m4a1", NameRu = "🔥 M4A1", NameEn = "🔥 M4A1", Cost = 250, Prefab = M4A1Prefab },
new WeaponData { Id = "m700", NameRu = "🎯 M700", NameEn = "🎯 M700", Cost = 400, Prefab = M700Prefab }
};
}
public bool TryBuyOrEquip( WeaponData weapon )
{
if ( weapon == null ) return false;
var meta = Scene.GetAllComponents<MetaProgression>().FirstOrDefault();
if ( weapon.IsUnlocked )
{
EquipWeapon( weapon );
return true;
}
if ( meta != null && meta.Credits >= weapon.Cost )
{
meta.AddCredits( -weapon.Cost );
weapon.IsUnlocked = true;
EquipWeapon( weapon );
return true;
}
return false;
}
public void EquipWeapon( WeaponData weapon )
{
if ( _spawnedWeaponInstance.IsValid() )
{
_spawnedWeaponInstance.Destroy();
}
CurrentWeapon = weapon;
if ( weapon?.Prefab == null )
{
Log.Warning( $"[WeaponManager] Префаб для {weapon?.Id} не назначен в Инспекторе!" );
return;
}
// 1. Ищем модели/персонажа
var playerModel = Scene.GetAllComponents<SkinnedModelRenderer>()
.FirstOrDefault( x => !x.IsProxy );
GameObject attachParent = null;
if ( playerModel.IsValid() )
{
attachParent = playerModel.GameObject;
}
else if ( Scene.Camera.IsValid() )
{
attachParent = Scene.Camera.GameObject;
}
if ( !attachParent.IsValid() ) return;
// 2. Создаем объект из префаба
_spawnedWeaponInstance = GameObject.Clone( weapon.Prefab );
if ( _spawnedWeaponInstance.IsValid() )
{
// Привязываем родителя (второй аргумент keepWorldPosition = false)
_spawnedWeaponInstance.SetParent( attachParent, false );
// Подгоняем локальную позицию и поворот под руку персонажа
_spawnedWeaponInstance.Transform.LocalPosition = new Vector3( 12, -8, 38 );
_spawnedWeaponInstance.Transform.LocalRotation = Rotation.From( 0, 90, 0 );
_spawnedWeaponInstance.Transform.LocalScale = Vector3.One;
Log.Info( $"[WeaponManager] Оружие {weapon.Id} успешно экипировано!" );
}
}
}