如何在Unity中单击时从十六进制地图获取坐标

时间:2019-04-25 04:21:37

标签: c# unity3d gameobject hexagonal-tiles

我正在将棋盘游戏称为Hex。当我单击一个图块时,它变为蓝色或黄色,但是我还需要知道该图块的坐标是什么。

我不能使用...

rend.transform.position;

...因为我要接收的坐标类似于此(0,0)位于左下角,而其上方是(0,1): enter image description here

控制台中的坐标是我需要接收的坐标。

enter image description here

在生成十六进制图时,我使用列和行变量将其打印出来:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class HexMap : MonoBehaviour
{
 // Use this for initialization
 void Start()
 {
    GenerateMap();
 }

public GameObject HexPrefab;

public void GenerateMap()
{
    for (int column = 0; column < 11; column++)
    {
        for (int row = 0; row < 11; row++)
        {
            // Instantiate a Hex
            Hex h = new Hex(column, row);

            Instantiate(HexPrefab, h.Position(), Quaternion.identity, this.transform);

            Debug.Log(column + "," + row);
        }
    }
}
}

当我在此处使用此脚本单击十六进制图块时,我希望能够获得坐标:

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using UnityEngine;
using UnityEngine.Networking;

public class ColorChange : MonoBehaviour {

public Color[]colors; // allows input of material colors in a set sized array
public SpriteRenderer rend;  // what are we rendering? the hex

public enum Player {ONE, TWO};
public static Player currentPlayer = Player.ONE;

// Use this for initialization
void Start () {
    rend = GetComponent<SpriteRenderer> (); // gives functionality for the renderer
}

void NextPlayer() {

   if( currentPlayer == Player.ONE ) {
      currentPlayer = Player.TWO;
   }
   else if( currentPlayer == Player.TWO) {
      currentPlayer = Player.ONE;
   }
}

// Update is called once per frame
void OnMouseDown () {
    // if there are no colors present nothing happens
    if (colors.Length == 0)
        return;

    if (currentPlayer == Player.ONE)
        rend.color = colors [0];
    else if (currentPlayer == Player.TWO)
        rend.color = colors [1];

    NextPlayer();
}

这是我用来确定十六进制图块在哪里的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Hex{

public Hex (int q, int r){
    this.Q = q;
    this.R = r;
}

public readonly int Q; // x
public readonly int R;  // y

static readonly float WIDTH_MULTIPLIER = Mathf.Sqrt(3) / 2;

public Vector2 Position(){
    float radius = 0.513f;
    float height = radius * 2;
    float width = WIDTH_MULTIPLIER * height;

    float vert = height * 0.75f;
    float horiz = width;

    return new Vector2(horiz * (this.Q - this.R/2f), vert * this.R);
}
}

我当时想我需要能够在实例化每个十六进制模型时为其指定行和列的值,但是我不确定如何做到这一点。我尝试了几种在网上以及使用GetComponent时发现的解决方案,但无法使其正常工作。 如果有人对如何实现这一想法有所了解,我将不胜感激!

1 个答案:

答案 0 :(得分:1)

在您的情况下GetComponent无法正常工作的原因是,坐标脚本位于十六进制预制的子对象上。您可以通过调用GetComponentInChildren访问子对象上的组件。看起来类似于以下内容:

// Instantiate a Hex
Hex h = new Hex(column, row);

// Instantiate the prefab
GameObject instance = Instantiate(HexPrefab, h.Position(), Quaternion.identity, this.transform);

// Let's find the coorinates component on the hex prefab instance.
Coordinates coordinates = instance.GetComponentInChildren<Coordinates>();

// now you may assign the column and row values to it
// ...

有很多解决此问题的方法。但是只要记住组件在预制层级中的哪个位置,就可以了。