Added Unity project files
This commit is contained in:
@ -0,0 +1,125 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace VRC.SDK3.ClientSim
|
||||
{
|
||||
// This class is used for when an object has no usable mesh renderers to highlight. This will copy the collider on
|
||||
// the interact instead of any mesh on or under the interact.
|
||||
// An object will not have usable colliders if:
|
||||
// - There are no mesh renderers on or as a child of the object.
|
||||
// - The mesh renderers do not have a mesh
|
||||
// - The mesh renderers are part of a combined or static batched mesh.
|
||||
[AddComponentMenu("")]
|
||||
public class ClientSimHighlightProxy : ClientSimBehaviour
|
||||
{
|
||||
public Renderer Renderer { get; private set; }
|
||||
|
||||
private Mesh _cubeMesh;
|
||||
private Mesh _capsuleMesh;
|
||||
private Mesh _sphereMesh;
|
||||
|
||||
private MeshFilter _filter;
|
||||
private Transform _proxyObject;
|
||||
private Collider _proxyCollider;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
Renderer = GetComponent<Renderer>();
|
||||
_filter = GetComponent<MeshFilter>();
|
||||
}
|
||||
|
||||
public void Initialize(Mesh cubeMesh, Mesh capsuleMesh, Mesh sphereMesh)
|
||||
{
|
||||
_cubeMesh = cubeMesh;
|
||||
_capsuleMesh = capsuleMesh;
|
||||
_sphereMesh = sphereMesh;
|
||||
}
|
||||
|
||||
private void OnWillRenderObject()
|
||||
{
|
||||
UpdatePosition();
|
||||
}
|
||||
|
||||
private void UpdatePosition()
|
||||
{
|
||||
Vector3 position = _proxyObject.position;
|
||||
Quaternion rotation = _proxyObject.rotation;
|
||||
Vector3 scale = _proxyObject.lossyScale;
|
||||
|
||||
if (_proxyCollider is BoxCollider boxCollider)
|
||||
{
|
||||
position += rotation * Vector3.Scale(boxCollider.center, scale);
|
||||
scale = Vector3.Scale(scale, boxCollider.size);
|
||||
_filter.sharedMesh = _cubeMesh;
|
||||
}
|
||||
else if (_proxyCollider is SphereCollider sphereCollider)
|
||||
{
|
||||
position += rotation * Vector3.Scale(sphereCollider.center, scale);
|
||||
|
||||
// VRChatBug: Unity will always keep spheres round, but VRChat ignores this for the proxy rendering.
|
||||
|
||||
// Sphere colliders are always round. Get the max component as the sphere size.
|
||||
float sphereScale = sphereCollider.radius * 2 * Mathf.Max(scale.x, scale.y, scale.z);
|
||||
scale = sphereScale * Vector3.one;
|
||||
_filter.sharedMesh = _sphereMesh;
|
||||
}
|
||||
else if (_proxyCollider is CapsuleCollider capsuleCollider)
|
||||
{
|
||||
position += rotation * Vector3.Scale(capsuleCollider.center, scale);
|
||||
float height = capsuleCollider.height * 0.5f;
|
||||
float radius = capsuleCollider.radius * 2;
|
||||
float sphereScale = radius;
|
||||
|
||||
switch (capsuleCollider.direction)
|
||||
{
|
||||
case 0: // X
|
||||
rotation *= Quaternion.Euler(0, 0, 90);
|
||||
sphereScale = Mathf.Max(scale.y, scale.z) * radius;
|
||||
height *= scale.x;
|
||||
break;
|
||||
case 1: // Y
|
||||
// No need to rotate since mesh is already along y axis.
|
||||
sphereScale = Mathf.Max(scale.x, scale.z) * radius;
|
||||
height *= scale.y;
|
||||
break;
|
||||
case 2: // Z
|
||||
rotation *= Quaternion.Euler(90, 0, 0);
|
||||
sphereScale = Mathf.Max(scale.y, scale.x) * radius;
|
||||
height *= scale.z;
|
||||
break;
|
||||
}
|
||||
|
||||
height = Mathf.Max(sphereScale * 0.5f, height);
|
||||
scale = new Vector3(sphereScale, height, sphereScale);
|
||||
_filter.sharedMesh = _capsuleMesh;
|
||||
}
|
||||
else if (_proxyCollider is MeshCollider meshCollider)
|
||||
{
|
||||
_filter.sharedMesh = meshCollider.sharedMesh;
|
||||
}
|
||||
|
||||
transform.SetPositionAndRotation(position, rotation);
|
||||
transform.localScale = scale;
|
||||
}
|
||||
|
||||
public void EnableProxy(Transform obj, Collider proxyCollider)
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
_filter.sharedMesh = null;
|
||||
_proxyObject = obj;
|
||||
_proxyCollider = proxyCollider;
|
||||
|
||||
UpdatePosition();
|
||||
}
|
||||
|
||||
public void DisableProxy()
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
_filter.sharedMesh = null;
|
||||
_proxyObject = null;
|
||||
_proxyCollider = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user