简体   繁体   English

我的选择(Raycast)代码出了什么问题

[英]What is wrong with my selection (Raycast) code

I am learning Unity and is trying to convert an XCODE game i have. 我正在学习Unity,并且正在尝试转换我拥有的XCODE游戏。

I have a deck of cards with 61 sprites on top of each other. 我有一副纸牌,上面有61张精灵。

...and I am using Raycast to try to capture the first sprite and I am not able to do that? ...并且我正在使用Raycast尝试捕获第一个精灵,但我无法做到这一点?

I also have a drag function to be able to move the sprite around. 我还有一个拖动功能,可以移动精灵。

I get very strange results: 我得到非常奇怪的结果:

  1. When i click on the top-sprite, the second on top is selected (60 of 61) 当我单击最上面的精灵时,选择了第二个(61个中的60个)
  2. When i then drag (works) the sprite it is the 51th sprite (51 of 61) that is dragged according to the print 当我然后拖动(工作)精灵时,是根据打印拖动的第51个精灵(61之51)

I just do not get my acts together around this "simple" challenge and really need help. 我只是无法围绕这个“简单”的挑战而团结一致,确实需要帮助。 I have been spending quite a few hours on this and tested all kinds of stuff but still ends up with the same problem. 我已经花了好几个小时在上面,并测试了各种东西,但最终还是遇到了同样的问题。 The current code is just the basic to try to sort this out. 当前的代码只是尝试解决该问题的基础。

Script attached to an empty GameObject: 附加到空GameObject的脚本:

void Update() {



if(Input.GetMouseButtonDown(0)) {

        RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);

        print (hit.collider.tag);

    }

}

The "drag" attached to the sprites: 精灵附带的“拖动”:

public class dragTheStuff : MonoBehaviour {



float x;

float y;



void Update() {

    x = Input.mousePosition.x;

    y = Input.mousePosition.y;

}



void OnMouseDrag() {

    // Control the drag of the sprite

    transform.position = Camera.main.ScreenToWorldPoint (new Vector3 (x, y, 1.0f));

    print ("Drag: " + transform.tag);

}

}

When i select the top-sprite manually in the scene the 36th of 61 sprite is selected. 当我在场景中手动选择顶部精灵时,选择了61个精灵中的第36个。 See image: 见图片:

在此处输入图片说明

They all have BoxCollider2D. 他们都有BoxCollider2D。

The 2D Raycast is supposed to be cast along your 2D plane (x,y), but you are trying to get the top element in the Z axis. 2D Raycast应该沿2D平面(x,y)投射,但是您正在尝试获取Z轴的顶部元素。 Switching to the 3D Raycast will not work, because it ignores 2D colliders. 切换到3D Raycast将不起作用,因为它会忽略2D对撞机。

According to MelvMay , a Unity Developer, you should use Physics2D.GetRayIntersection . MelvMay ,一个团结开发者,你应该使用Physics2D.GetRayIntersection

I'm not sure why your OnMouseDrag() and manually clicking is not working, but maybe your sprites are not in the correct Z order or don't have one at all. 我不确定为什么您的OnMouseDrag()和手动单击不起作用,但是您的子画面可能没有正确的Z顺序或根本没有。 If they all have the same Z position, it would just be random which sprite you will select. 如果它们都具有相同的Z位置,那将是随机的,您将选择哪个精灵。

If you are using the Unity default settings for a 2D game, your Z axis will be positive pointing into the game, so that cards at the bottom of the stack should have a higher Z value than the card on top. 如果您使用2D游戏的Unity默认设置,则您的Z轴将正指向游戏,因此,堆栈底部的卡的Z值应高于顶部的卡。

In your OnMouseDrag() method you are setting Z to 1 while calling Camera.ScreenToWorldPoint . OnMouseDrag()方法中,在调用Camera.ScreenToWorldPoint将Z设置为1。 The Z position is in world units from the camera, so if your camera is at Z = -10 (default value), the resulting Z value will be -10 + 1 = -9 . Z位置是以相机的世界单位为单位,因此,如果相机的位置为Z = -10 (默认值),则Z值的最终值为-10 + 1 = -9 It would probably be better to ignore the resulting Z value and use only X and Y to update your card. 最好忽略产生的Z值,而仅使用X和Y来更新卡。

I think you may have a problem with your raycast. 我认为您的光线投射可能有问题。 Looking at the documentation , The second parameter is supposed to be direction, but you have Vector2.zero there. 查看文档 ,第二个参数应该是direction,但是那里有Vector2.zero So I'm guessing your logic is that since it's a 2D raycast, direction of zero would put it directly towards the 2D plane? 所以我猜您的逻辑是,由于它是2D光线投射,零方向会将其直接指向2D平面吗? I'm thinking that function may be intended to be used for casts along the 2D plane only and doesn't work that way. 我认为该功能可能只打算用于2D平面上的投射,而不能那样工作。

You should try Physics2D.GetRayIntersection , it might be more suited for your case. 您应该尝试Physics2D.GetRayIntersection ,它可能更适合您的情况。 Ray with a direction (0, 0, 1) should work there. 方向为(0, 0, 1) 0,0,1)的射线应该在那里工作。

I finally solved this problem. 我终于解决了这个问题。 The test project is using this code: 测试项目正在使用以下代码:

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

public class EGOScript : MonoBehaviour {

public static List<string> cardDeckList = new List<string> {
    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",
    "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26",};

public GameObject theGameObject;
float ff = 0f;
public float addIT = 0.2f;
int counter;
public static int zOffset = 0;
public static float zSelect = 26;
public static int zSelectInt = 26;






// Use this for initialization
void Start () {

    counter = 0;
    zOffset = 26;

    print (cardDeckList.Count);

    for (int z = 0; z < 26; z++) {

        theGameObject = Resources.Load(cardDeckList[z]) as GameObject;
        theGameObject.transform.position =  new Vector3(0f + ff, 0f + ff, zOffset);
        theGameObject.renderer.sortingOrder = counter;
        Instantiate(theGameObject);

        ff = ff + addIT;

        counter++;
        zOffset--;
    }
}

// Update is called once per frame
void Update () {
    if(Input.GetMouseButtonDown(0)) {
        //RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);

        Vector3 worldPoint = Camera.main.ScreenToWorldPoint( Input.mousePosition );
        worldPoint.z = Camera.main.transform.position.z;
        Ray ray = new Ray( worldPoint, new Vector3( 0, 0, 1 ) );
        RaycastHit2D hit = Physics2D.GetRayIntersection( ray );

        zSelect++;
        zSelectInt++;

        if(hit.collider != null) {
            //print (hit.collider.tag);
            //zSelect = hit.collider.transform.position.z;

            Vector3 z3 = hit.collider.transform.position;

            z3.z = zSelect;

            hit.collider.transform.position = z3;
            hit.collider.renderer.sortingOrder = zSelectInt;

            print (hit.collider.transform.position + " + " + zSelectInt);
        }
    }
}
}


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

public class DragScript : MonoBehaviour {

float x;
float y;
float z;


// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {
    x = Input.mousePosition.x;
    y = Input.mousePosition.y;
}

void OnMouseDrag() {

    // Control the drag of the sprite
    transform.position = Camera.main.ScreenToWorldPoint (new Vector3 (x, y, EGOScript.zSelect));
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM