在为 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 工作时如何将一个对象粘贴到另一个对象位置 的相关文章

  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 覆盖子类中的字段或属性

    我有一个抽象基类 我想声明一个字段或属性 该字段或属性在从该父类继承的每个类中具有不同的值 我想在基类中定义它 以便我可以在基类方法中引用它 例如覆盖 ToString 来表示 此对象的类型为 property field 我有三种方法可以
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐