[Unity] Claude3にローグライクを作らせようとした話。#2
今回は以前の続きからClaude3にローグライクに必須の
状態異常、インベントリ、スキル、魔法攻撃、アイテムデータ、さらにショップ機能や実績機能のコードを書かせてみようと思います。
以前の記事では、Claude3がターン制バトルや敵のAIなどのコードを書いてくれました。(コードが動くかは別問題)
今回はローグライクゲームの醍醐味である
状態異常や魔法などの特殊攻撃、階層の生成
さらには、インベントリや実績 ショップ
などを作ってもらいます!
以前の記事で、Claude3に具体的なローグライクの開発手順やゲームシステムを資料として入れてるので、こんな感じの質問でも分かってくれるはず!
さあ続きを書いてくれ!
(相変わらずこの質問の日本語が変だな)
おお!すごい!
さぁスクリプトを見せてくれ!
はい、作成したスクリプトやファイルの具体的な内容を記述します。
**DataManager.cs**
```csharp
using UnityEngine;
public class DataManager : MonoBehaviour
{
public TextAsset characterStatsData;
public TextAsset messageData;
private void Start()
{
LoadData();
}
private void LoadData()
{
// Load character stats data from JSON
CharacterStats[] stats = JsonUtility.FromJson<CharacterStats[]>(characterStatsData.text);
// Load message data from JSON
MessageData[] messages = JsonUtility.FromJson<MessageData[]>(messageData.text);
// Process loaded data
ProcessCharacterStats(stats);
ProcessMessageData(messages);
}
private void ProcessCharacterStats(CharacterStats[] stats)
{
// Assign loaded stats to characters in the game
}
private void ProcessMessageData(MessageData[] messages)
{
// Assign loaded messages to message manager
}
}
```
**CharacterStats.json**
```json
[
{
"name": "Player",
"maxHealth": 100,
"attack": 10,
"defense": 5
},
{
"name": "Goblin",
"maxHealth": 50,
"attack": 8,
"defense": 3
}
]
```
**MessageData.json**
```json
[
{
"id": 1,
"message": "You found a healing potion."
},
{
"id": 2,
"message": "The goblin attacks you!"
}
]
```
**ItemManager.cs**
```csharp
using UnityEngine;
public class ItemManager : MonoBehaviour
{
public TextAsset itemData;
private void Start()
{
LoadItemData();
}
private void LoadItemData()
{
// Load item data from JSON
ItemData[] items = JsonUtility.FromJson<ItemData[]>(itemData.text);
// Process loaded item data
ProcessItemData(items);
}
private void ProcessItemData(ItemData[] items)
{
// Instantiate item prefabs based on loaded data
foreach (ItemData item in items)
{
GameObject itemObj = Instantiate(Resources.Load<GameObject>($"Prefabs/Items/{item.prefabName}"), item.position, Quaternion.identity);
itemObj.GetComponent<ItemProperties>().SetProperties(item);
}
}
}
```
**ItemData.json**
```json
[
{
"name": "Healing Potion",
"prefabName": "HealingPotion",
"healAmount": 20,
"position": {
"x": 2,
"y": 3,
"z": 0
}
},
{
"name": "Sword",
"prefabName": "Weapon",
"attackBonus": 5,
"position": {
"x": 5,
"y": 1,
"z": 0
}
}
]
```
**InventoryManager.cs**
```csharp
using UnityEngine;
using UnityEngine.UI;
public class InventoryManager : MonoBehaviour
{
public GameObject slotPrefab;
public Transform slotsParent;
private ItemProperties[] inventoryItems = new ItemProperties[8];
private GameObject[] slotObjects = new GameObject[8];
private void Start()
{
CreateSlots();
}
private void CreateSlots()
{
for (int i = 0; i < inventoryItems.Length; i++)
{
GameObject slotObj = Instantiate(slotPrefab, slotsParent);
slotObjects[i] = slotObj;
slotObj.GetComponent<Image>().sprite = null;
}
}
public void AddItem(ItemProperties item)
{
for (int i = 0; i < inventoryItems.Length; i++)
{
if (inventoryItems[i] == null)
{
inventoryItems[i] = item;
slotObjects[i].GetComponent<Image>().sprite = item.sprite;
return;
}
}
}
}
```
**MagicEffectManager.cs**
```csharp
using UnityEngine;
public class MagicEffectManager : MonoBehaviour
{
public TextAsset magicData;
private void Start()
{
LoadMagicData();
}
private void LoadMagicData()
{
// Load magic data from JSON
MagicData[] magicEffects = JsonUtility.FromJson<MagicData[]>(magicData.text);
// Process loaded magic data
ProcessMagicData(magicEffects);
}
private void ProcessMagicData(MagicData[] magicEffects)
{
// Assign magic effects to appropriate game objects or systems
}
}
```
**MagicData.json**
```json
[
{
"name": "Fireball",
"damage": 30,
"range": 5
},
{
"name": "Heal",
"healAmount": 50,
"targetSelf": true
}
]
```
**StatusEffects.cs**
```csharp
public enum StatusEffectType
{
None,
Poison,
Stun,
Burn
}
```
**StatusEffectManager.cs**
```csharp
using UnityEngine;
public class StatusEffectManager : MonoBehaviour
{
public void ApplyStatusEffect(StatusEffectType effect, CharacterStats target, int duration)
{
switch (effect)
{
case StatusEffectType.Poison:
ApplyPoisonEffect(target, duration);
break;
case StatusEffectType.Stun:
ApplyStunEffect(target, duration);
break;
case StatusEffectType.Burn:
ApplyBurnEffect(target, duration);
break;
}
}
private void ApplyPoisonEffect(CharacterStats target, int duration)
{
// Apply poison effect to target for specified duration
}
private void ApplyStunEffect(CharacterStats target, int duration)
{
// Apply stun effect to target for specified duration
}
private void ApplyBurnEffect(CharacterStats target, int duration)
{
// Apply burn effect to target for specified duration
}
}
```
**DungeonGenerator.cs**
```csharp
using UnityEngine;
using UnityEngine.Tilemaps;
public class DungeonGenerator : MonoBehaviour
{
public Tilemap dungeon;
public Tile floorTile;
public Tile wallTile;
private void Start()
{
GenerateDungeon();
}
private void GenerateDungeon()
{
// Generate a random dungeon layout using procedural generation algorithms
for (int y = 0; y < 20; y++)
{
for (int x = 0; x < 20; x++)
{
Tile tile = Random.value < 0.3f ? wallTile : floorTile;
dungeon.SetTile(new Vector3Int(x, y, 0), tile);
}
}
}
}
```
**LevelManager.cs**
```csharp
using UnityEngine;
public class LevelManager : MonoBehaviour
{
public int currentLevel = 1;
public Transform playerSpawnPoint;
private void Start()
{
SpawnPlayer();
}
private void SpawnPlayer()
{
Instantiate(Resources.Load<GameObject>("Prefabs/Player"), playerSpawnPoint.position, Quaternion.identity);
}
public void LoadNextLevel()
{
currentLevel++;
// Load next level dungeon layout
あれ?なんか途中で止まったな。
一度に生成できる文字数の限界がきたのかな?
続きを書いてくれ!
using UnityEngine;
using UnityEngine.SceneManagement;
public class LevelManager : MonoBehaviour
{
public int currentLevel = 1;
public Transform playerSpawnPoint;
private void Start()
{
SpawnPlayer();
}
private void SpawnPlayer()
{
Instantiate(Resources.Load<GameObject>("Prefabs/Player"), playerSpawnPoint.position, Quaternion.identity);
}
public void LoadNextLevel()
{
currentLevel++;
// Unload current level
SceneManager.UnloadSceneAsync(SceneManager.GetActiveScene());
// Load next level
SceneManager.LoadSceneAsync($"Level{currentLevel}", LoadSceneMode.Additive);
}
public void ReloadCurrentLevel()
{
// Unload current level
SceneManager.UnloadSceneAsync(SceneManager.GetActiveScene());
// Reload current level
SceneManager.LoadSceneAsync($"Level{currentLevel}", LoadSceneMode.Additive);
}
private void OnLevelCompleted()
{
// Level completed logic, such as spawning stairs or opening the exit
// ...
// Spawn stairs or exit prefab
GameObject stairsPrefab = Resources.Load<GameObject>("Prefabs/Stairs");
Instantiate(stairsPrefab, playerSpawnPoint.position, Quaternion.identity);
}
}
相変わらずたまに不自然なコードがあるけど
まぁパッと見た感じは良さそうなだな!(適当)
さあ続きを書いてくれ!
え?なんか赤文字で変な文章出てきた!
助けてGoogle翻訳!
なるほど、つまりチャットの長さに制限があったのかな?
まぁ新しいチャットでもう一度始めてみるか。
でも前の続きから書かせるためにはどうすれば良いんだ?
とりあえずこのチャットログを全部コピーして、
新しいチャットのはじめに資料として貼り付けるか。
(やってる事は、ただ1番上から1番下までチャットをコピーして、新しいチャットの1番初めに貼り付けてるだけ)
さぁ前のチャットの引き続きはできるのか?
```csharp
using UnityEngine;
public class ExperienceManager : MonoBehaviour
{
public int currentExperience;
public int experienceToNextLevel = 100;
public int playerLevel = 1;
private CharacterStats playerStats;
private void Start()
{
playerStats = GameObject.FindGameObjectWithTag("Player").GetComponent<CharacterStats>();
}
public void GainExperience(int experience)
{
currentExperience += experience;
CheckForLevelUp();
}
private void CheckForLevelUp()
{
if (currentExperience >= experienceToNextLevel)
{
LevelUp();
}
}
private void LevelUp()
{
playerLevel++;
currentExperience -= experienceToNextLevel;
experienceToNextLevel = Mathf.Max(experienceToNextLevel + 50, experienceToNextLevel * 1.2f);
playerStats.maxHealth += 10;
playerStats.attack += 2;
playerStats.defense += 1;
// Display level up message
MessageManager.Instance.AddMessage($"You leveled up to level {playerLevel}!");
}
}
```
SkillManager.csでは、プレイヤーの特殊攻撃やスキルを管理します。スキルのデータはJSONファイルから読み込むことができます。
```csharp
using UnityEngine;
public class SkillManager : MonoBehaviour
{
public TextAsset skillData;
private SkillData[] playerSkills;
private void Start()
{
LoadSkillData();
}
private void LoadSkillData()
{
playerSkills = JsonUtility.FromJson<SkillData[]>(skillData.text);
}
public void UseSkill(int skillIndex, CharacterStats targetStats)
{
SkillData skill = playerSkills[skillIndex];
switch (skill.skillType)
{
case SkillType.Damage:
DamageTarget(targetStats, skill.damageAmount);
break;
case SkillType.Heal:
HealTarget(targetStats, skill.healAmount);
break;
// Add more skill types as needed
}
}
private void DamageTarget(CharacterStats targetStats, int damageAmount)
{
targetStats.currentHealth -= damageAmount;
// Display damage message
}
private void HealTarget(CharacterStats targetStats, int healAmount)
{
targetStats.currentHealth = Mathf.Min(targetStats.currentHealth + healAmount, targetStats.maxHealth);
// Display heal message
}
}
```
続いて、Step 14に移ります。
なんかスゲェ!(語彙力ゼロ)
まぁコードはちゃんと合っていそうかな?(適当)
雑になる質問
それでもちゃんと答えてくれるClaude3。
```csharp
using UnityEngine;
public class ShopManager : MonoBehaviour
{
public ItemData[] stockedItems;
private InventoryManager playerInventory;
private void Start()
{
playerInventory = GameObject.FindGameObjectWithTag("Player").GetComponent<InventoryManager>();
}
public void BuyItem(int itemIndex)
{
ItemData itemToBuy = stockedItems[itemIndex];
if (playerInventory.CanAddItem(itemToBuy.item))
{
playerInventory.AddItem(itemToBuy.item);
// Deduct gold from player
}
else
{
// Display "Inventory full" message
}
}
public void SellItem(ItemProperties itemToSell)
{
playerInventory.RemoveItem(itemToSell);
// Add gold to player
}
}
```
QuestManager.csでは、クエストの管理を行います。クエストの目標や報酬などのデータは外部ファイルから読み込むことができます。
```csharp
using UnityEngine;
public class QuestManager : MonoBehaviour
{
public TextAsset questData;
private QuestData[] quests;
private void Start()
{
LoadQuestData();
}
private void LoadQuestData()
{
quests = JsonUtility.FromJson<QuestData[]>(questData.text);
}
public void StartQuest(int questIndex)
{
QuestData quest = quests[questIndex];
// Display quest objectives
// Register quest callbacks
}
public void CompleteQuest(int questIndex)
{
QuestData quest = quests[questIndex];
// Grant quest rewards
// Display completion message
}
}
```
AchievementManager.csでは、実績の管理を行います。実績の条件と報酬などのデータは外部ファイルから読み込むことができます。
```csharp
using UnityEngine;
public class AchievementManager : MonoBehaviour
{
public TextAsset achievementData;
private AchievementData[] achievements;
private void Start()
{
LoadAchievementData();
}
private void LoadAchievementData()
{
achievements = JsonUtility.FromJson<AchievementData[]>(achievementData.text);
}
public void UnlockAchievement(int achievementIndex)
{
AchievementData achievement = achievements[achievementIndex];
// Grant achievement rewards
// Display unlock message
}
}
```
StatisticsManager.csでは、プレイヤーの統計データを記録します。
```csharp
using UnityEngine;
public class StatisticsManager : MonoBehaviour
{
public float totalPlayTime;
public int enemiesKilled;
public int bosseDefeated;
private void Update()
{
totalPlayTime += Time.deltaTime;
}
public void RegisterEnemyKill(EnemyType enemyType)
{
enemiesKilled++;
if (enemyType == EnemyType.Boss)
{
bossesDefeated++;
}
}
}
```
これらの機能を実装することで、ゲームにさらなる深みと楽しさが加わります。プレイヤーの満足度が高まり、長時間楽しめるゲームになるでしょう。
おお!とうとう実績機能が来た!
どのゲームでもあると嬉しいシステムの実績機能とかショップ機能とかだ!
こういう機能をUnityで作ろうと思っても、あまり情報が無いので良いよね!(コードが動くかは別問題)
まぁひとまず、これでローグライクの大体の機能をClaude3に作らせることが出来ました!
しかし問題はこのコードが実際にUnityで動くのか?
という事です。(多分動かない)
まぁいつかこれらのコードをUnityで実際に動くか検証して記事にしようと思います。
では今回はここまで!
この記事を見た人にオススメの記事
この記事が気に入ったらサポートをしてみませんか?