Код: Выделить всё
using System.Collections.Generic;
using UnityEngine;
public class Arrow : MonoBehaviour
{
public enum Direction { Up, Down, Left, Right }
[Header("Runtime settings (per-instance in Inspector)")]
[SerializeField] private Direction arrowDirection = Direction.Up;
[SerializeField] private Vector2Int gridPosition = Vector2Int.zero;
[SerializeField] private float moveTimerMax = 1f;
[Header("References")]
[SerializeField] private Transform arrowHead;
[SerializeField] private Transform arrowContainer;
private float moveTimer;
private bool moveInitialized;
// manual body parts (child components)
private List bodyParts = new List();
private List bodyGridPositions = new List();
private void Awake()
{
// preserve existing behaviour you wanted
moveTimer = 0f;
moveInitialized = false;
// gather body parts beneath the container in Hierarchy order
if (arrowContainer != null)
{
bodyParts.Clear();
foreach (var bp in arrowContainer.GetComponentsInChildren())
{
bodyParts.Add(bp);
}
// initialize body positions from inspector values on each part
bodyGridPositions.Clear();
for (int i = 0; i < bodyParts.Count; i++)
{
bodyParts[i].Init();
bodyGridPositions.Add(bodyParts[i].GetGridPosition());
}
}
// place head using localPosition relative to ArrowParent
if (arrowHead != null)
{
arrowHead.localPosition = GridToLocal(gridPosition);
}
else
{
// if no head ref assigned, assume this object acts as head
transform.localPosition = GridToLocal(gridPosition);
}
}
private void Update()
{
HandleTouch();
moveTimer += Time.deltaTime;
if (moveInitialized && moveTimer > moveTimerMax)
{
Vector2Int prevHead = gridPosition;
gridPosition += DirectionToVector(arrowDirection);
moveTimer -= moveTimerMax;
// shift body positions
if (bodyGridPositions.Count > 0)
{
bodyGridPositions.Insert(0, prevHead);
if (bodyGridPositions.Count > bodyParts.Count)
{
bodyGridPositions.RemoveAt(bodyGridPositions.Count - 1);
}
// apply positions & computed facing to each child body part
for (int i = 0; i < bodyParts.Count; i++)
{
var gridPos = bodyGridPositions[i];
// compute facing for this segment based on its next position
ArrowBodyPart.Direction dir = GetDirectionForBodySegment(i);
bodyParts[i].SetGridPosition(gridPos, dir);
}
}
// update head local position
if (arrowHead != null) arrowHead.localPosition = GridToLocal(gridPosition);
}
}
// compute local vector for grid coordinates (local to ArrowParent)
private Vector3 GridToLocal(Vector2Int g)
{
return new Vector3(g.x, g.y, 0f);
}
private ArrowBodyPart.Direction GetDirectionForBodySegment(int index)
{
// from = this segment pos, to = preceding pos
Vector2Int from = bodyGridPositions[index];
Vector2Int to = (index == 0) ? gridPosition : bodyGridPositions[index - 1];
Vector2Int delta = to - from;
if (delta == new Vector2Int(0, 1)) return ArrowBodyPart.Direction.Up;
if (delta == new Vector2Int(0, -1)) return ArrowBodyPart.Direction.Down;
if (delta == new Vector2Int(1, 0)) return ArrowBodyPart.Direction.Right;
if (delta == new Vector2Int(-1, 0)) return ArrowBodyPart.Direction.Left;
return bodyParts[index].GetDirection();
}
private void HandleTouch()
{
if (Input.touchCount == 0) return;
Touch touch = Input.GetTouch(0);
if (touch.phase != TouchPhase.Ended) return;
Vector3 worldPoint = Camera.main.ScreenToWorldPoint(touch.position);
Vector2 point2D = new Vector2(worldPoint.x, worldPoint.y);
RaycastHit2D hit = Physics2D.Raycast(point2D, Vector2.zero);
if (hit.collider != null)
{
// if arrowHead has collider and was hit, start movement
if (arrowHead != null && hit.collider.gameObject == arrowHead.gameObject)
{
moveInitialized = true;
}
else
{
foreach (var bp in bodyParts)
{
if (hit.collider.gameObject == bp.gameObject)
{
moveInitialized = true;
break;
}
}
}
}
}
private Vector2Int DirectionToVector(Direction d)
{
switch (d)
{
case Direction.Up: return new Vector2Int(0, 1);
case Direction.Down: return new Vector2Int(0, -1);
case Direction.Left: return new Vector2Int(-1, 0);
case Direction.Right: return new Vector2Int(1, 0);
default: return Vector2Int.zero;
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... ing-gizmos