test
This commit is contained in:
@@ -181,6 +181,19 @@ public class InventoryItemFactory : MonoBehaviour
|
|||||||
rb.linearVelocity = velocity.Value + (Vector3.up * (config?.dropForce ?? 2f));
|
rb.linearVelocity = velocity.Value + (Vector3.up * (config?.dropForce ?? 2f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Если у ItemData нет связанной модели — создаём простой визуал (куб)
|
||||||
|
if (itemData != null && itemData.modelPrefab == null && worldItem != null)
|
||||||
|
{
|
||||||
|
var visual = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||||
|
visual.name = "Visual";
|
||||||
|
visual.transform.SetParent(worldItem.transform, false);
|
||||||
|
visual.transform.localPosition = Vector3.zero;
|
||||||
|
visual.transform.localScale = Vector3.one * 0.3f;
|
||||||
|
// Удаляем лишний коллайдер на визуале
|
||||||
|
var col = visual.GetComponent<Collider>();
|
||||||
|
if (col != null) GameObject.Destroy(col);
|
||||||
|
}
|
||||||
|
|
||||||
return worldItem;
|
return worldItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
public class InventoryManager : MonoBehaviour
|
public class InventoryManager : MonoBehaviour
|
||||||
{
|
{
|
||||||
@@ -108,37 +109,22 @@ public class InventoryManager : MonoBehaviour
|
|||||||
var eventsGO = new GameObject("InventoryEvents");
|
var eventsGO = new GameObject("InventoryEvents");
|
||||||
eventsGO.AddComponent<InventoryEvents>();
|
eventsGO.AddComponent<InventoryEvents>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Попробуем загрузить сохранённый инвентарь
|
||||||
|
LoadFromFile();
|
||||||
|
|
||||||
|
// Ensure PlayerInput exists and subscribe to input events
|
||||||
|
if (PlayerInput.Instance == null)
|
||||||
|
{
|
||||||
|
var go = new GameObject("PlayerInput");
|
||||||
|
go.AddComponent<PlayerInput>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update()
|
PlayerInput.Instance.OnToggleInventory += ToggleInventory;
|
||||||
{
|
PlayerInput.Instance.OnDropPressed += DropSelectedItem;
|
||||||
// Toggle инвентаря на Tab
|
PlayerInput.Instance.OnHotbarSelect += SelectHotbarSlot;
|
||||||
if (Input.GetKeyDown(KeyCode.Tab))
|
|
||||||
{
|
|
||||||
ToggleInventory();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Закрыть на Escape
|
|
||||||
if (Input.GetKeyDown(KeyCode.Escape) && inventoryPanel != null && inventoryPanel.activeSelf)
|
|
||||||
{
|
|
||||||
ToggleInventory();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Горячие клавиши 1-9 для хотбара
|
|
||||||
for (int i = 0; i < 9; i++)
|
|
||||||
{
|
|
||||||
if (Input.GetKeyDown(KeyCode.Alpha1 + i))
|
|
||||||
{
|
|
||||||
SelectHotbarSlot(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Выброс предмета на Q
|
|
||||||
if (Input.GetKeyDown(KeyCode.Q))
|
|
||||||
{
|
|
||||||
DropSelectedItem();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ToggleInventory()
|
public void ToggleInventory()
|
||||||
{
|
{
|
||||||
@@ -151,11 +137,15 @@ public class InventoryManager : MonoBehaviour
|
|||||||
{
|
{
|
||||||
Cursor.lockState = CursorLockMode.None;
|
Cursor.lockState = CursorLockMode.None;
|
||||||
InventoryEvents.Instance?.OnInventoryOpened?.Invoke();
|
InventoryEvents.Instance?.OnInventoryOpened?.Invoke();
|
||||||
|
if (PlayerInput.Instance != null)
|
||||||
|
PlayerInput.Instance.Enabled = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Cursor.lockState = CursorLockMode.Locked;
|
Cursor.lockState = CursorLockMode.Locked;
|
||||||
InventoryEvents.Instance?.OnInventoryClosed?.Invoke();
|
InventoryEvents.Instance?.OnInventoryClosed?.Invoke();
|
||||||
|
if (PlayerInput.Instance != null)
|
||||||
|
PlayerInput.Instance.Enabled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -568,6 +558,49 @@ public class InventoryManager : MonoBehaviour
|
|||||||
return JsonUtility.ToJson(inventoryData, true);
|
return JsonUtility.ToJson(inventoryData, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Сохранить инвентарь в файл (Application.persistentDataPath)
|
||||||
|
/// </summary>
|
||||||
|
public void SaveToFile()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string json = ExportToJson();
|
||||||
|
string path = Path.Combine(Application.persistentDataPath, "inventory_save.json");
|
||||||
|
File.WriteAllText(path, json);
|
||||||
|
Debug.Log($"[InventoryManager] Saved inventory to: {path}");
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
Debug.LogError($"[InventoryManager] Failed to save inventory: {ex}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Загрузить инвентарь из файла (если есть)
|
||||||
|
/// </summary>
|
||||||
|
public void LoadFromFile()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string path = Path.Combine(Application.persistentDataPath, "inventory_save.json");
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
string json = File.ReadAllText(path);
|
||||||
|
ImportFromJson(json);
|
||||||
|
Debug.Log($"[InventoryManager] Loaded inventory from: {path}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log("[InventoryManager] No save file found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
Debug.LogError($"[InventoryManager] Failed to load inventory: {ex}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void ImportFromJson(string json)
|
public void ImportFromJson(string json)
|
||||||
{
|
{
|
||||||
var inventoryData = JsonUtility.FromJson<InventorySaveData>(json);
|
var inventoryData = JsonUtility.FromJson<InventorySaveData>(json);
|
||||||
@@ -598,4 +631,9 @@ public class InventoryManager : MonoBehaviour
|
|||||||
public string itemId;
|
public string itemId;
|
||||||
public int amount;
|
public int amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnApplicationQuit()
|
||||||
|
{
|
||||||
|
SaveToFile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -90,7 +90,6 @@ public class InventorySceneSetup
|
|||||||
|
|
||||||
// Компонент предмета
|
// Компонент предмета
|
||||||
var worldItem = itemGO.AddComponent<WorldItem>();
|
var worldItem = itemGO.AddComponent<WorldItem>();
|
||||||
worldItem.pickupDelay = 0f; // мгновенный подбор
|
|
||||||
worldItem.useFactory = false;
|
worldItem.useFactory = false;
|
||||||
|
|
||||||
// Тестовые данные
|
// Тестовые данные
|
||||||
@@ -101,8 +100,8 @@ public class InventorySceneSetup
|
|||||||
testItem.type = ItemType.Material;
|
testItem.type = ItemType.Material;
|
||||||
testItem.maxStack = 64;
|
testItem.maxStack = 64;
|
||||||
|
|
||||||
worldItem.itemData = testItem;
|
// Используем Setup чтобы инициализировать визуал и включить мгновенный подбор
|
||||||
worldItem.amount = 5;
|
worldItem.Setup(testItem, 5);
|
||||||
|
|
||||||
// Коллайдер для подбора (trigger для обычных коллайдеров)
|
// Коллайдер для подбора (trigger для обычных коллайдеров)
|
||||||
var box = itemGO.AddComponent<BoxCollider>();
|
var box = itemGO.AddComponent<BoxCollider>();
|
||||||
@@ -141,6 +140,15 @@ public class InventorySceneSetup
|
|||||||
canvas.sortingOrder = 100;
|
canvas.sortingOrder = 100;
|
||||||
canvasGO.AddComponent<GraphicRaycaster>();
|
canvasGO.AddComponent<GraphicRaycaster>();
|
||||||
|
|
||||||
|
// Ensure EventSystem exists for UI interaction
|
||||||
|
var existingES = GameObject.FindObjectOfType<UnityEngine.EventSystems.EventSystem>();
|
||||||
|
if (existingES == null)
|
||||||
|
{
|
||||||
|
var es = new GameObject("EventSystem");
|
||||||
|
es.AddComponent<UnityEngine.EventSystems.EventSystem>();
|
||||||
|
es.AddComponent<UnityEngine.EventSystems.StandaloneInputModule>();
|
||||||
|
}
|
||||||
|
|
||||||
// Создаём панель инвентаря
|
// Создаём панель инвентаря
|
||||||
var inventoryPanel = CreatePanel(canvasGO.transform, "InventoryPanel", new Color(0.15f, 0.15f, 0.15f, 0.95f));
|
var inventoryPanel = CreatePanel(canvasGO.transform, "InventoryPanel", new Color(0.15f, 0.15f, 0.15f, 0.95f));
|
||||||
var inventoryRect = inventoryPanel.GetComponent<RectTransform>();
|
var inventoryRect = inventoryPanel.GetComponent<RectTransform>();
|
||||||
|
|||||||
79
Assets/charecter-controller/scripts/PlayerInput.cs
Normal file
79
Assets/charecter-controller/scripts/PlayerInput.cs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
public class PlayerInput : MonoBehaviour
|
||||||
|
{
|
||||||
|
public static PlayerInput Instance { get; private set; }
|
||||||
|
|
||||||
|
// Continuous axes
|
||||||
|
public float MouseX { get; private set; }
|
||||||
|
public float MouseY { get; private set; }
|
||||||
|
public float Horizontal { get; private set; }
|
||||||
|
public float Vertical { get; private set; }
|
||||||
|
|
||||||
|
// Continuous states
|
||||||
|
public bool Crouch { get; private set; }
|
||||||
|
public bool Run { get; private set; }
|
||||||
|
|
||||||
|
// Events for discrete actions
|
||||||
|
public event Action OnToggleInventory;
|
||||||
|
public event Action OnDropPressed;
|
||||||
|
public event Action OnPickupPressed;
|
||||||
|
public event Action OnJumpPressed;
|
||||||
|
public event Action<int> OnHotbarSelect;
|
||||||
|
|
||||||
|
public bool Enabled { get; set; } = true;
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
if (Instance == null)
|
||||||
|
{
|
||||||
|
Instance = this;
|
||||||
|
DontDestroyOnLoad(gameObject);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Destroy(gameObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
// Always allow toggle inventory (Tab/Escape) even when input is disabled
|
||||||
|
if (Input.GetKeyDown(KeyCode.Tab) || Input.GetKeyDown(KeyCode.Escape))
|
||||||
|
OnToggleInventory?.Invoke();
|
||||||
|
|
||||||
|
if (!Enabled) return;
|
||||||
|
|
||||||
|
// Axes
|
||||||
|
MouseX = Input.GetAxis("Mouse X");
|
||||||
|
MouseY = Input.GetAxis("Mouse Y");
|
||||||
|
Horizontal = Input.GetAxisRaw("Horizontal");
|
||||||
|
Vertical = Input.GetAxisRaw("Vertical");
|
||||||
|
|
||||||
|
// Continuous keys
|
||||||
|
Crouch = Input.GetKey(KeyCode.C);
|
||||||
|
Run = Input.GetKey(KeyCode.LeftShift);
|
||||||
|
|
||||||
|
// Discrete actions
|
||||||
|
if (Input.GetButtonDown("Jump"))
|
||||||
|
OnJumpPressed?.Invoke();
|
||||||
|
|
||||||
|
if (Input.GetKeyDown(KeyCode.Tab))
|
||||||
|
OnToggleInventory?.Invoke();
|
||||||
|
|
||||||
|
if (Input.GetKeyDown(KeyCode.Q))
|
||||||
|
OnDropPressed?.Invoke();
|
||||||
|
|
||||||
|
if (Input.GetKeyDown(KeyCode.E))
|
||||||
|
OnPickupPressed?.Invoke();
|
||||||
|
|
||||||
|
for (int i = 0; i < 9; i++)
|
||||||
|
{
|
||||||
|
if (Input.GetKeyDown(KeyCode.Alpha1 + i))
|
||||||
|
{
|
||||||
|
OnHotbarSelect?.Invoke(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Assets/charecter-controller/scripts/PlayerInput.cs.meta
Normal file
2
Assets/charecter-controller/scripts/PlayerInput.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cb5fd82e043d6694e90df66d2b3f267a
|
||||||
@@ -31,6 +31,7 @@ public class charecter : MonoBehaviour
|
|||||||
float _headYaw;
|
float _headYaw;
|
||||||
float _pitch;
|
float _pitch;
|
||||||
Quaternion _headBindPose;
|
Quaternion _headBindPose;
|
||||||
|
bool _jumpRequested = false;
|
||||||
|
|
||||||
// Animator parameter hashes — no hardcoded strings at runtime
|
// Animator parameter hashes — no hardcoded strings at runtime
|
||||||
static readonly int HashSpeed = Animator.StringToHash("Speed");
|
static readonly int HashSpeed = Animator.StringToHash("Speed");
|
||||||
@@ -49,22 +50,28 @@ public class charecter : MonoBehaviour
|
|||||||
_bodyYaw = transform.eulerAngles.y;
|
_bodyYaw = transform.eulerAngles.y;
|
||||||
_headYaw = _bodyYaw;
|
_headYaw = _bodyYaw;
|
||||||
_headBindPose = head.localRotation;
|
_headBindPose = head.localRotation;
|
||||||
|
|
||||||
|
// Ensure PlayerInput exists and subscribe to events
|
||||||
|
if (PlayerInput.Instance == null)
|
||||||
|
{
|
||||||
|
var go = new GameObject("PlayerInput");
|
||||||
|
go.AddComponent<PlayerInput>();
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerInput.Instance.OnPickupPressed += () => TryPickupNearbyItem();
|
||||||
|
PlayerInput.Instance.OnJumpPressed += () => { _jumpRequested = true; };
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
HandleLook();
|
HandleLook();
|
||||||
HandleMovement();
|
HandleMovement();
|
||||||
HandlePickup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Item Pickup ───────────────────────────────────────────────────────────
|
// ── Item Pickup ───────────────────────────────────────────────────────────
|
||||||
void HandlePickup()
|
void HandlePickup()
|
||||||
{
|
{
|
||||||
if (Input.GetKeyDown(KeyCode.E))
|
// Input moved to PlayerInput events
|
||||||
{
|
|
||||||
TryPickupNearbyItem();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TryPickupNearbyItem()
|
void TryPickupNearbyItem()
|
||||||
@@ -115,19 +122,24 @@ public class charecter : MonoBehaviour
|
|||||||
// ── Mouse look ────────────────────────────────────────────────────────────
|
// ── Mouse look ────────────────────────────────────────────────────────────
|
||||||
void HandleLook()
|
void HandleLook()
|
||||||
{
|
{
|
||||||
_headYaw += Input.GetAxis("Mouse X") * mouseSensitivity;
|
var input = PlayerInput.Instance;
|
||||||
_pitch -= Input.GetAxis("Mouse Y") * mouseSensitivity;
|
if (input != null)
|
||||||
|
{
|
||||||
|
_headYaw += input.MouseX * mouseSensitivity;
|
||||||
|
_pitch -= input.MouseY * mouseSensitivity;
|
||||||
|
}
|
||||||
_pitch = Mathf.Clamp(_pitch, -maxPitch, maxPitch);
|
_pitch = Mathf.Clamp(_pitch, -maxPitch, maxPitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Movement ──────────────────────────────────────────────────────────────
|
// ── Movement ──────────────────────────────────────────────────────────────
|
||||||
void HandleMovement()
|
void HandleMovement()
|
||||||
{
|
{
|
||||||
float h = Input.GetAxisRaw("Horizontal");
|
var input = PlayerInput.Instance;
|
||||||
float v = Input.GetAxisRaw("Vertical");
|
float h = input != null ? input.Horizontal : Input.GetAxisRaw("Horizontal");
|
||||||
|
float v = input != null ? input.Vertical : Input.GetAxisRaw("Vertical");
|
||||||
|
|
||||||
bool isCrouching = Input.GetKey(KeyCode.C);
|
bool isCrouching = input != null ? input.Crouch : Input.GetKey(KeyCode.C);
|
||||||
bool isRunning = Input.GetKey(KeyCode.LeftShift) && !isCrouching;
|
bool isRunning = input != null ? input.Run && !isCrouching : Input.GetKey(KeyCode.LeftShift) && !isCrouching;
|
||||||
bool isMoving = (h * h + v * v) > 0.01f;
|
bool isMoving = (h * h + v * v) > 0.01f;
|
||||||
|
|
||||||
float speed = isCrouching ? crouchSpeed : isRunning ? runSpeed : walkSpeed;
|
float speed = isCrouching ? crouchSpeed : isRunning ? runSpeed : walkSpeed;
|
||||||
@@ -147,11 +159,12 @@ public class charecter : MonoBehaviour
|
|||||||
{
|
{
|
||||||
if (_verticalVelocity < 0f) _verticalVelocity = -2f;
|
if (_verticalVelocity < 0f) _verticalVelocity = -2f;
|
||||||
|
|
||||||
if (Input.GetButtonDown("Jump") && !isCrouching)
|
if (_jumpRequested && !isCrouching)
|
||||||
{
|
{
|
||||||
_verticalVelocity = Mathf.Sqrt(jumpHeight * -2f * gravity);
|
_verticalVelocity = Mathf.Sqrt(jumpHeight * -2f * gravity);
|
||||||
_anim?.SetTrigger(HashJump);
|
_anim?.SetTrigger(HashJump);
|
||||||
}
|
}
|
||||||
|
_jumpRequested = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_verticalVelocity += gravity * Time.deltaTime;
|
_verticalVelocity += gravity * Time.deltaTime;
|
||||||
|
|||||||
Reference in New Issue
Block a user