You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现将游戏对象传送到玩家点击的屏幕位置?

游戏对象点击屏幕传送的实现方法

下面分主流游戏引擎给你讲具体实现方式,核心思路都是检测屏幕点击→转换屏幕坐标到世界坐标→将目标对象移动到该坐标,不同引擎的API略有差异:

Unity(C#)

  1. 给要处理逻辑的GameObject挂一个脚本,比如TeleportOnClick
  2. 在脚本里绑定要传送的对象和主相机,然后在Update里检测鼠标点击:
using UnityEngine;

public class TeleportOnClick : MonoBehaviour
{
    public GameObject objectToTeleport; // 拖拽要传送的对象到这里
    public Camera mainCamera; // 拖拽主相机到这里,默认也可以用Camera.main

    void Update()
    {
        // 检测左键按下
        if (Input.GetMouseButtonDown(0))
        {
            // 从相机发射射线到点击位置
            Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out RaycastHit hitInfo))
            {
                // 把对象移到射线击中的位置(比如地面)
                objectToTeleport.transform.position = hitInfo.point;
            }
        }
    }
}

注意:

  • 要确保地面或你想点击的平面有Collider组件,射线才能检测到
  • 如果是2D游戏,把Physics.Raycast换成Physics2D.Raycast,用2D碰撞体

Unreal Engine(C++/蓝图)

蓝图实现

  1. 打开PlayerController的蓝图,在BeginPlay里绑定鼠标左键输入到自定义事件
  2. 自定义事件里做以下操作:
    • 用Deproject Screen to World把屏幕坐标转成世界射线
    • 用Line Trace By Channel做射线检测,获取击中位置
    • 调用Set Actor Location把目标对象移到该位置

C++实现

#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "TeleportController.generated.h"

UCLASS()
class YOURPROJECT_API ATeleportController : public APlayerController
{
    GENERATED_BODY()

protected:
    virtual void BeginPlay() override;

private:
    UFUNCTION()
    void OnLeftClick();

    UPROPERTY(EditAnywhere, Category = "Teleport")
    AActor* TargetObject; // 在Details面板选要传送的对象
};
#include "TeleportController.h"
#include "Kismet/GameplayStatics.h"

void ATeleportController::BeginPlay()
{
    Super::BeginPlay();
    // 绑定鼠标左键输入(要先在Project Settings的Input里加LeftMouseButton映射)
    InputComponent->BindAction("LeftMouseButton", IE_Pressed, this, &ATeleportController::OnLeftClick);
}

void ATeleportController::OnLeftClick()
{
    FVector2D MousePos;
    if (GetMousePosition(MousePos.X, MousePos.Y))
    {
        FVector WorldLoc, WorldDir;
        DeprojectScreenPositionToWorld(MousePos.X, MousePos.Y, WorldLoc, WorldDir);

        FHitResult Hit;
        // 射线检测,长度1000单位,可按需调整
        GetWorld()->LineTraceSingleByChannel(Hit, WorldLoc, WorldLoc + WorldDir * 1000, ECC_Visibility);

        if (Hit.bBlockingHit && TargetObject)
        {
            TargetObject->SetActorLocation(Hit.Location);
        }
    }
}

Godot(GDScript)

3D场景

extends Node3D

@onready var teleport_target = $TeleportTarget # 引用要传送的对象
@onready var main_camera = $Camera3D

func _input(event):
    # 检测左键点击
    if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
        # 获取射线的起点和方向
        var ray_origin = main_camera.project_ray_origin(event.position)
        var ray_dir = main_camera.project_ray_normal(event.position)
        
        # 射线检测,检测范围1000单位
        var space_state = get_world_3d().direct_space_state
        var hit_result = space_state.intersect_ray(Ray3D(ray_origin, ray_dir * 1000))
        
        if hit_result:
            # 移动对象到击中位置
            teleport_target.global_position = hit_result.position

2D场景(更简单)

extends Node2D

@onready var teleport_target = $TeleportTarget

func _input(event):
    if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
        # 直接获取鼠标全局位置,赋值给对象
        teleport_target.global_position = get_global_mouse_position()

通用注意点:

  • 如果不需要检测地面,只是传送到点击的屏幕对应的世界坐标(比如空中),可以跳过射线检测,直接用坐标转换后的位置
  • 可以给传送加个动画或者粒子效果,提升体验

内容的提问来源于stack exchange,提问作者pokefalle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 11:40:38