选择移动游戏对象的困难

时间:2015-12-14 21:36:24

标签: c# vector unity3d physics

我正在开发一款带触控功能的手机游戏。我可以非常容易地选择一个不动的游戏对象并且它会响应,但是当它移动时很难选择它,因为它很小(例如,它是基于所有物理的)。有没有办法增加游戏对象的触摸半径,以便更容易按下它,还是有其他解决方案?

 private void Update() {
    //User input (touches) will select cubes
    if(Input.touchCount > 0) {
        Touch touch = Input.GetTouch(0);
    }
    Touch[] touches = Input.touches;

    foreach(var touchInput in touches) {
        RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint((Input.GetTouch(0).position)), Vector2.zero);

        if (hit.collider != null) {
            selectedCube = hit.collider.gameObject;
            selectedCube.GetComponent<SpriteRenderer>().color = Color32.Lerp(defaultColor, darkerColor, 1);
        }

    }
}

1 个答案:

答案 0 :(得分:2)

而不是增加对象的对撞机大小(你在评论中讨论过),如何以相反的方式接近它?使用Physics2D.CircleCast

检查触摸周围的区域是否有碰撞而不是单点
private void Update() {
    //User input (touches) will select cubes
    if(Input.touchCount > 0) {
        Touch touch = Input.GetTouch(0);
    }
    Touch[] touches = Input.touches;

    foreach(var touchInput in touches) {
        float radius = 1.0f; // Change as needed based on testing
        RaycastHit2D hit = Physics2D.CircleCast(Camera.main.ScreenToWorldPoint((Input.GetTouch(0).position)), radius, Vector2.zero);

        if (hit.collider != null) {
            selectedCube = hit.collider.gameObject;
            selectedCube.GetComponent<SpriteRenderer>().color = Color32.Lerp(defaultColor, darkerColor, 1);
        }

    }
}

请注意,如果您有大量可选择的对象相互冲洗,这将不会很好......但是,在这种情况下增加对撞机大小也无济于事。 (我只是说增加对象大小。无法以其他方式提高用户准确性。或允许多选,并使用Physics2D.CircleCastAll)。

希望这有帮助!如果您有任何问题,请告诉我。

编辑:为了获得更好的准确性,由于Physics2D.CircleCast返回的“第一”结果可能是任意选择的,因此您可以使用Physics2D.CircleCastAll来获取触摸中的所有对象半径,并且只选择最接近原始触摸点的那个:

private void Update() {
    //User input (touches) will select cubes
    if(Input.touchCount > 0) {
        Touch touch = Input.GetTouch(0);
    }
    Touch[] touches = Input.touches;

    foreach(var touchInput in touches) {
        float radius = 1.0f; // Change as needed based on testing
        Vector2 worldTouchPoint = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position);
        RaycastHit2D[] allHits = Physics2D.CircleCastAll(worldTouchPoint, radius, Vector2.zero);

        // Find closest collider that was hit
        float closestDist = Mathf.Infinity;
        GameObject closestObject = null;
        foreach (RaycastHit2D hit in allHits){

            // Record the object if it's the first one we check,
            // or is closer to the touch point than the previous
            if (closestObject == null ||
                Vector2.Distance(closestObject.transform.position, worldTouchPoint) < closestDist){
                closestObject = hit.collider.gameObject;
                closestDist = Vector2.Distance(closestObject.transform.position, worldTouchPoint);
            }
        }

        // Finally, select the object we chose based on the criteria
        if (closestObject != null) {
            selectedCube = closestObject;
            selectedCube.GetComponent<SpriteRenderer>().color = Color32.Lerp(defaultColor, darkerColor, 1);
        }
    }
}