简体   繁体   中英

How to stick an object to another objects position while working on unity for 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.

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.

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.

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.

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

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

}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM