197 lines
5.1 KiB
C#
197 lines
5.1 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class Constellation : MonoBehaviour
|
|
{
|
|
[Header("Режим малювання")]
|
|
public bool editMode = false;
|
|
[Header("Максимальна кількіссть зірок")]
|
|
public int maxStars = 10;
|
|
|
|
[Header("Матеріали")]
|
|
[SerializeField] private GameObject starPrefab;
|
|
[SerializeField] private Material lineMaterial;
|
|
|
|
[Header("Відстань")]
|
|
[SerializeField] private float planeDistance = 8f;
|
|
|
|
[Header("Розміри")]
|
|
[SerializeField] private float starScaleMin = 0.06f;
|
|
[SerializeField] private float starScaleMax = 0.14f;
|
|
[SerializeField] private float lineWidth = 0.02f;
|
|
|
|
private readonly List<Transform> _stars = new List<Transform>();
|
|
private readonly List<LineRenderer> _lines = new List<LineRenderer>();
|
|
|
|
private Transform _root;
|
|
private Camera _cam;
|
|
|
|
private void Awake()
|
|
{
|
|
EnsureCameraAndRoot();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!editMode) return;
|
|
|
|
EnsureCameraAndRoot();
|
|
|
|
if (_cam == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (Input.GetMouseButtonDown(0))
|
|
{
|
|
TryAddStarByClick(Input.mousePosition);
|
|
}
|
|
|
|
UpdateAllLines();
|
|
}
|
|
|
|
private void EnsureCameraAndRoot()
|
|
{
|
|
if (_cam == null || !_cam.enabled)
|
|
{
|
|
_cam = FindEnabledCamera();
|
|
}
|
|
|
|
if (_cam != null && (_root == null || _root.parent != _cam.transform))
|
|
{
|
|
if (_root == null)
|
|
{
|
|
GameObject go = new GameObject("ConstellationRoot");
|
|
_root = go.transform;
|
|
}
|
|
|
|
_root.SetParent(_cam.transform);
|
|
_root.localPosition = new Vector3(0f, 0f, planeDistance);
|
|
_root.localRotation = Quaternion.identity;
|
|
_root.localScale = Vector3.one;
|
|
}
|
|
}
|
|
|
|
private Camera FindEnabledCamera()
|
|
{
|
|
Camera[] cams = Camera.allCameras;
|
|
for (int i = 0; i < cams.Length; i++)
|
|
{
|
|
if (cams[i] != null && cams[i].enabled && cams[i].gameObject.activeInHierarchy)
|
|
return cams[i];
|
|
}
|
|
|
|
if (Camera.main != null && Camera.main.enabled)
|
|
return Camera.main;
|
|
|
|
return null;
|
|
}
|
|
|
|
private void TryAddStarByClick(Vector3 screenPos)
|
|
{
|
|
Ray ray = _cam.ScreenPointToRay(screenPos);
|
|
|
|
Plane plane = new Plane(_cam.transform.forward, _cam.transform.position + _cam.transform.forward * planeDistance);
|
|
|
|
if (!plane.Raycast(ray, out float enter))
|
|
{
|
|
return;
|
|
}
|
|
|
|
Vector3 worldHit = ray.GetPoint(enter);
|
|
Vector3 localHit = _root.InverseTransformPoint(worldHit);
|
|
|
|
GameObject starGo = Instantiate(starPrefab, _root);
|
|
starGo.name = "Star_" + _stars.Count;
|
|
|
|
Transform starT = starGo.transform;
|
|
starT.localPosition = localHit;
|
|
|
|
float rndScale = Random.Range(starScaleMin, starScaleMax);
|
|
starT.localScale = Vector3.one * rndScale;
|
|
|
|
_stars.Add(starT);
|
|
|
|
if (_stars.Count >= 2)
|
|
{
|
|
CreateLine(_stars[_stars.Count - 2], _stars[_stars.Count - 1]);
|
|
}
|
|
}
|
|
|
|
private void CreateLine(Transform a, Transform b)
|
|
{
|
|
if (a == null || b == null) return;
|
|
|
|
GameObject lineGo = new GameObject("Line_" + _lines.Count);
|
|
lineGo.transform.SetParent(_root);
|
|
lineGo.transform.localPosition = Vector3.zero;
|
|
lineGo.transform.localRotation = Quaternion.identity;
|
|
lineGo.transform.localScale = Vector3.one;
|
|
|
|
LineRenderer lr = lineGo.AddComponent<LineRenderer>();
|
|
|
|
if (lineMaterial != null)
|
|
{
|
|
lr.material = lineMaterial;
|
|
}
|
|
else
|
|
{
|
|
Material fallback = new Material(Shader.Find("Unlit/Color"));
|
|
fallback.color = new Color(0.7f, 0.85f, 1f, 1f);
|
|
lr.material = fallback;
|
|
}
|
|
|
|
lr.useWorldSpace = false;
|
|
lr.positionCount = 2;
|
|
lr.startWidth = lineWidth;
|
|
lr.endWidth = lineWidth;
|
|
|
|
lr.numCapVertices = 6;
|
|
lr.numCornerVertices = 6;
|
|
|
|
_lines.Add(lr);
|
|
|
|
lr.SetPosition(0, a.localPosition);
|
|
lr.SetPosition(1, b.localPosition);
|
|
}
|
|
|
|
private void UpdateAllLines()
|
|
{
|
|
int needed = Mathf.Max(0, _stars.Count - 1);
|
|
if (_lines.Count < needed) return;
|
|
|
|
for (int i = 0; i < needed; i++)
|
|
{
|
|
LineRenderer lr = _lines[i];
|
|
if (lr == null) continue;
|
|
|
|
Transform a = _stars[i];
|
|
Transform b = _stars[i + 1];
|
|
|
|
if (a == null || b == null) continue;
|
|
|
|
lr.SetPosition(0, a.localPosition);
|
|
lr.SetPosition(1, b.localPosition);
|
|
}
|
|
}
|
|
|
|
public void ClearAll()
|
|
{
|
|
for (int i = 0; i < _lines.Count; i++)
|
|
{
|
|
if (_lines[i] != null) Destroy(_lines[i].gameObject);
|
|
}
|
|
|
|
for (int i = 0; i < _stars.Count; i++)
|
|
{
|
|
if (_stars[i] != null) Destroy(_stars[i].gameObject);
|
|
}
|
|
|
|
_lines.Clear();
|
|
_stars.Clear();
|
|
|
|
}
|
|
|
|
}
|