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

时间:2014-04-13 18:45:03

标签: c# unity3d raycasting

我正在学习Unity并正在尝试转换我拥有的XCODE游戏。

我有一副卡片,上面有61个精灵。

...我正在使用Raycast尝试捕获第一个精灵,我无法做到这一点?

我还有一个拖动功能,可以移动精灵。

我得到了非常奇怪的结果:

  1. 当我点击顶级精灵时,选择了第二个顶部(61个中的60个)
  2. 当我然后拖动(工作)精灵时,它是根据打印拖动的第51个精灵(61个中的51个)
  3. 我只是不能围绕这个“简单”挑战采取行动并真正需要帮助。我已经花了相当多的时间来测试各种各样的东西,但仍然会遇到同样的问题。目前的代码只是尝试对其进行排序的基础。

    附加到空GameObject的脚本:

    void Update() {
    
    
    
    if(Input.GetMouseButtonDown(0)) {
    
            RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
    
            print (hit.collider.tag);
    
        }
    
    }
    

    附加在精灵上的“拖拽”:

    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);
    
    }
    
    }
    

    当我在场景中手动选择顶级精灵时,选择了61个精灵的第36个。见图:

    enter image description here

    他们都有BoxCollider2D。

3 个答案:

答案 0 :(得分:1)

2D Raycast应该沿着你的2D平面(x,y)投射,但是你试图获得Z轴的顶部元素。切换到3D Raycast不起作用,因为它忽略了2D碰撞器。

根据Unity开发人员MelvMay,您应该使用Physics2D.GetRayIntersection

我不确定为什么你的OnMouseDrag()并且手动点击不起作用,但是你的精灵可能没有正确的Z顺序或根本没有。如果它们都具有相同的Z位置,那么您选择的精灵就是随机的。

如果您正在使用Unity游戏的Unity默认设置,那么您的Z轴将正向指向游戏,因此堆栈底部的卡片应具有比顶部卡片更高的Z值。

OnMouseDrag()方法中,您在调用Camera.ScreenToWorldPoint时将Z设置为1。 Z位置是相机的世界单位,因此如果您的相机处于Z = -10(默认值),则生成的Z值将为-10 + 1 = -9。忽略生成的Z值并仅使用X和Y来更新卡片可能会更好。

答案 1 :(得分:0)

我认为你的光线投射可能有问题。查看documentation,第二个参数应该是方向,但那里有Vector2.zero。所以我猜你的逻辑是因为它是2D光线投射,零方向会直接将它放到2D平面上吗?我认为该功能可能仅用于2D平面上的演员表,并且不会那样工作。

您应该尝试Physics2D.GetRayIntersection,它可能更适合您的情况。方向为(0, 0, 1)的Ray应该在那里工作。

答案 2 :(得分:0)

我终于解决了这个问题。测试项目正在使用此代码:

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));
}
}