Щелкните и перетащите, чтобы создать массив координат, затем сохраните эти координаты и их величину в списке

#unity3d

#unity3d

Вопрос:

Это скрипт c # для unity, который должен (onClick) и (onRelease) сохранять позиции курсора по X и Y в виде плавающих значений, присваивать их массиву [2], вычислять величину между двумя точками…

И вот где я застрял

Мне нужно сохранить эти значения в списке или массиве, который я могу распечатать toString() для отладки, а также сделать эти отдельные координаты доступными для программы.

В идеале я хочу хранить значения, отформатированные следующим образом:

 listOfSavedCoordinates
{
[0] {{X1 , Y1}, {X2 , Y2} , {Magnitude}}
}
  

И чтобы иметь возможность получить к ним доступ, ссылаясь на индекс списка, затем на индексы зубчатого массива.

Вот мой сценарий who на данный момент:

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

public class ClickDrag : MonoBehaviour
{
    public class Coordinate
    {
        public static float X { get => Input.mousePosition.x; }
        public static float Y { get => Input.mousePosition.y; }
        public static float[] XY1 { get; set; }
        public static float[] XY2 { get; set; }
        public static float XY3 { get; set; }
    }

    public class Action
    {
        public static float[] XY1 { get; set; }
        public static float[] XY2 { get; set; }
        public static float[] Magnitude { get; set; }

    }

    [HideInInspector] public float X1;
    [HideInInspector] public float Y1;
    [HideInInspector] public float X2;
    [HideInInspector] public float Y2;
    public static float Magnitude;

//The list I want to save my coordinates and magnitudes to
    List<float[,]> listOfSavedCoordinates = new List<float[,]>();


    public static float CalculateMagnitude(float X2, float X1, float Y2, float Y1)
    {//calculates the distance between 2 X,Y points. Called in OnRelease()
        float Xsqr = (X2 - X1) * (X2 - X1);
        float Ysqr = (Y2 - Y1) * (Y2 - Y1);
        float XYsqr = Xsqr   Ysqr;
        float magnitude = Mathf.Sqrt(XYsqr);
        return magnitude;
    }

    private void SaveCoordsAndMag(float X1, float Y1, float X2, float Y2, float M)
    {//saves action coordinates and magnitude to a list. Called in OnRelease()
        Action.XY1 = new float[2] { X1, Y1 };
        Action.XY2 = new float[2] { X2, Y2 };
        Action.Magnitude = new float[1] { M } ;

        listOfSavedCoordinates.Add(new float[3, 1] { { Action.XY1 }, { Action.XY2 }, { Action.Magnitude } });

        //STACKOVERFLOW: This is the method I want to use to save the elements to my list.
        //the problem is that adding the arrays requires an array initializer even though the values are already arrays,
        //so initializing them makes the array expect a float.
        //Please help thank you
    }

        // Use this for initialization
        void Start()
        {
            Debug.Log("Game Start!");
            Debug.Log("Click and drag the mouse to create vectors");
            Debug.Log("Press M to show previous vectors");


    }

    // Update is called once per frame

    void Update()
    {
        //Inputs
        bool onClick = Input.GetKeyDown(KeyCode.Mouse0);
        bool onDrag = Input.GetKey(KeyCode.Mouse0);
        bool onRelease = Input.GetKeyUp(KeyCode.Mouse0);

        if (onClick == true)
        {//Coordinates for the start point
            X1 = Coordinate.X;
            Y1 = Coordinate.Y;
            Debug.Log("Action Start!");
            Debug.Log(X1   " , "   Y1);
        }

        if (onDrag == true)
        {//Coordinates of the current mouse position
            float X3 = Coordinate.X;
            float Y3 = Coordinate.Y;
            Debug.Log("Action Charging! "   X3   " , "   Y3);
        }

        if (onRelease == true)
        {//Coordinates of the final point
            X2 = Coordinate.X;
            Y2 = Coordinate.Y;
            Debug.Log("Action Released!");
            Debug.Log(X2   " , "   Y2);
            Magnitude = CalculateMagnitude(X2, X1, Y2, Y1);
            Debug.Log("The magnitude is "   Magnitude);
            SaveCoordsAndMag(X1, Y1, X2, Y2, Magnitude);
            Debug.LogWarning(listOfSavedCoordinates.Count   " Actions Saved.");

        }
        if (Input.GetKeyDown(KeyCode.M) == true)
        {
            int xy1 = 0;
            int xy2 = 1;
            int mag = 2;

            listOfSavedCoordinates.ToArray();
            Debug.LogWarning(
                  listOfSavedCoordinates[xy1].ToString()
                  ','
                  listOfSavedCoordinates[xy2].ToString() 
                  " ---> "
                  listOfSavedCoordinates[mag].ToString()
                );
            xy1 = xy1   3;
            xy2 = xy1   1;
            mag = xy2   1;
            //STACKOVERFLOW: This is how I'd like to log my list's elements.
        }
    }
}
  

Ответ №1:

Я разобрался со своей проблемой. Мне нужно было присвоить переменным массива с плавающей запятой моего класса Action их индексную ссылку, чтобы получить фактическое значение.

         listOfSavedCoordinates.Add(new float[3,2] { { Action.XY1[0], Action.XY1[1] }, { Action.XY2[0], Action.XY2[1] }, { Action.Magnitude[0], listOfSavedCoordinates.Count } });
  

Ответ №2:

Вы должны делать что-то вроде этого:

 List<Coordinate> lstCoords = new List<Coordinate>();

// long handing this for understanding

Coordinate coord = new Coordinate();

// assign strongly typed vars in object to values here
coord.X1 = X1;
coord.X2 = X2;
coord.Y1 = Y1;
coord.Y2 = Y2;

// add the object to the list
lstCoords.Add(coord);
  

Тогда доступ к каждому элементу будет примерно таким:

 foreach (Coordinate coord in lstCoords)
{
    console.writeline( coord.X1, coord.X2, coord.y1, coord.y2);
}
  

Вы также можете выполнить поиск конкретной координаты в списке.

Но на самом деле вы хотите использовать список объектов, а не пытаться хранить данные без строго типизированных имен.

Ответ №3:

Я бы посоветовал вам попробовать это:

 public class ClickDrag : MonoBehaviour
{
    List<Coordinates> coordinatesList;

    Vector2 startPos;

    // Use this for initialization
    void Start()
    {
        coordinatesList = new List<Coordinates>();
        // Some other code
    }

    void Update()
    {
        if(Input.GetMouseButtonDown(0))
        {
            startPos = Input.mousePosition;
        }
        else if(Input.GetMouseButtonUp(0))
        {
            // Here create the new coordinates
            Coordinates newCoordinates = new Coordinates(startPos, Input.mousePosition);
            coordinatesList.Add(newCoordinates);
        }

        // Note here you don't need "== true", cause the method will already give you a boolean
        if(Input.GetKeyDown(KeyCode.M))
        {
            DebugList();
        }
    }

    private DebugList()
    {
        Debug.Log("listOfSavedCoordinates: ");
        for(int i=0; i<coordinatesList.Count; i  )
            Debug.Log("[" i "] "   coordinatesList[i].PrintCoordinates());
    }
}

public class Coordinates
{
    private Vector2 startPos;
    private Vector2 endPos;
    private float magnitude;

    public Coordinates(Vector2 startPos, Vector2 endPos)
    {
        this.startPos = startPos;
        this.endPos = endPos;
        magnitude = Vector2.Distance(startPos, endPos);
    }

    public PrintCoordinates()
    {
        return ("{"   startPos   "}, {"   endPos   "}, "   magnitude);
    }
}