Trình chỉnh sửa trò chơi - Khi màn hình được nhấp, làm thế nào để bạn xác định đối tượng nào được nhấp?


7

Tôi đang cố gắng tạo Trình chỉnh sửa trò chơi, hiện chỉ đặt các loại Hình dạng khác nhau và như vậy. Tôi đang làm điều này trong Windows Forms trong khi vẽ 3D bằng XNA. Vì vậy, nếu tôi có một vài Hình dạng trên màn hình và tôi nhấp vào màn hình tôi muốn có thể xác định "đối tượng" nào trong số các đối tượng bạn đã nhấp.

Phương pháp tốt nhất cho việc này là gì? Vì có hai vật thể nằm phía sau vật thể khác, nó sẽ có thể nhận ra vật thể ở phía trước chứ không phải vật thể phía sau nó và nếu tôi xoay máy ảnh và nhấp vào vật thể phía sau nó - nó sẽ xác định nó chứ không phải vật thể đầu tiên.

Có cách nào thông minh để đi về điều này?


6
Quá trình xác định đối tượng nào đã được nhấp vào thường được gọi là 'chọn'. Một số Google tìm kiếm thứ gì đó như 'chọn xna' sẽ cung cấp cho bạn một số kết quả hữu ích.
Gyan aka Gary Buyn

Câu trả lời:


2

Trong video này tôi chỉ ra cách thực hiện với mã ... hình chiếu / khung nhìn là đẳng cự, nhưng tất cả các calcs đều được thực hiện trong 3D ...

http://www.youtube.com/watch?v=axHp1f3RlHM

Khi tôi tính toán tia chuột, tôi kiểm tra va chạm với mặt phẳng ... nhưng quy trình này là tương tự để kiểm tra danh sách các ràng buộc liên quan đến các đối tượng của bạn.

Thuật toán nên tương tự như sau:

1. Calculate mouse ray
2. for every object
3.     check if ray intersecs with it
4.         if does then save the object and the distance in a sorted list by distance
5. choose from sorted list the nearest object.

Ví dụ của bạn là khá nhiều những gì tôi đang tìm kiếm, có lẽ không phải là Isometric. Làm thế nào để bạn kết xuất Grid đó và Outline of a Cube? Cần một cái gì đó tương tự để kiểm tra vị trí của con chuột trong Không gian 3D.
Deukalion

Tôi sử dụng một lớp riêng để vẽ các đường ... rất dễ thực hiện thông qua câu này GraphicsDevice.DrawUserPrimologists <VertexPocationColor> (PrimitiveType.LineList, data.Vertices, 0, data.Index / 2);
Blau

Vâng, tôi đã thử một cái gì đó tương tự nhưng tôi không thể làm cho nó hoạt động. Tôi sử dụng một phương pháp toán học cho việc này, nhưng sự hiểu biết của tôi về phương pháp này không như tôi nghĩ. Câu hỏi của tôi về điều này: gamedev.stackexchange.com/questions/31424/ Khăn
Deukalion

Đây là mã để vẽ nó pastebin.com/YpCKAHcF rất dễ dàng ... chỉ vẽ các đường dọc và ngang
Blau

Bạn gọi DrawLine3D, nhưng không có mã của nó. Có phải đó chỉ là DrawUserPrimologists (LineList, Data.Vertices, 0, data.Index / 2)? dữ liệu. Index / 2 là gì?
Deukalion

9

Điều đầu tiên bạn cần nắm bắt tốt là chuyển đổi các điểm 3D thành tọa độ màn hình 2D và quay lại. Dưới đây là một vài câu trả lời tôi đã đưa ra về chủ đề đó; Hiểu 3D sang màn hình , 3D sang 2D .

Bây giờ, để chuyển từ tọa độ chuột của bạn thành 2D sang 3D, bạn cần thực hiện chuyển đổi 3D sang 2D. Điều này khá đơn giản.

Một tọa độ đối tượng / cục bộ được chuyển thành không gian màn hình bằng cách nhân nó với ma trận thế giới (lấy tọa độ thế giới), sau đó bằng ma trận xem (tạo thế giới tọa độ tương đối với máy ảnh) và sau đó là ma trận chiếu (lấy tọa độ màn hình) .

Làm điều này ngược là dễ dàng. Đảo ngược tất cả các ma trận. Sau đó nhân với phép chiếu ngược, sau đó là ma trận khung nhìn ngược. Bây giờ, bạn sẽ không có tọa độ 3D cho chuột. Lý do là vì bạn đã thiếu một thứ nguyên của dữ liệu. Vì vậy, những gì bạn có là một tia thay thế. Nhưng đó là tốt. Tia sẽ có tọa độ xác định và sẽ được chỉ cùng hướng với camera nhìn vào vectơ. Bạn cũng có thể nhận thấy rằng bạn không cần phải đảo ngược ma trận thế giới cho bất kỳ đối tượng nào. Đó chỉ là vì bạn không thực sự muốn tia trong không gian vật thể / cục bộ, không có điểm nào, có lẽ bạn cũng có khối lượng va chạm của mình được xác định trong không gian thế giới.

Bây giờ tất cả những gì bạn phải làm là kiểm tra giao điểm hình tròn / hộp / đa tia để tìm ra nếu tia giao nhau với một đối tượng.

Tìm tất cả các đối tượng được giao nhau và giữ một danh sách. Sau đó tính toán khoảng cách của từng đối tượng từ camera. Cái gần camera nhất là cái mà người dùng muốn chọn.

Đây là mã bạn sẽ cần để làm điều này trong XNA. Giải pháp này cũng sẽ hoạt động cho các loại dự án khác (miễn là bạn chuyển đổi nó trước). Nếu bạn chỉ hiển thị các họa tiết 2D thì có lẽ bạn không sử dụng ma trận chiếu, vì vậy chỉ cần sử dụng hàm Matrix.Identity.

using System;
using Microsoft.Xna.Framework;

namespace FluxPrototype
{
    /// <summary>
    /// Contains functions useful in working with XNA Vectors.
    /// </summary>
    static class VectorHelper
    {
        /// <summary>
        /// Converts a Vector2 position into a 3D ray.
        /// </summary>
        /// <param name="Position">The 2D position.</param>
        /// <param name="View">The view matrix for the camera.</param>
        /// <param name="Projection">The projection matrix for the camera.</param>
        /// <param name="Point">The returned point defining part of the 3D ray.</param>
        /// <param name="Direction">The direction of the 3D ray.</param>
        public static void Unproject(Vector2 Position, Matrix View, Matrix Projection, out Vector3 Point, out Vector3 Direction)
        {
            if (Position == null)
                Position = Vector2.Zero;

            // Create two 3D points from the position. The first one we will return.
            Point = new Vector3(Position, 0);
            Vector3 Point2 = new Vector3(Position, 1);

            // Transform the points.
            Matrix InvertedProjection = Matrix.Invert(Projection);
            Point = Vector3.Transform(Point, InvertedProjection);
            Point2 = Vector3.Transform(Point2, InvertedProjection);

            Matrix InvertedView = Matrix.Invert(View);
            Point = Vector3.Transform(Point, InvertedView);
            Point2 = Vector3.Transform(Point2, InvertedView);

            // Use the difference between the points to define the ray direction.
            // This will only be the camera direction if the view frustum is orthographic.
            Direction = (Point2 - Point);
            Direction.Normalize();
        }
    }
}

Đồng ý. Tôi sẽ xem xét nó. Quan tâm để giải thích làm thế nào để đảo ngược ma trận? Tôi không biết làm thế nào.
Deukalion

1
Matrix InvertedView = Matrix.Invert (Xem);
OriginalDaemon

Phương pháp này có hiệu quả khi đặt công cụ lên Trình chỉnh sửa không? Vì điều đó "quan trọng" hơn là chọn chúng. Nói nếu tôi muốn thêm một khối vào màn hình tôi nhấp vào nơi tôi muốn - phương pháp này có hỗ trợ điều đó không?
Deukalion

Điều này theo như tôi đã đến và tôi không chắc liệu nó có đúng không: Vector2 screenPocation = new Vector2 (PointToClient (MousePocation) .X, PointToClient (MousePocation) .Y); Ma trận m = screenPocation * matrix.Invert (Camera.MatrixWorld) * Matrix.Invert (Camera.MatrixView) * Matrix.Invert (Camera.MatrixWorld);
Deukalion

... và tôi tạo Ma trận (trong lớp Máy ảnh của mình) theo cách này: matrix_world = Matrix.CreateRotationZ (MathHelper.ToRadians (world_rotation.Z)) * Matrix.CreateRotationY (MathHelper.ToRadians (world_rotation.Y) (MathHelper.ToRadians (world_rotation.X)) * Matrix.CreateTranslation (world_location) * Matrix.CreateScale (world_zoom); matrix_view = Matrix.CreateLookAt (view_poseition, view_lookat, Vector3.Up); matrix_projection = Matrix.CreatePers perspectiveFieldOfView (chiếu_fieldofview, chiếu_aspectratio, chiếu_clipstart, chiếu_clipend);
Deukalion

2

Thông thường, tôi sẽ chỉ tạo ra một âm lượng giới hạn từ con chuột của tôi. Nguồn gốc là nơi tôi nhấp. Sau đó, hoàn thành một bài kiểm tra giao nhau bằng cách lặp tất cả các đối tượng. Sau đó, sắp xếp danh sách bạn nhận lại dựa trên tiêu chí bạn muốn và chọn phần tử 0.


Tôi hiểu rồi Nhưng làm thế nào để tôi làm với giá trị Z? Hoặc độ sâu, bởi vì nếu tôi chỉ nhấp vào màn hình, tôi nhận được tọa độ X, Y và sau đó có thể tương ứng với một điểm trong Thế giới 3D nơi tôi nhấp, nhưng giá trị độ sâu tôi không nhận được. Làm thế nào "gần" với máy ảnh là nó hoặc bao xa?
Deukalion

1

Một ý tưởng tôi đã xem xét nhưng chưa thử:

Vẽ một hình ảnh ngoài màn hình giống như hình ảnh thật nhưng không có họa tiết, v.v. Chỉ cần vẽ các đối tượng của bạn, mỗi đối tượng trong một "màu" khác nhau trong đó "màu" thực sự chỉ là một số đối tượng. Để tìm ra những gì bên dưới con chuột, bạn chỉ cần nhìn vào màu của pixel trên hình ảnh thay thế.

Tất nhiên điều này đang làm rất nhiều việc lãng phí nhưng đó là GPU làm việc đó chứ không phải CPU và chắc chắn sẽ giải quyết mọi việc theo chính xác các quy tắc.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.