HTC VIVE统一工作时如何将一个对象粘贴到另一个对象的位置 [英] How to stick an object to another objects position while working on unity for HTC VIVE

查看:69
本文介绍了HTC VIVE统一工作时如何将一个对象粘贴到另一个对象的位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个场景,其中电线(子代)插入插槽(父代),然后电线成为父代的子代,即使我移动父代,电线的位置也与父代固定应该随它一起移动.

I want to create a scene in which a wire(children) goes into a socket(parent) and then the wire becomes the child of the parent and it's position is fixed with the parent, even if i move the parent the wire should move along with it.

该项目基于unity3D FOR HTC Vive.我已经使用过ontriggerenter事件检查对撞机并将孩子的位置设置为父对象,但没有任何事情可以按照我希望的方式工作.

This project is based on unity3D FOR HTC Vive. I have already used the ontriggerenter events to check the colliders and set the position of child to the parent but nothing is working the way i want it to be.

公共GameObject Wire; 公共无效OnTriggerEnter(对撞机其他) { 如果(other.gameObject.tag =="Wire") {Debug.Log(在插座中输入电线");

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;
    }

孩子实际上撞上了撞机,但没有被我真正想发生的母体所吸引.

The child actually hits the collider but does not get attatched to the parent body which i really want to happen.

推荐答案

您可以创建一个Plug类和一个Socket类,以及一个SocketPlugShape枚举(None,Circle,Square,Plus等). Plug类将具有一个OnDrop()函数,该函数触发利用Physics.OverlapSphere的LookForFittingSocketsNearby().对于Foreach对撞机,您然后将通过socket.TryInsertPlug(Plug插件)函数比较它是否是SocketPlugShape匹配项,如果成功,该函数将设置一个connectedPlug属性-以及更改plug.transform.parent =套接字的转换.确保对撞机组件的触发"被勾选.

You could create a Plug class, and a Socket class, along with a SocketPlugShape enum (None, Circle, Square, Plus etc.). The Plug class would have an OnDrop() function triggering LookForFittingSocketsNearby() which utilizes Physics.OverlapSphere. Foreach collider, you'd then compare if it's a SocketPlugShape match via a socket.TryInsertPlug(Plug plug) function, which sets a connectedPlug property if successful -- as well as changing the plug.transform.parent = transform of the socket. Ensure the collider components have Is Trigger ticked.

通过此系统,可以轻松地将插头和插座连接到Prefabs中的节点上,并且打开的SocketPlugShape意味着您可以轻松创建各种连接器,如

Via this system, the Plug and Sockets can then be easily attached to nodes in your Prefabs, and the open SocketPlugShape means you can create a variety of connectors easily, as shown in this video.

下面该项目的源代码,它不是完全独立的,但可能会为您提供更多的指针.祝你好运!

Source code of that project below, it's not fully self-contained but maybe gives you some more pointers. Good luck!

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;
    }

}

}

Socket.cs

Socket.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;
    }

}

}

这篇关于HTC VIVE统一工作时如何将一个对象粘贴到另一个对象的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆