147 lines
3.6 KiB
C#
147 lines
3.6 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public class LightManager : MonoBehaviour
|
|
{
|
|
[SerializeField] private GameObject lightPanel;
|
|
public int maxLights = 15;
|
|
[SerializeField] private float maxDistance = 200f;
|
|
|
|
private int _currentLights = 0;
|
|
public int CurrentLights => _currentLights;
|
|
|
|
private Color _selectedColor;
|
|
private GameObject _previewObject;
|
|
private List<GameObject> _placedLights = new List<GameObject>();
|
|
public GameObject GetLightPanel() => lightPanel;
|
|
|
|
void Start()
|
|
{
|
|
lightPanel.SetActive(false);
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (Input.GetKeyDown(KeyCode.R))
|
|
{
|
|
lightPanel.SetActive(!lightPanel.activeSelf);
|
|
|
|
if (!lightPanel.activeSelf)
|
|
CancelPreview();
|
|
}
|
|
|
|
if (_previewObject != null)
|
|
{
|
|
UpdatePreviewPosition();
|
|
|
|
if (Input.GetMouseButtonDown(0))
|
|
PlaceLight();
|
|
|
|
if (Input.GetMouseButtonDown(1))
|
|
CancelPreview();
|
|
}
|
|
else
|
|
{
|
|
if (Input.GetMouseButtonDown(1))
|
|
TryRemoveLight();
|
|
}
|
|
}
|
|
|
|
public void SetWhite() => CreatePreview(Color.white);
|
|
public void SetRed() => CreatePreview(Color.red);
|
|
public void SetBlue() => CreatePreview(Color.blue);
|
|
public void SetGreen() => CreatePreview(Color.green);
|
|
|
|
private void CreatePreview(Color color)
|
|
{
|
|
if (_currentLights >= maxLights) return;
|
|
|
|
CancelPreview();
|
|
_selectedColor = color;
|
|
|
|
_previewObject = new GameObject("Preview Light");
|
|
|
|
Light l = _previewObject.AddComponent<Light>();
|
|
l.type = LightType.Point;
|
|
l.range = 8f;
|
|
l.intensity = 3f;
|
|
l.color = _selectedColor;
|
|
}
|
|
|
|
private void CancelPreview()
|
|
{
|
|
if (_previewObject != null)
|
|
{
|
|
Destroy(_previewObject);
|
|
_previewObject = null;
|
|
}
|
|
}
|
|
|
|
private void UpdatePreviewPosition()
|
|
{
|
|
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
|
|
|
if (Physics.Raycast(ray, out RaycastHit hit, maxDistance))
|
|
{
|
|
_previewObject.transform.position = hit.point + hit.normal * 0.1f;
|
|
}
|
|
}
|
|
|
|
private void PlaceLight()
|
|
{
|
|
if (_currentLights >= maxLights) return;
|
|
|
|
GameObject lightGO = new GameObject("New Light");
|
|
lightGO.transform.position = _previewObject.transform.position;
|
|
|
|
Light l = lightGO.AddComponent<Light>();
|
|
l.type = LightType.Point;
|
|
l.range = 8f;
|
|
l.intensity = 5f;
|
|
l.color = _selectedColor;
|
|
|
|
SphereCollider col = lightGO.AddComponent<SphereCollider>();
|
|
col.radius = 0.5f;
|
|
|
|
_placedLights.Add(lightGO);
|
|
_currentLights++;
|
|
}
|
|
|
|
private void TryRemoveLight()
|
|
{
|
|
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
|
|
|
if (!Physics.Raycast(ray, out RaycastHit hit, maxDistance))
|
|
return;
|
|
|
|
GameObject hitObject = hit.collider.gameObject;
|
|
|
|
if (_placedLights.Contains(hitObject))
|
|
{
|
|
RemoveLight(hitObject);
|
|
return;
|
|
}
|
|
|
|
float removeRadius = 1f;
|
|
Collider[] nearby = Physics.OverlapSphere(hit.point, removeRadius);
|
|
|
|
foreach (Collider col in nearby)
|
|
{
|
|
if (_placedLights.Contains(col.gameObject))
|
|
{
|
|
RemoveLight(col.gameObject);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void RemoveLight(GameObject lightObject)
|
|
{
|
|
_placedLights.Remove(lightObject);
|
|
Destroy(lightObject);
|
|
_currentLights--;
|
|
}
|
|
}
|