[英]How to stick an object to another objects position while working on unity for HTC VIVE
我想创建一个场景,其中电线(子项)进入插座(父项),然后电线成为父项的子项,并且它的位置与父项一起固定,即使我移动父项,线也应随之移动用它。
这个项目基于unity3D FOR HTC Vive。 我已经使用 ontriggerenter 事件来检查碰撞器并将孩子的位置设置为父母,但没有任何事情按照我想要的方式工作。
公共游戏对象线; 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 类将有一个 OnDrop() 函数触发 LookForFittingSocketsNearby(),它利用 Physics.OverlapSphere。 Foreach collider,然后您将通过 socket.TryInsertPlug(Plug plug) 函数比较它是否是 SocketPlugShape 匹配,如果成功,该函数设置 connectedPlug 属性 - 以及更改插座的 plug.transform.parent = 变换。 确保对撞机组件已勾选 Is Trigger。
通过该系统,插头和插座可以轻松连接到预制件中的节点,而开放的 SocketPlugShape 意味着您可以轻松创建各种连接器,如本视频所示。
下面那个项目的源代码,它不是完全独立的,但可能会给你一些更多的指示。 祝你好运!
插件.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;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.