C# 在为HTC VIVE开发unity时,如何将一个对象粘贴到另一个对象位置
我想创建一个场景,其中导线(子导线)进入插座(父导线),然后导线成为父导线的子导线,其位置与父导线固定,即使我移动父导线,导线也应随之移动 该项目基于HTC Vive的unity3D。我已经使用了OnTiggerEnter事件来检查碰撞器,并将子对象的位置设置为父对象,但没有任何事情按照我希望的方式工作 公共游戏对象线; 公共空对撞机(对撞机其他) { if(other.gameObject.tag==“Wire”) {Debug.Log(“在套接字中输入wire”)C# 在为HTC VIVE开发unity时,如何将一个对象粘贴到另一个对象位置,c#,unity3d,htc-vive,C#,Unity3d,Htc Vive,我想创建一个场景,其中导线(子导线)进入插座(父导线),然后导线成为父导线的子导线,其位置与父导线固定,即使我移动父导线,导线也应随之移动 该项目基于HTC Vive的unity3D。我已经使用了OnTiggerEnter事件来检查碰撞器,并将子对象的位置设置为父对象,但没有任何事情按照我希望的方式工作 公共游戏对象线; 公共空对撞机(对撞机其他) { if(other.gameObject.tag==“Wire”) {Debug.Log(“在套接字中输入wire”) 子对象实际上击中了碰撞器,
子对象实际上击中了碰撞器,但没有连接到父对象,这是我真正希望发生的。您可以创建一个Plug类和一个Socket类,以及一个SocketPlugShape枚举(无、圆、方等)。Plug类将有一个OnDrop()函数触发LookForFittingSocketsNearby()它利用Physics.Overlapphere.Foreach collider,然后通过socket.TryInsertPlug(Plug-Plug)函数比较它是否是SocketPlugShape匹配,如果成功,该函数将设置connectedPlug属性——以及更改套接字的Plug.transform.parent=转换。确保碰撞器组件已触发勾选 通过此系统,插头和插座可以轻松连接到预制件中的节点,而开放式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;
}
}
}
命名空间虚拟化{
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
使用System.Linq;
公共类插件:MonoBehavior
{
//可以插入插座的插头。
[SerializeField]SocketPlugShape=SocketPlugShape.None;
[SerializeField]浮子插头半径=0.05f;
[SerializeField]AudioSource unfittingSocketSound=null;
公屋
{
套接字Socket=getComponentParent();
中频(插座)
{
插座。卸下插头();
}
}
公共图书馆
{
return lookforfittingsocketsnarby();
}
公共空间拔掉()
{
套接字Socket=getComponentParent();
中频(插座)
{
插座。卸下插头();
}
}
bool查找配件库存任意()
{
布尔成功=假;
Collider[]colliders=physical.overlapphere(transform.position,plugRadius);
colliders=colliders.OrderBy(
x=>Vector3.距离(transform.position,x.transform.position)
).ToArray();
bool unfittingSocketFound=false;
foreach(碰撞器中的碰撞器)
{
变换父对象=collider.Transform.parent;
如果(父项!=null)
{
Socket Socket=parent.GetComponent();
if(套接字!=null)
{
success=socket.tryinstertplug(此);
如果(成功)
{
打破
}
其他的
{
unfittingSocketFound=真;
}
}
}
}
if(未安装socketfound&!success)
{
HandleUnfittingSocketSound();
}
回归成功;
}
void HandleUnfittingSocketSound()
{
未安装的SocketSound.Play();
Handable Handable=getComponentParent();
if(可处理!=null)
{
可操作。反转速度();
}
}
公共SocketPlugShape GetShape()
{
返回形状;
}
}
}
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;
}
}
}
命名空间虚拟化{
使用制度;
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类套接字:单行为
{
//CustomObject中的一个套接字子对象,允许插头插入,通知
//发生这种情况时,CustomObject将被删除。
[SerializeField]SocketPlugShape=SocketPlugShape.None;
[SerializeField]AudioSource insertPlugSound=null;
[SerializeField]AudioSource removePlugSound=null;
插头连接插头=空;
Action=null;
操作onUnpugged=null;
公共无效设置已堵塞(操作已堵塞)
{
this.onplucked=onplucked;
}
公共无效设置未建议(操作未建议)
{
this.onUnplugged=onUnplugged;
}
公共bool TryInsertPlug(插头)
{
布尔成功=假;
如果(
connectedPlug==null&&
形状!=插座插头形状。无&&
plug.GetShape()==shape
)
{
CustomObject CustomObject=plug.getComponentParent();
if(customObject!=null)
{
成功=真实;
已连接插头=插头;
customObject.transform.parent=转换;
AnimatePlugTowardsUs(自定义对象);
insertPlugSound.Play();
Handable Handable=getComponentParent();
if(handable!=null&&handable.handHoldingMe!=null)
{
可操作。手持。振动(振动力。硬);
}
如果(onplucked!=null){onplucked(plug);}
}
}
回归成功;
}
void AnimatePlugTowardsUs(自定义对象自定义对象)
{
Tweener Tweener=customObject.GetComponent();
if(tweener!=null)
{
tweener.达到目标();
}
其他的
{
tweener=customObject.gameObject.AddComponent();
}
特威纳。动画制作(
位置:矢量3.0,旋转:矢量3
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;
}
}
}