added inventory and stamina system
This commit is contained in:
100
Assets/Scripts/Editor/BhopBootsSetup.cs
Normal file
100
Assets/Scripts/Editor/BhopBootsSetup.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
|
||||
/// <summary>
|
||||
/// OGG → Setup → Create Bunny Hop Boots
|
||||
/// Creates the ItemDefinition and a world pickup for the bhop boots.
|
||||
/// </summary>
|
||||
public static class BhopBootsSetup
|
||||
{
|
||||
private const string ITEM_DEF_PATH = "Assets/Items/BhopBoots_Item.asset";
|
||||
private const string PICKUP_PREFAB = "Assets/Prefabs/Pickups/BhopBoots_Pickup.prefab";
|
||||
|
||||
[MenuItem("OGG/Setup/Create Bunny Hop Boots")]
|
||||
public static void Create()
|
||||
{
|
||||
EnsureFolder("Assets/Items");
|
||||
EnsureFolder("Assets/Prefabs/Pickups");
|
||||
|
||||
// ── ItemDefinition ────────────────────────────────────────────
|
||||
ItemDefinition item = AssetDatabase.LoadAssetAtPath<ItemDefinition>(ITEM_DEF_PATH);
|
||||
bool isNew = item == null;
|
||||
if (isNew) item = ScriptableObject.CreateInstance<ItemDefinition>();
|
||||
|
||||
item.itemName = "Bunny Hop Boots";
|
||||
item.type = ItemDefinition.ItemType.Misc;
|
||||
item.isEquippable = true;
|
||||
item.description = "Illegal footwear. Gives 200 stamina while worn. Do not wear near cliffs.";
|
||||
|
||||
if (isNew)
|
||||
AssetDatabase.CreateAsset(item, ITEM_DEF_PATH);
|
||||
else
|
||||
EditorUtility.SetDirty(item);
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
// ── Pickup prefab — procedural boot shape ─────────────────────
|
||||
GameObject root = new GameObject("BhopBoots_Pickup");
|
||||
|
||||
// Simple visual: a squashed cube (boot-ish)
|
||||
GameObject body = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
body.name = "Visual";
|
||||
body.transform.SetParent(root.transform, false);
|
||||
body.transform.localPosition = new Vector3(0f, 0f, 0f);
|
||||
body.transform.localScale = new Vector3(0.4f, 0.2f, 0.7f);
|
||||
Object.DestroyImmediate(body.GetComponent<Collider>());
|
||||
|
||||
// Bright accent colour so it stands out
|
||||
var rend = body.GetComponent<Renderer>();
|
||||
if (rend != null)
|
||||
{
|
||||
rend.material = new Material(Shader.Find("Universal Render Pipeline/Lit"));
|
||||
rend.material.color = new Color(0.1f, 0.9f, 0.4f);
|
||||
}
|
||||
|
||||
PickupItem pickup = root.AddComponent<PickupItem>();
|
||||
pickup.definition = item;
|
||||
pickup.spinSpeed = 140f;
|
||||
pickup.bobHeight = 0.2f;
|
||||
pickup.bobSpeed = 2.8f;
|
||||
pickup.pickupRadius = 2.2f;
|
||||
pickup.pickupKey = KeyCode.E;
|
||||
|
||||
StaminaBoostPickup boost = root.AddComponent<StaminaBoostPickup>();
|
||||
boost.newMaxStamina = 200f;
|
||||
|
||||
if (File.Exists(Application.dataPath + "/../" + PICKUP_PREFAB))
|
||||
AssetDatabase.DeleteAsset(PICKUP_PREFAB);
|
||||
|
||||
GameObject saved = PrefabUtility.SaveAsPrefabAsset(root, PICKUP_PREFAB);
|
||||
Object.DestroyImmediate(root);
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
EditorUtility.DisplayDialog(
|
||||
"Bunny Hop Boots ✓",
|
||||
$"Created:\n• {ITEM_DEF_PATH}\n• {PICKUP_PREFAB}\n\n" +
|
||||
"Drag BhopBoots_Pickup into the scene.\n" +
|
||||
"Pick it up with [E] to unlock bunny hopping.\n\n" +
|
||||
"Hold SPACE while landing to chain hops and build speed.\n" +
|
||||
"Strafe left/right mid-air to steer.",
|
||||
"Let's go");
|
||||
|
||||
EditorGUIUtility.PingObject(saved);
|
||||
Selection.activeObject = saved;
|
||||
}
|
||||
|
||||
static void EnsureFolder(string path)
|
||||
{
|
||||
string[] parts = path.Split('/');
|
||||
string current = parts[0];
|
||||
for (int i = 1; i < parts.Length; i++)
|
||||
{
|
||||
string next = current + "/" + parts[i];
|
||||
if (!AssetDatabase.IsValidFolder(next))
|
||||
AssetDatabase.CreateFolder(current, parts[i]);
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Editor/BhopBootsSetup.cs.meta
Normal file
2
Assets/Scripts/Editor/BhopBootsSetup.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 92ff81f98e809934bab9c5b8f160276a
|
||||
151
Assets/Scripts/Editor/GunSplatSetup.cs
Normal file
151
Assets/Scripts/Editor/GunSplatSetup.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
|
||||
/// <summary>
|
||||
/// OGG → Setup → Create Gun Splat Weapon
|
||||
/// Builds:
|
||||
/// • Assets/Prefabs/Weapons/GunSplat.prefab — the held weapon (SimpleGun)
|
||||
/// • Assets/Prefabs/Pickups/GunSplat_Pickup.prefab — world pickup (spins/bobs, press E)
|
||||
/// • Assets/Items/GunSplat_Item.asset — ItemDefinition (type = Weapon)
|
||||
/// </summary>
|
||||
public static class GunSplatSetup
|
||||
{
|
||||
private const string GLB_PATH = "Assets/Models/LidarScans/Gun Splat.glb";
|
||||
private const string WEAPON_PREFAB = "Assets/Prefabs/Weapons/GunSplat.prefab";
|
||||
private const string PICKUP_PREFAB = "Assets/Prefabs/Pickups/GunSplat_Pickup.prefab";
|
||||
private const string ITEM_DEF_PATH = "Assets/Items/GunSplat_Item.asset";
|
||||
|
||||
[MenuItem("OGG/Setup/Create Gun Splat Weapon")]
|
||||
public static void CreateGunSplat()
|
||||
{
|
||||
// ── 1. Ensure output folders exist ──────────────────────────
|
||||
EnsureFolder("Assets/Prefabs/Weapons");
|
||||
EnsureFolder("Assets/Prefabs/Pickups");
|
||||
EnsureFolder("Assets/Items");
|
||||
|
||||
// ── 2. Load the GLB model ────────────────────────────────────
|
||||
GameObject modelAsset = AssetDatabase.LoadAssetAtPath<GameObject>(GLB_PATH);
|
||||
if (modelAsset == null)
|
||||
{
|
||||
Debug.LogError($"[GunSplatSetup] Could not find GLB at: {GLB_PATH}");
|
||||
EditorUtility.DisplayDialog("Gun Splat Setup", $"Could not find model at:\n{GLB_PATH}", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
// ── 3. Build the held-weapon prefab ──────────────────────────
|
||||
GameObject weaponRoot = new GameObject("GunSplat");
|
||||
AttachVisual(weaponRoot, modelAsset);
|
||||
|
||||
SimpleGun gun = weaponRoot.AddComponent<SimpleGun>();
|
||||
gun.damage = 30f;
|
||||
gun.range = 120f;
|
||||
gun.fireRate = 6f;
|
||||
gun.maxAmmo = 24;
|
||||
gun.isAutomatic = false;
|
||||
|
||||
if (File.Exists(DataRelative(WEAPON_PREFAB)))
|
||||
AssetDatabase.DeleteAsset(WEAPON_PREFAB);
|
||||
|
||||
GameObject savedWeapon = PrefabUtility.SaveAsPrefabAsset(weaponRoot, WEAPON_PREFAB);
|
||||
Object.DestroyImmediate(weaponRoot);
|
||||
|
||||
if (savedWeapon == null)
|
||||
{
|
||||
Debug.LogError("[GunSplatSetup] Failed to save weapon prefab.");
|
||||
return;
|
||||
}
|
||||
Debug.Log($"[GunSplatSetup] Weapon prefab → {WEAPON_PREFAB}");
|
||||
|
||||
// ── 4. Create / update ItemDefinition ────────────────────────
|
||||
ItemDefinition item = AssetDatabase.LoadAssetAtPath<ItemDefinition>(ITEM_DEF_PATH);
|
||||
bool isNew = item == null;
|
||||
if (isNew) item = ScriptableObject.CreateInstance<ItemDefinition>();
|
||||
|
||||
item.itemName = "Gun Splat";
|
||||
item.type = ItemDefinition.ItemType.Weapon;
|
||||
item.weaponPrefab = savedWeapon;
|
||||
item.description = "A janky lidar-scanned sidearm. Shoots first, looks weird always.";
|
||||
|
||||
if (isNew)
|
||||
AssetDatabase.CreateAsset(item, ITEM_DEF_PATH);
|
||||
else
|
||||
EditorUtility.SetDirty(item);
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
Debug.Log($"[GunSplatSetup] ItemDefinition → {ITEM_DEF_PATH}");
|
||||
|
||||
// ── 5. Build the world pickup prefab ─────────────────────────
|
||||
GameObject pickupRoot = new GameObject("GunSplat_Pickup");
|
||||
|
||||
// Visual child — the GLB model
|
||||
AttachVisual(pickupRoot, modelAsset);
|
||||
|
||||
// PickupItem component
|
||||
PickupItem pickup = pickupRoot.AddComponent<PickupItem>();
|
||||
pickup.definition = item;
|
||||
pickup.spinSpeed = 90f;
|
||||
pickup.bobHeight = 0.15f;
|
||||
pickup.bobSpeed = 2.0f;
|
||||
pickup.pickupRadius = 2.2f;
|
||||
pickup.pickupKey = KeyCode.E;
|
||||
|
||||
if (File.Exists(DataRelative(PICKUP_PREFAB)))
|
||||
AssetDatabase.DeleteAsset(PICKUP_PREFAB);
|
||||
|
||||
GameObject savedPickup = PrefabUtility.SaveAsPrefabAsset(pickupRoot, PICKUP_PREFAB);
|
||||
Object.DestroyImmediate(pickupRoot);
|
||||
|
||||
if (savedPickup == null)
|
||||
{
|
||||
Debug.LogError("[GunSplatSetup] Failed to save pickup prefab.");
|
||||
return;
|
||||
}
|
||||
Debug.Log($"[GunSplatSetup] Pickup prefab → {PICKUP_PREFAB}");
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
// ── 6. Done ──────────────────────────────────────────────────
|
||||
EditorUtility.DisplayDialog(
|
||||
"Gun Splat Setup ✓",
|
||||
"Created:\n" +
|
||||
$"• {WEAPON_PREFAB}\n" +
|
||||
$"• {PICKUP_PREFAB}\n" +
|
||||
$"• {ITEM_DEF_PATH}\n\n" +
|
||||
"Drag GunSplat_Pickup into the scene wherever you want it to spawn.\n" +
|
||||
"It will spin, bob, and show an [E] prompt when the player gets close.",
|
||||
"Sick");
|
||||
|
||||
EditorGUIUtility.PingObject(savedPickup);
|
||||
Selection.activeObject = savedPickup;
|
||||
}
|
||||
|
||||
// ─── Helpers ─────────────────────────────────────────────────────
|
||||
|
||||
static void AttachVisual(GameObject parent, GameObject modelAsset)
|
||||
{
|
||||
GameObject visual = (GameObject)PrefabUtility.InstantiatePrefab(modelAsset);
|
||||
if (visual == null) visual = Object.Instantiate(modelAsset);
|
||||
visual.name = "Visual";
|
||||
visual.transform.SetParent(parent.transform, false);
|
||||
visual.transform.localPosition = Vector3.zero;
|
||||
visual.transform.localRotation = Quaternion.identity;
|
||||
visual.transform.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
static string DataRelative(string assetPath) =>
|
||||
Application.dataPath + "/../" + assetPath;
|
||||
|
||||
static void EnsureFolder(string path)
|
||||
{
|
||||
string[] parts = path.Split('/');
|
||||
string current = parts[0];
|
||||
for (int i = 1; i < parts.Length; i++)
|
||||
{
|
||||
string next = current + "/" + parts[i];
|
||||
if (!AssetDatabase.IsValidFolder(next))
|
||||
AssetDatabase.CreateFolder(current, parts[i]);
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Editor/GunSplatSetup.cs.meta
Normal file
2
Assets/Scripts/Editor/GunSplatSetup.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0ceea0a64e3fa344b83004be51fe457
|
||||
92
Assets/Scripts/Editor/WeaponManagerEditor.cs
Normal file
92
Assets/Scripts/Editor/WeaponManagerEditor.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
[CustomEditor(typeof(WeaponManager))]
|
||||
public class WeaponManagerEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
DrawDefaultInspector();
|
||||
|
||||
WeaponManager wm = (WeaponManager)target;
|
||||
|
||||
if (!Application.isPlaying) return;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("── Live Positioning ──", EditorStyles.boldLabel);
|
||||
|
||||
// Show what's active
|
||||
string activeName = wm.ActiveWeaponName;
|
||||
if (string.IsNullOrEmpty(activeName))
|
||||
{
|
||||
EditorGUILayout.HelpBox("No weapon currently equipped.", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUILayout.HelpBox($"Active: {activeName}", MessageType.None);
|
||||
|
||||
// Select the live GO so you can drag gizmos in Scene view
|
||||
if (GUILayout.Button("🎯 Select Active Weapon in Scene"))
|
||||
{
|
||||
var slot = wm.slots.Find(s => s.itemName == activeName);
|
||||
if (slot != null)
|
||||
{
|
||||
Selection.activeGameObject = slot.instance;
|
||||
SceneView.lastActiveSceneView?.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// Sync the current transform back into the WeaponViewmodel (or fallback global offset)
|
||||
if (GUILayout.Button("⬆ Sync Transform → Offset Fields"))
|
||||
{
|
||||
var slot = wm.slots.Find(s => s.itemName == activeName);
|
||||
if (slot != null)
|
||||
{
|
||||
var vm = slot.instance.GetComponent<WeaponViewmodel>();
|
||||
if (vm != null)
|
||||
{
|
||||
Undo.RecordObject(vm, "Sync Weapon Viewmodel");
|
||||
vm.SyncFromTransform();
|
||||
EditorUtility.SetDirty(vm);
|
||||
|
||||
// Also save back to the source prefab asset
|
||||
var prefabAsset = PrefabUtility.GetCorrespondingObjectFromSource(slot.instance);
|
||||
if (prefabAsset != null)
|
||||
{
|
||||
var prefabVm = prefabAsset.GetComponent<WeaponViewmodel>();
|
||||
if (prefabVm != null)
|
||||
{
|
||||
Undo.RecordObject(prefabVm, "Sync Weapon Viewmodel Prefab");
|
||||
prefabVm.positionOffset = vm.positionOffset;
|
||||
prefabVm.rotationOffset = vm.rotationOffset;
|
||||
prefabVm.scale = vm.scale;
|
||||
EditorUtility.SetDirty(prefabVm);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
}
|
||||
Debug.Log($"[WeaponManager] Synced to WeaponViewmodel: pos={vm.positionOffset} rot={vm.rotationOffset} scale={vm.scale}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback: no viewmodel, write to global offsets
|
||||
Undo.RecordObject(wm, "Sync Weapon Offset");
|
||||
wm.weaponPositionOffset = slot.instance.transform.localPosition;
|
||||
wm.weaponRotationOffset = slot.instance.transform.localRotation.eulerAngles;
|
||||
wm.weaponScale = slot.instance.transform.localScale;
|
||||
EditorUtility.SetDirty(wm);
|
||||
Debug.Log($"[WeaponManager] Synced to global offset: pos={wm.weaponPositionOffset}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.HelpBox(
|
||||
"1. Hit Play & equip the gun\n" +
|
||||
"2. Click 'Select Active Weapon'\n" +
|
||||
"3. Use Move/Rotate gizmos in Scene view\n" +
|
||||
"4. Click 'Sync Transform → Offset Fields'\n" +
|
||||
"5. Stop Play — values are saved",
|
||||
MessageType.Info);
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Editor/WeaponManagerEditor.cs.meta
Normal file
2
Assets/Scripts/Editor/WeaponManagerEditor.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe67de8a32d4bf5449ee8def34a1bb8a
|
||||
Reference in New Issue
Block a user