Как проверить возможные коллизии с помощью штуковинC#

Место общения программистов C#
Ответить
Anonymous
 Как проверить возможные коллизии с помощью штуковин

Сообщение Anonymous »

Я делаю клон игры "Arrow Out". Я не уверен, что это вообще правильный путь, но я подумываю использовать штуковины, чтобы проверить, есть ли еще одна стрелка на пути нажатой стрелки. Прямо сейчас стрелки работают так, как ожидалось, но я хочу, чтобы нажатая кнопка находилась на своем месте, если на ее пути есть еще одна стрелка. Как мне это сделать? Сценарий стрелки выглядит следующим образом:

Код: Выделить всё

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;
}
}
}
Я понял, что стрелки следуют за движением змеи из аркадной игры Snake, поэтому я реализовал движение стрелок с помощью сетки. Если вы считаете, что есть лучший способ, предложите, пожалуйста!

Подробнее здесь: https://stackoverflow.com/questions/798 ... ing-gizmos
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»