← Назад к вопросам
Реализовать систему прокачки персонажа
2.0 Middle🔥 241 комментариев
#C# и ООП#UI#Коллекции и структуры данных#Паттерны проектирования
Условие
Реализуйте систему уровней и прокачки персонажа.
Требования
- Получение опыта за действия
- Кривая опыта для уровней
- Очки навыков при повышении уровня
- Дерево навыков
- Сохранение прогресса
- UI отображение
Статы
- Сила, ловкость, интеллект
- Здоровье, мана
- Урон, защита
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Система прокачки и уровней персонажа
Реализую полнофункциональную систему развития персонажа с опытом, уровнями, деревом навыков, прокачкой статов и сохранением прогресса. Используется ScriptableObject конфиги и JSON сериализация.
Модель персонажа и опыта
[System.Serializable]
public class CharacterStats
{
public int strength = 10; // Сила - увеличивает урон и здоровье
public int agility = 10; // Ловкость - увеличивает защиту и скорость
public int intelligence = 10; // Интеллект - увеличивает ману и урон магии
public int maxHealth;
public int currentHealth;
public int maxMana;
public int currentMana;
public float armor; // Защита
public float physicalDamage; // Урон
public void RecalculateStats()
{
maxHealth = 100 + strength * 5;
maxMana = 50 + intelligence * 3;
armor = agility * 0.5f;
physicalDamage = 10f + strength * 1.5f;
}
}
public class ExperienceConfig : ScriptableObject
{
[SerializeField] private List<int> experiencePerLevel; // Кривая опыта
[SerializeField] private int skillPointsPerLevel = 5;
public int GetExperienceForLevel(int level)
{
if (level < 0 || level >= experiencePerLevel.Count)
return 0;
return experiencePerLevel[level];
}
public int SkillPointsPerLevel => skillPointsPerLevel;
}
Система уровней с отслеживанием опыта
public class LevelingSystem : MonoBehaviour
{
[SerializeField] private ExperienceConfig expConfig;
[SerializeField] private CharacterStats stats;
private int currentLevel = 1;
private int currentExperience = 0;
private int skillPoints = 0;
public int CurrentLevel => currentLevel;
public int CurrentExperience => currentExperience;
public int ExperienceForNextLevel => expConfig.GetExperienceForLevel(currentLevel);
public float LevelProgress => (float)currentExperience / ExperienceForNextLevel;
public int SkillPoints => skillPoints;
public void GainExperience(int amount)
{
currentExperience += amount;
OnExperienceGained?.Invoke(amount, currentExperience);
while (currentExperience >= ExperienceForNextLevel)
{
LevelUp();
}
}
private void LevelUp()
{
currentExperience -= ExperienceForNextLevel;
currentLevel++;
skillPoints += expConfig.SkillPointsPerLevel;
stats.RecalculateStats();
OnLevelUp?.Invoke(currentLevel, expConfig.SkillPointsPerLevel);
}
public bool TrySpendSkillPoint(string statName)
{
if (skillPoints <= 0)
return false;
skillPoints--;
IncreaseStat(statName);
OnSkillPointSpent?.Invoke(skillPoints);
return true;
}
private void IncreaseStat(string statName)
{
switch (statName.ToLower())
{
case "strength":
stats.strength++;
break;
case "agility":
stats.agility++;
break;
case "intelligence":
stats.intelligence++;
break;
}
stats.RecalculateStats();
}
public event System.Action<int, int> OnExperienceGained;
public event System.Action<int, int> OnLevelUp;
public event System.Action<int> OnSkillPointSpent;
}
Дерево навыков (Skill Tree)
[System.Serializable]
public class SkillNode
{
public string skillId;
public string skillName;
public string description;
public int requiredLevel;
public int skillPointCost = 1;
public List<string> prerequisiteSkills;
public Sprite icon;
public bool isUnlocked;
[NonSerialized]
public List<SkillNode> children = new();
}
public class SkillTreeSystem : MonoBehaviour
{
[SerializeField] private List<SkillNode> rootSkills;
[SerializeField] private Dictionary<string, SkillNode> skillNodeMap;
[SerializeField] private LevelingSystem levelingSystem;
private Dictionary<string, bool> unlockedSkills = new();
public bool TryUnlockSkill(string skillId)
{
if (!skillNodeMap.TryGetValue(skillId, out var skill))
return false;
if (levelingSystem.CurrentLevel < skill.requiredLevel)
return false;
if (levelingSystem.SkillPoints < skill.skillPointCost)
return false;
foreach (var prereq in skill.prerequisiteSkills)
{
if (!unlockedSkills.ContainsKey(prereq) || !unlockedSkills[prereq])
return false;
}
unlockedSkills[skillId] = true;
skill.isUnlocked = true;
OnSkillUnlocked?.Invoke(skill);
return true;
}
public event System.Action<SkillNode> OnSkillUnlocked;
}
Система сохранения (JSON)
[System.Serializable]
public class CharacterSaveData
{
public int currentLevel;
public int currentExperience;
public int skillPoints;
public CharacterStats stats;
public Dictionary<string, bool> unlockedSkills;
public string lastSaveTime;
}
public class SaveSystem : MonoBehaviour
{
[SerializeField] private string saveFilePath = "Saves/character.json";
public void SaveCharacter(CharacterStats stats, int level, int exp, int skillPoints)
{
var saveData = new CharacterSaveData
{
currentLevel = level,
currentExperience = exp,
skillPoints = skillPoints,
stats = stats,
lastSaveTime = System.DateTime.Now.ToString()
};
string json = JsonUtility.ToJson(saveData, true);
System.IO.File.WriteAllText(saveFilePath, json);
}
public CharacterSaveData LoadCharacter()
{
if (!System.IO.File.Exists(saveFilePath))
return null;
string json = System.IO.File.ReadAllText(saveFilePath);
return JsonUtility.FromJson<CharacterSaveData>(json);
}
}
Преимущества решения
- Экспоненциальная кривая опыта для реалистичного прогресса
- Дерево навыков с предусловиями и зависимостями
- Динамический расчёт статов при прокачке
- JSON сериализация для сохранения прогресса
- Event система для слабой связанности компонентов
- Модульная архитектура для расширяемости