Unity游戏鼠标拾取、放下物体

本文介绍了在Unity游戏中如何通过添加标签、启用rigidbody和collider组件来实现对象的拾取和放下功能。开发者在Update方法中处理鼠标事件,确保对象只能被带有pickedObject标签的游戏物体拾取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于拾取、放下游戏物体,要先在游戏物体上加入标签tag,这里我统一将可以拾取的物体标志为pickedObject。然后对游戏添加rigidbody、collider组件,只有这三步都做到才可以拾取物体。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class pick : MonoBehaviour
{
    private float smooth=10;
    private float depth=0.5f;
    Transform currentObject;
    Vector3 mouse3DPosition;
    //public Text lifeText;
    //手机UI界面
    public GameObject smartphoneUI;
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            if (currentObject == null)
            {
                Ray rays = Camera.main.ScreenPointToRay(Input.mousePosition);
                Debug.DrawRay(rays.origin, rays.direction * 100, Color.yellow);
                RaycastHit hit;
                if (Physics.Raycast(rays, out hit))
                {//将创建的射线投射出去并将反馈信息存储到hit中
                    if (hit.collider.gameObject.tag == "pickedObject")
                    {
                        
                        
                        currentObject = hit.transform;
                        currentObject.gameObject.SetActive(false);
                    }     //获取被射线碰到的对象transform变量
                }

            }
            else
            {
                
                currentObject.gameObject.SetActive(true);
                Vector3 mp = Input.mousePosition;
                mp.z = depth;
                mouse3DPosition = Camera.main.ScreenToWorldPoint(mp);
                currentObject.position = Vector3.Lerp(currentObject.position, mouse3DPosition, smooth );
                currentObject = null;
            }
        }

    }
}

### 实现网络同步拾取物体 为了在网络环境中实现物品的拾取和丢弃操作,Unity Mirror 提供了一套完整的解决方案来处理这些互动行为。考虑到 Mirror 不支持对象层次结构中的多个 `NetworkIdentity` 组件[^1],因此设计时需特别注意这一点。 #### 设计思路 - **物品管理**:创建一个独立于玩家角色的对象池用于存储所有的可拾起物项实例。 - **状态同步**:利用 `Cmd` 和 `Rpc` 方法确保服务器端能够控制重要逻辑并及时通知所有客户端更新界面显示。 - **交互检测**:基于射线投射技术判断鼠标指针所指向的具体位置及其上是否有符合条件的目标存在;当满足条件时触发相应的动作执行流程。 #### 关键代码片段 定义一个继承自 MonoBehaviourPun 的类作为基底模板: ```csharp using UnityEngine; using Mirror; public class PickupableObject : NetworkBehaviour { private bool isHeld = false; // 是否被持有标志位 void Update() { if (!isLocalPlayer) return; // 只允许本地玩家进行操作 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hitInfo; if (Physics.Raycast(ray, out hitInfo)) { var pickupableObj = hitInfo.collider.GetComponent<PickupableObject>(); if (pickupableObj != null && Input.GetKeyDown(KeyCode.E)) { // E 键拾取 CmdTryPickUp(pickupableObj.gameObject); } } if(isHeld && Input.GetKeyUp(KeyCode.X)){// X 键放下 CmdDrop(); } } [Command] public void CmdTryPickUp(GameObject obj){ RpcSetParent(obj.transform); } [ClientRpc] void RpcSetParent(Transform parentTransform){ transform.SetParent(parentTransform); isHeld=true; } [Command] public void CmdDrop(){ RpcResetParent(); } [ClientRpc] void RpcResetParent(){ transform.SetParent(null); isHeld=false; } } ``` 此脚本实现了基本的拾取/放置功能,并通过命令方法 (`Cmd`) 来保证只有经过授权的操作才会生效,而远程过程调用(`Rpc`)则用来广播最新的变化给其他玩家知晓[^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值