问题描述
我目前正在开发一款 2D 等距游戏,玩家将能够控制不同的单位,并通过它们进行交互。
我创建了一个名为 UnitType 的可编写脚本的对象。多亏了这个系统,我可以定义一个动作范围和一个移动范围,即玩家可以移动到或与之交互的单元格中的最大距离。
问题是我不知道如何通过代码实现这一点。这就是我想要实现的,使用 2 个单元格的动作范围进行演示。 This is the goal
和我的一个朋友一起,我们考虑计算这 4 条线的线性方程,以检查光线投射是否在其中,但它不适用于负 x。 This is the current system
最佳做法是什么?
非常感谢您的时间和关注,
解决方法
Mousehit 是一个 Unity 游戏对象,它是角色的孩子。由于 mousePosition 是一个附加到 GameManager 的脚本,所以它的位置被绑定到了 tilemap 单元的中心。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class Interact : MonoBehaviour
{
[SerializeField] private Sprite upperLeft,upperRight,midLeft,midRight,bottomLeft,bottomMid,bottomRight;
[SerializeField] private GameObject mouseHit;
public UnitType unitType;
private GameObject gameManager;
private CheckMousePosition mousePosition;
private bool isInteracting,isAtGoodDistance;
private SpriteRenderer spriteRenderer;
private Tilemap tilemap;
private RaycastHit2D hit;
//private Transform mouseHit;
void Start()
{
tilemap = GameObject.Find("Tilemap").GetComponent<Tilemap>();
gameManager = GameObject.FindGameObjectWithTag("GameManager");
mousePosition = gameManager.GetComponent<CheckMousePosition>();
spriteRenderer = gameObject.GetComponent<SpriteRenderer>();
isInteracting = false;
mouseHit.SetActive(false);
}
// Update is called once per frame
void Update()
{
if (isInteracting)
{
mouseHit.SetActive(true);
mouseHit.transform.position = new Vector3(mousePosition.tilemap.GetCellCenterLocal(mousePosition.cellPosition).x,mousePosition.tilemap.GetCellCenterLocal(mousePosition.cellPosition).y,1);
if (Input.GetMouseButtonDown(0))
{
Interaction();
}
}
if (isInteracting == false)
{
spriteRenderer.sprite = null;
mouseHit.SetActive(false);
}
}
public void InitInteraction()
{
isInteracting = true;
transform.root.GetComponent<ContextualMenu>().CloseContextualMenu();
}
private void Interaction()
{
//When the player interacts,we cast a ray that will determine what he is interacting with.
hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition),Vector2.zero);
if (hit.collider != null)
{
if (isInteracting)
{
isInteracting = false; //the player is no longer interacting.
//If the player is interacting with a farmable cell using the worker.
if (transform.root.name == "Worker"
&& hit.collider.GetComponent<FarmableCell>() != null)
{
CheckInteractionDistance();
//hit.collider.GetComponent<FarmableCell>().CheckIfFarmed();
}
}
}
}
private void CheckInteractionDistance()
{
if (mouseHit.transform.localPosition.y <= (-0.5 * (mouseHit.transform.localPosition.x) + unitType.actionDistance / 2)
&& mouseHit.transform.localPosition.x >= (-0.5 * (mouseHit.transform.localPosition.x) - unitType.actionDistance / 2)
&& mouseHit.transform.localPosition.x >= (0.5 * (mouseHit.transform.localPosition.x) - unitType.actionDistance / 2)
&& mouseHit.transform.localPosition.x <= (0.5 * (mouseHit.transform.localPosition.x) + unitType.actionDistance / 2))
{
Debug.Log("ok");
}
else
{
Debug.Log("not ok");
}
}
}