在为 HTC VIVE 进行 Unity 工作时如何将一个对象粘贴到另一个对象位置

2024-04-01

我想创建一个场景,其中电线(子级)进入套接字(父级),然后电线成为父级的子级,并且它的位置与父级固定,即使我移动父级,电线也应该随之移动用它。

该项目基于unity3D FOR HTC Vive。我已经使用 ontriggerenter 事件来检查碰撞器并将子级的位置设置为父级,但没有任何效果按照我希望的方式工作。

public GameObject Wire;
    public void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "Wire")
         {   Debug.Log("enter wire in socket");

            other.transform.parent = Wire.transform;
        }
    }
    public void OnTriggerExit(Collider other)
    {
        if (other.gameObject.tag == "Wire")
        {   Debug.Log("exitt wire from socket");
            other.transform.parent = null;
        }

孩子实际上撞到了对撞机,但没有附着到父体上,这是我真正希望发生的。


您可以创建一个 Plug 类、一个 Socket 类以及一个 SocketPlugShape 枚举(None、Circle、Square、Plus 等)。 Plug 类将具有触发 LookForFittingSocketsNearby() 的 OnDrop() 函数,该函数利用Physics.OverlapSphere。对于每个碰撞器,您可以通过 socket.TryInsertPlug(Plugplug) 函数比较它是否是 SocketPlugShape 匹配,如果成功,该函数会设置connectedPlug 属性,并更改套接字的plug.transform.parent = 转换。确保碰撞器组件已勾选 Is Trigger。

通过该系统,插头和插座可以轻松连接到预制件中的节点,并且开放的 SocketPlugShape 意味着您可以轻松创建各种连接器,如下所示.

下面该项目的源代码,它并不完全独立,但也许可以为您提供更多指导。祝你好运!

Plug.cs:

namespace VirtualOS {

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class Plug : MonoBehaviour
{
    // A plug that can be inserted into sockets.

    [SerializeField] SocketPlugShape shape = SocketPlugShape.None;
    [SerializeField] float plugRadius = 0.05f;
    [SerializeField] AudioSource unfittingSocketSound = null;

    public void OnDrag()
    {
        Socket socket = GetComponentInParent<Socket>();
        if (socket)
        {
            socket.RemovePlug();
        }
    }

    public bool OnDrop()
    {
        return LookForFittingSocketsNearby();
    }

    public void Unplug()
    {
        Socket socket = GetComponentInParent<Socket>();
        if (socket)
        {
            socket.RemovePlug();
        }
    }

    bool LookForFittingSocketsNearby()
    {
        bool success = false;
        Collider[] colliders = Physics.OverlapSphere(transform.position, plugRadius);
        colliders = colliders.OrderBy(
            x => Vector3.Distance(transform.position, x.transform.position)
        ).ToArray();

        bool unfittingSocketFound = false;        
        foreach (Collider collider in colliders)
        {
            Transform parent = collider.transform.parent;
            if (parent != null)
            {
                Socket socket = parent.GetComponent<Socket>();
                if (socket != null)
                {
                    success = socket.TryInsertPlug(this);
                    if (success)
                    {
                        break;
                    }
                    else
                    {
                        unfittingSocketFound = true;
                    }
                }
            }
        }

        if (unfittingSocketFound && !success)
        {
            HandleUnfittingSocketSound();
        }

        return success;
    }

    void HandleUnfittingSocketSound()
    {
        unfittingSocketSound.Play();
        Handable handable = GetComponentInParent<Handable>();
        if (handable != null)
        {
            handable.InvertVelocity();
        }
    }

    public SocketPlugShape GetShape()
    {
        return shape;
    }

}

}

套接字.cs

namespace VirtualOS {

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Socket : MonoBehaviour
{
    // A socket child in a CustomObject that allows plugs to snap into it, informing
    // the CustomObject when that happens.

    [SerializeField] SocketPlugShape shape = SocketPlugShape.None;
    [SerializeField] AudioSource insertPlugSound = null;
    [SerializeField] AudioSource removePlugSound = null;

    Plug connectedPlug = null;

    Action<Plug> onPlugged = null;
    Action       onUnplugged = null;

    public void SetOnPlugged(Action<Plug> onPlugged)
    {
        this.onPlugged = onPlugged;
    }

    public void SetOnUnplugged(Action onUnplugged)
    {
        this.onUnplugged = onUnplugged;
    }

    public bool TryInsertPlug(Plug plug)
    {
        bool success = false;
        if (
            connectedPlug == null &&
            shape != SocketPlugShape.None &&
            plug.GetShape() == shape
        )
        {
            CustomObject customObject = plug.GetComponentInParent<CustomObject>();
            if (customObject != null)
            {
                success = true;

                connectedPlug = plug;
                customObject.transform.parent = transform;

                AnimatePlugTowardsUs(customObject);

                insertPlugSound.Play();

                Handable handable = GetComponentInParent<Handable>();
                if (handable != null && handable.handHoldingMe != null)
                {
                    handable.handHoldingMe.Vibrate(VibrationForce.Hard);
                }

                if (onPlugged != null) { onPlugged(plug); }
            }
        }
        return success;
    }

    void AnimatePlugTowardsUs(CustomObject customObject)
    {
        Tweener tweener = customObject.GetComponent<Tweener>();
        if (tweener != null)
        {
            tweener.ReachTargetInstantly();
        }
        else
        {
            tweener = customObject.gameObject.AddComponent<Tweener>();
        }
        tweener.Animate(
            position: Vector3.zero, rotation: Vector3.zero, seconds: 0.1f,
            tweenType: TweenType.EaseInOut
        );
    }

    public void RemovePlug()
    {
        if (connectedPlug != null)
        {
            if (onUnplugged != null) { onUnplugged(); }

            CustomObject customObject = connectedPlug.GetComponentInParent<CustomObject>();
            customObject.transform.parent = null;

            connectedPlug = null;

            removePlugSound.Play();
        }
    }

    public SocketPlugShape GetShape()
    {
        return shape;
    }

}

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在为 HTC VIVE 进行 Unity 工作时如何将一个对象粘贴到另一个对象位置 的相关文章

  • 将 SQL Server varBinary 数据转换为字符串 C#

    我需要帮助弄清楚如何转换来自SQL服务器表列设置为varBinary 最大 转换为字符串以便将其显示在标签中 这是在C 我正在使用数据读取器 我可以使用以下方式提取数据 var BinaryString reader 1 我知道该列包含之前
  • 在 Unity 中平滑动态生成的网格?

    给定 Unity 和 C 中的网格 其本身是通过合并更简单的基础网格实时创建的 我们如何在运行时 将其变成平滑的 几乎像包裹在布中的网格版本一样 不是完全凸出的版本 而是更圆润 软化锋利的边缘 桥接深间隙等 理想情况下 表面也将像 平滑角度
  • C# 并行与并行线程代码性能

    我一直在测试 System Threading Parallel 与线程的性能 我很惊讶地发现并行比线程花费更长的时间来完成任务 我确信这是由于我对并行的了解有限 我刚刚开始阅读 我想我会分享一些片段 如果有人可以向我指出并行代码比线程代码
  • 增量决策树 C++ 实现

    有谁知道决策树分类器的增量实现吗 这样 当您将新实例添加到训练集中时 它可以根据现有决策树分类器以低计算量并尽可能快地生成最佳决策树分类器 换句话说 我有一个最优决策树分类器集A 其中命名为T 1 现在我想添加实例X to set A并找到
  • & 运算符的含义是什么?

    在下面的代码中 Expression
  • 为什么将 char 传递给函数会改变它在 c 中的值?

    我目前正在关注本作业簿 http www cs bham ac uk exr lectures opsys 10 11 lectures os dev pdf关于构建操作系统 我的目的是写一个64位内核 我已经在文本模式下加载 内核 代码并
  • std::tr1::function 和 std::tr1::bind

    我在使用时遇到问题veryC 类中的复杂 C 函数 重写 C 函数是not一个选项 C函数 typedef void integrand unsigned ndim const double x void fdata unsigned fd
  • 我的 WPF 应用程序未触发 MainWindow_Loaded

    我目前正在关注Pluralsight C Fundamentals Part 1并在Classes and Objects视频部分指导我在 Visual Studio 中创建一个新的 WPF 应用程序并填写代码 这导致以下结果 namesp
  • 我要恢复我的记忆!我怎样才能真正处理一个控件?

    我正在制作一个应用程序 它创建大量的窗口控件 按钮和标签等 它们都是通过函数动态生成的 我遇到的问题是 当我删除控件并处置它们时 它们不会从内存中删除 void loadALoadOfStuff while tabControlToClea
  • 如何在Azure功能中添加razor视图文件?

    我正在创建一个应用程序 它是 azure 函数项目 我想在该项目中使用 Razor 视图 我应该在 azure 函数中使用任何模板引擎吗 得益于一些方面的进步剃刀之光项目 https github com toddams RazorLigh
  • 为什么这个单独的定义会导致错误?

    挑战 我有这段代码无法编译 你能找出问题所在吗 有一次让我很头疼 header namespace values extern std string address extern int port cpp file std string v
  • C++:LPWSTR 在 cout 中打印为地址

    我有一个类型变量LPTSTR 我打印到std cout with lt lt 在 ANSI 系统中 不知道它是在哪里确定的 它工作得很好 它打印了字符串 现在 在 Unicode 系统中 我得到的是十六进制地址而不是字符串 那么 为什么LP
  • 我可以对(非成员)函数使用部分模板特化吗?

    我试图在 非成员 函数上使用部分模板专业化 但我在语法上遇到了问题 我在 StackOverflow 中搜索了其他部分模板专业化问题 但这些问题涉及类或成员函数模板的部分专业化 作为起点 我有 struct RGBA RGBA uint8
  • 生成范围 [min,max] 内的随机数 [重复]

    这个问题在这里已经有答案了 我正在使用 C 生成范围 min max 内的整数随机数 我在用 int random int int min int max return min rand max min 但我认为上面的代码适用于范围 min
  • 如何在asp.net core 6中注入IConfiguration

    web api 应用程序中不再有 Startup cs 我们以前可以注入IConfiguration进入那个Startup class public class Startup public Startup IConfiguration c
  • 如何创建和使用类箭头运算符? [复制]

    这个问题在这里已经有答案了 因此 在到处研究之后 我似乎找不到如何创建类箭头运算符 即 class Someclass operator gt 我只需要知道如何使用它并正确使用它 它的输入是什么 它返回什么 我如何正确地声明 原型化它 运算
  • Gridview 错误:对 Bind 的调用格式不正确

    我有以下 gridview 代码
  • 将多个 Blob 输入传递到 QueueTrigger Azure 函数的最佳方法

    问题 触发后 生成 3 个 XML 文件 完成后将它们通过 ftp 传输到站点 目前的方法 我有一个 HTTP 触发器 Azure 函数 运行时将构造 3 个 XML 文件并将它们保存到 Azure 存储 Blob 容器中 由于有多个输出
  • “显式”关键字对返回值优化 (RVO) 有何影响?

    以下代码工作得很好 显示 RVO struct A A int cout lt lt A A n constructor A const A cout lt lt A A const A n copy constructor A foo r
  • 替换全局热键

    我有一个位于托盘中的应用程序 我想定义多个热键来触发我的程序中的事件 我从 AaronLS 在这个问题中的出色回答中找到了灵感 使用C 设置全局热键 https stackoverflow com a 27309185 3064934 如果

随机推荐