SummerGame/Assets/KirillAss/Scripts/Player/TruckBoxVisuals.cs

156 lines
5.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

namespace Player
{
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TruckBedVisuals : MonoBehaviour
{
[Header("Настройки кузова")]
public Transform bedStartPoint;
public GameObject visualBoxPrefab;
[Header("Сетка укладки")]
public int columns = 3;
public int rows = 3;
[Header("Размеры и отступы ")]
public bool uniformScale = true;
public Vector3 boxSize = new Vector3(1f, 1f, 1f);
public Vector3 boxPadding = new Vector3(0.05f, 0.05f, 0.05f);
[Header("Отрисовка в редакторе")]
public int gizmoPreviewLayers = 3;
[Header("Физика выпадения")]
public float dropUpForce = 5f;
public float dropBackForce = 15f;
public float dropTorque = 10f;
private Stack<GameObject> _stackedBoxes = new Stack<GameObject>();
private Collider _carCollider;
private void OnValidate()
{
if (uniformScale)
{
boxSize.y = boxSize.x;
boxSize.z = boxSize.x;
boxPadding.y = boxPadding.x;
boxPadding.z = boxPadding.x;
}
}
void Awake()
{
_carCollider = GetComponent<Collider>();
}
private void OnEnable()
{
GameEvents.OnBoxAddedToTruck += AddBox;
GameEvents.OnBoxLostFromTruck += DropBox;
}
private void OnDisable()
{
GameEvents.OnBoxAddedToTruck -= AddBox;
GameEvents.OnBoxLostFromTruck -= DropBox;
}
private void OnDrawGizmos()
{
if (bedStartPoint == null) return;
Gizmos.color = new Color(0f, 1f, 0f, 0.5f);
Vector3 step = boxSize + boxPadding;
// Сохраняем старую матрицу и применяем трансформацию якоря кузова.
// Теперь сетка будет крутиться и двигаться вместе с машиной!
Matrix4x4 oldMatrix = Gizmos.matrix;
Gizmos.matrix = bedStartPoint.localToWorldMatrix;
for (int layer = 0; layer < gizmoPreviewLayers; layer++)
{
for (int x = 0; x < columns; x++)
{
for (int z = 0; z < rows; z++)
{
Vector3 boxCenter = new Vector3(x * step.x, layer * step.y, -z * step.z);
Gizmos.DrawWireCube(boxCenter, boxSize);
}
}
}
Gizmos.matrix = oldMatrix;
}
private void AddBox()
{
if (visualBoxPrefab == null || bedStartPoint == null) return;
int index = _stackedBoxes.Count;
int layer = index / (columns * rows);
int indexInLayer = index % (columns * rows);
int x = indexInLayer % columns;
int z = indexInLayer / columns;
Vector3 step = boxSize + boxPadding;
Vector3 localPos = new Vector3(x * step.x, layer * step.y, -z * step.z);
GameObject newBox = SimpleObjectPool.Instance.Get(visualBoxPrefab, bedStartPoint.position, bedStartPoint.rotation);
newBox.transform.SetParent(bedStartPoint);
newBox.transform.localPosition = localPos;
newBox.transform.localRotation = Quaternion.identity;
newBox.transform.localScale = boxSize;
Rigidbody rb = newBox.GetComponent<Rigidbody>();
if (rb != null) rb.isKinematic = true;
Collider coll = newBox.GetComponent<Collider>();
if (coll != null) coll.enabled = false;
_stackedBoxes.Push(newBox);
}
private void DropBox()
{
if (_stackedBoxes.Count == 0) return;
GameObject boxToDrop = _stackedBoxes.Pop();
boxToDrop.transform.SetParent(null);
Collider coll = boxToDrop.GetComponent<Collider>();
if (coll != null)
{
coll.enabled = true;
if (_carCollider != null) Physics.IgnoreCollision(coll, _carCollider);
}
Rigidbody rb = boxToDrop.GetComponent<Rigidbody>();
if (rb != null)
{
rb.isKinematic = false;
Rigidbody carRb = GetComponent<Rigidbody>();
if (carRb != null) rb.linearVelocity = carRb.linearVelocity;
Vector3 force = transform.up * dropUpForce - transform.forward * dropBackForce;
rb.AddForce(force, ForceMode.Impulse);
rb.AddTorque(Random.insideUnitSphere * dropTorque, ForceMode.Impulse);
}
StartCoroutine(ReturnBoxToPool(boxToDrop, 3f));
}
IEnumerator ReturnBoxToPool(GameObject box, float delay)
{
yield return new WaitForSeconds(delay);
SimpleObjectPool.Instance.ReturnToPool(visualBoxPrefab, box);
}
}
}