0

我目前正在开发一个 2D 等距游戏,玩家将能够控制不同的单位,并通过它们进行交互。

我创建了一个名为 UnitType 的 Scriptable Object。多亏了这个系统,我可以定义一个动作范围和一个移动范围,即玩家可以移动到或与之交互的单元格中的最大距离。

问题是我不知道如何通过代码实现这一点。这就是我想要实现的,使用 2 个单元格的动作范围进行演示。 这是目标

和我的一个朋友一起,我们考虑计算这 4 条线的线性方程来检查光线投射是否在它们之内,但它不适用于负 x。 这是目前的系统

最佳做法是什么?

非常感谢您的时间和关注,

4

1 回答 1

0

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");
        }
    }
}
于 2021-02-17T16:27:31.317 回答