我想创建一个场景,其中电线(子级)进入套接字(父级),然后电线成为父级的子级,并且它的位置与父级固定,即使我移动父级,电线也应该随之移动用它。
该项目基于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(使用前将#替换为@)