Move third party assets to ThirdParty folder
This commit is contained in:
82
Assets/ThirdParty/UltimateXR/Editor/Avatar/AddAvatarToSceneMenu.cs
vendored
Normal file
82
Assets/ThirdParty/UltimateXR/Editor/Avatar/AddAvatarToSceneMenu.cs
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="AddAvatarToSceneMenu.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using UltimateXR.Core;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UltimateXR.Editor.Avatar
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility class with menu items to add built-in UltimateXR avatars to the scene.
|
||||
/// </summary>
|
||||
public static class AddAvatarToSceneMenu
|
||||
{
|
||||
#region Public Methods
|
||||
|
||||
[MenuItem(UxrConstants.Editor.MenuPathAddAvatar + "Small Hands Avatar (BRP)", priority = UxrConstants.Editor.PriorityMenuPathAvatar)]
|
||||
public static void AddSmallHandsAvatarBrp()
|
||||
{
|
||||
AddAvatar(SmallHandsAvatarBrpAssetGuid);
|
||||
}
|
||||
|
||||
[MenuItem(UxrConstants.Editor.MenuPathAddAvatar + "Small Hands Avatar (URP)", priority = UxrConstants.Editor.PriorityMenuPathAvatar + 1)]
|
||||
public static void AddSmallHandsAvatarUrp()
|
||||
{
|
||||
AddAvatar(SmallHandsAvatarUrpAssetGuid);
|
||||
}
|
||||
|
||||
[MenuItem(UxrConstants.Editor.MenuPathAddAvatar + "Big Hands Avatar (BRP)", priority = UxrConstants.Editor.PriorityMenuPathAvatar + 2)]
|
||||
public static void AddBigHandsAvatarBrp()
|
||||
{
|
||||
AddAvatar(BigHandsAvatarBrpAssetGuid);
|
||||
}
|
||||
|
||||
[MenuItem(UxrConstants.Editor.MenuPathAddAvatar + "Big Hands Avatar (URP)", priority = UxrConstants.Editor.PriorityMenuPathAvatar + 3)]
|
||||
public static void AddBigHandsAvatarUrp()
|
||||
{
|
||||
AddAvatar(BigHandsAvatarUrpAssetGuid);
|
||||
}
|
||||
|
||||
[MenuItem(UxrConstants.Editor.MenuPathAddAvatar + "Cyborg Avatar (BRP)", priority = UxrConstants.Editor.PriorityMenuPathAvatar + 4)]
|
||||
public static void AddCyborgAvatarBrp()
|
||||
{
|
||||
AddAvatar(CyborgAvatarBrpAssetGuid);
|
||||
}
|
||||
|
||||
[MenuItem(UxrConstants.Editor.MenuPathAddAvatar + "Cyborg Avatar (URP)", priority = UxrConstants.Editor.PriorityMenuPathAvatar + 5)]
|
||||
public static void AddCyborgAvatarUrp()
|
||||
{
|
||||
AddAvatar(CyborgAvatarUrpAssetGuid);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Types & Data
|
||||
|
||||
private static void AddAvatar(string assetGuid)
|
||||
{
|
||||
GameObject avatarAsset = AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GUIDToAssetPath(assetGuid));
|
||||
|
||||
if (avatarAsset != null)
|
||||
{
|
||||
GameObject newInstance = PrefabUtility.InstantiatePrefab(avatarAsset) as GameObject;
|
||||
newInstance.transform.position = Vector3.zero;
|
||||
newInstance.transform.rotation = Quaternion.identity;
|
||||
newInstance.name = avatarAsset.name;
|
||||
Selection.activeGameObject = newInstance;
|
||||
}
|
||||
}
|
||||
|
||||
private const string SmallHandsAvatarBrpAssetGuid = "c311edb378c22084c9abc1d944113176";
|
||||
private const string SmallHandsAvatarUrpAssetGuid = "7195d091dac462e4db9ba0793d9a6727";
|
||||
private const string BigHandsAvatarBrpAssetGuid = "e7c39828446955c4eb062c0ef1f5eb71";
|
||||
private const string BigHandsAvatarUrpAssetGuid = "dc011efb41f2d4a419389aefb4b4270d";
|
||||
private const string CyborgAvatarBrpAssetGuid = "d12ff67997e4a1547890dc7efeb1b11c";
|
||||
private const string CyborgAvatarUrpAssetGuid = "e7468ec6b7af89c4d94d451ec3c1807b";
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
11
Assets/ThirdParty/UltimateXR/Editor/Avatar/AddAvatarToSceneMenu.cs.meta
vendored
Normal file
11
Assets/ThirdParty/UltimateXR/Editor/Avatar/AddAvatarToSceneMenu.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e087a265e2b755f4ba843e1c6295c466
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
172
Assets/ThirdParty/UltimateXR/Editor/Avatar/BigHandGizmoLeft.prefab
vendored
Normal file
172
Assets/ThirdParty/UltimateXR/Editor/Avatar/BigHandGizmoLeft.prefab
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &3105755673493717711
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6660199555974101477}
|
||||
m_Layer: 0
|
||||
m_Name: BigHandGizmoLeft
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &6660199555974101477
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3105755673493717711}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 3934064300957786961}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1001 &3535928094376264890
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 6660199555974101477}
|
||||
m_Modifications:
|
||||
- target: {fileID: -8679921383154817045, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_RootOrder
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -6709857489335223893, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_IsActive
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5747895058768455926, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Wrist
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5654198184702395596, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_Materials.Array.data[0]
|
||||
value:
|
||||
objectReference: {fileID: 2100000, guid: efed6a9e4d429f64fb8335d6c1b71f6b, type: 2}
|
||||
- target: {fileID: 919132149155446097, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Hand
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3291163720618517394, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3291163720618517394, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3291163720618517394, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3291163720618517394, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3291163720618517394, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352927432503674278, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352927432503674278, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352927432503674278, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352927432503674278, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352927432503674278, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3823570585033785298, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3823570585033785298, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3823570585033785298, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3823570585033785298, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3823570585033785298, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4542265952940996083, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
propertyPath: m_Materials.Array.data[0]
|
||||
value:
|
||||
objectReference: {fileID: 2100000, guid: efed6a9e4d429f64fb8335d6c1b71f6b, type: 2}
|
||||
m_RemovedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
--- !u!4 &3934064300957786961 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: 3cc1bfa741063664e8b13a63afcd062f, type: 3}
|
||||
m_PrefabInstance: {fileID: 3535928094376264890}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
7
Assets/ThirdParty/UltimateXR/Editor/Avatar/BigHandGizmoLeft.prefab.meta
vendored
Normal file
7
Assets/ThirdParty/UltimateXR/Editor/Avatar/BigHandGizmoLeft.prefab.meta
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93019d606e943b7429d29c694143ad6e
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
184
Assets/ThirdParty/UltimateXR/Editor/Avatar/BigHandGizmoRight.prefab
vendored
Normal file
184
Assets/ThirdParty/UltimateXR/Editor/Avatar/BigHandGizmoRight.prefab
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &4805418415246262332
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8582211912875862288}
|
||||
m_Layer: 0
|
||||
m_Name: BigHandGizmoRight
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &8582211912875862288
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4805418415246262332}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 550750527984811268}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1001 &12967445033245423
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 8582211912875862288}
|
||||
m_Modifications:
|
||||
- target: {fileID: -8679921383154817045, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_RootOrder
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8646571443531358356, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_Materials.Array.data[0]
|
||||
value:
|
||||
objectReference: {fileID: 2100000, guid: efed6a9e4d429f64fb8335d6c1b71f6b, type: 2}
|
||||
- target: {fileID: -7327828634711335260, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_Materials.Array.data[0]
|
||||
value:
|
||||
objectReference: {fileID: 2100000, guid: efed6a9e4d429f64fb8335d6c1b71f6b, type: 2}
|
||||
- target: {fileID: -5193524538114237147, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5193524538114237147, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5193524538114237147, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5193524538114237147, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5193524538114237147, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5193524538114237147, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5193524538114237147, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -147837933818791889, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -147837933818791889, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -147837933818791889, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -147837933818791889, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -147837933818791889, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -147837933818791889, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -147837933818791889, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 919132149155446097, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Hand
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6665695938027609144, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Wrist
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8731801213580401448, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8731801213580401448, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8731801213580401448, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8731801213580401448, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8857101846222818459, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
propertyPath: m_IsActive
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
--- !u!4 &550750527984811268 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: 1de94829f1eb3df4e97553bc8bb8135c, type: 3}
|
||||
m_PrefabInstance: {fileID: 12967445033245423}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
7
Assets/ThirdParty/UltimateXR/Editor/Avatar/BigHandGizmoRight.prefab.meta
vendored
Normal file
7
Assets/ThirdParty/UltimateXR/Editor/Avatar/BigHandGizmoRight.prefab.meta
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d45d3edc285cfd64a86fddd771e13f47
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ThirdParty/UltimateXR/Editor/Avatar/Controllers.meta
vendored
Normal file
8
Assets/ThirdParty/UltimateXR/Editor/Avatar/Controllers.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 470a2f8a41647a14a98eec5954b6b218
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
303
Assets/ThirdParty/UltimateXR/Editor/Avatar/Controllers/UxrStandardAvatarControllerEditor.cs
vendored
Normal file
303
Assets/ThirdParty/UltimateXR/Editor/Avatar/Controllers/UxrStandardAvatarControllerEditor.cs
vendored
Normal file
@@ -0,0 +1,303 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrStandardAvatarControllerEditor.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Linq;
|
||||
using UltimateXR.Animation.IK;
|
||||
using UltimateXR.Avatar;
|
||||
using UltimateXR.Avatar.Controllers;
|
||||
using UltimateXR.Avatar.Rig;
|
||||
using UltimateXR.Editor.Animation.IK;
|
||||
using UltimateXR.Extensions.System.Collections;
|
||||
using UltimateXR.Extensions.Unity;
|
||||
using UltimateXR.Manipulation.HandPoses;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UltimateXR.Editor.Avatar.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom inspector for the <see cref="UxrStandardAvatarController" /> component.
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(UxrStandardAvatarController))]
|
||||
public sealed class UxrStandardAvatarControllerEditor : UnityEditor.Editor
|
||||
{
|
||||
#region Public Types & Data
|
||||
|
||||
public const string PropAllowHandTracking = "_allowHandTracking";
|
||||
public const string PropUseArmIK = "_useArmIK";
|
||||
public const string PropArmIKElbowAperture = "_armIKElbowAperture";
|
||||
public const string PropArmIKOverExtendMode = "_armIKOverExtendMode";
|
||||
public const string PropUseBodyIK = "_useBodyIK";
|
||||
public const string PropBodyIKSettings = "_bodyIKSettings";
|
||||
//public const string PropUseLegIK = "_useLegIK";
|
||||
public const string PropListControllerEvents = "_listControllerEvents";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unity
|
||||
|
||||
/// <summary>
|
||||
/// Caches the serialized properties and initializes data.
|
||||
/// </summary>
|
||||
private void OnEnable()
|
||||
{
|
||||
UxrStandardAvatarController selectedController = (UxrStandardAvatarController)serializedObject.targetObject;
|
||||
UxrAvatar avatar = selectedController.Avatar;
|
||||
|
||||
_propAllowHandTracking = serializedObject.FindProperty(PropAllowHandTracking);
|
||||
_propUseArmIK = serializedObject.FindProperty(PropUseArmIK);
|
||||
_propArmIKElbowAperture = serializedObject.FindProperty(PropArmIKElbowAperture);
|
||||
_propArmIKOverExtendMode = serializedObject.FindProperty(PropArmIKOverExtendMode);
|
||||
_propUseBodyIK = serializedObject.FindProperty(PropUseBodyIK);
|
||||
_propBodyIKSettings = serializedObject.FindProperty(PropBodyIKSettings);
|
||||
//_propUseLegIK = serializedObject.FindProperty(PropUseLegIK);
|
||||
_propListControllerEvents = serializedObject.FindProperty(PropListControllerEvents);
|
||||
|
||||
if (_propListControllerEvents != null)
|
||||
{
|
||||
_reorderableEventList = CreateReorderableList(serializedObject, _propListControllerEvents, DrawControllerEventCallback);
|
||||
}
|
||||
|
||||
// Get avatar info
|
||||
|
||||
_reorderableEventList.elementHeightCallback = index =>
|
||||
{
|
||||
if (index >= selectedController.ControllerEvents.Count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
UxrHandPoseAsset handPoseAsset = avatar.GetHandPose(selectedController.ControllerEvents[index].PoseName);
|
||||
return EditorGUIUtility.singleLineHeight * 3.5f + (handPoseAsset && handPoseAsset.PoseType == UxrHandPoseType.Blend ? EditorGUIUtility.singleLineHeight : 0.0f);
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by Unity to draw the inspector for the selected component(s).
|
||||
/// </summary>
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
UxrAvatar avatar = ((UxrStandardAvatarController)serializedObject.targetObject).GetComponent<UxrAvatar>();
|
||||
|
||||
// Handle UI
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.Space();
|
||||
|
||||
_foldoutGeneral = UxrEditorUtils.FoldoutStylish("General", _foldoutGeneral);
|
||||
|
||||
if (_foldoutGeneral)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propAllowHandTracking, ContentAllowHandTracking);
|
||||
}
|
||||
|
||||
if (avatar.AvatarRigType == UxrAvatarRigType.HalfOrFullBody)
|
||||
{
|
||||
_foldoutIK = UxrEditorUtils.FoldoutStylish("Inverse Kinematics", _foldoutIK);
|
||||
|
||||
if (_foldoutIK)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propUseArmIK, ContentUseArmIK);
|
||||
|
||||
if (!avatar.AvatarRig.HasArmData())
|
||||
{
|
||||
EditorGUILayout.HelpBox($"To use arm IK, the {nameof(UxrAvatar)} component needs arm references in the Avatar Rig section", MessageType.Warning);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_propUseArmIK.boolValue)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.Slider(_propArmIKElbowAperture, 0.0f, 1.0f, ContentArmIKElbowAperture);
|
||||
if (EditorGUI.EndChangeCheck() && Application.isPlaying)
|
||||
{
|
||||
UxrIKSolver.GetComponents(avatar, true).OfType<UxrArmIKSolver>().ForEach(s => s.RelaxedElbowAperture = _propArmIKElbowAperture.floatValue);
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(_propArmIKOverExtendMode, ContentArmIKOverExtendMode);
|
||||
if (EditorGUI.EndChangeCheck() && Application.isPlaying)
|
||||
{
|
||||
UxrIKSolver.GetComponents(avatar, true).OfType<UxrArmIKSolver>().ForEach(s => s.OverExtendMode = (UxrArmOverExtendMode)_propArmIKOverExtendMode.enumValueIndex);
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
bool hasUpperBodyReferences = avatar.AvatarRig.HasAnyUpperBodyIKReference();
|
||||
|
||||
EditorGUILayout.PropertyField(_propUseBodyIK, ContentUseBodyIK);
|
||||
|
||||
if (!hasUpperBodyReferences)
|
||||
{
|
||||
EditorGUILayout.HelpBox($"To use body IK, the {nameof(UxrAvatar)} component needs upper body references in the Avatar Rig section", MessageType.Warning);
|
||||
}
|
||||
|
||||
GUI.enabled = hasUpperBodyReferences;
|
||||
|
||||
if (_propUseBodyIK.boolValue && hasUpperBodyReferences)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(_propBodyIKSettings, ContentBodyIKSettings);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
GUI.enabled = false;
|
||||
//EditorGUILayout.PropertyField(_propUseLegIK);
|
||||
EditorGUILayout.Toggle(ContentUseLegIK, false);
|
||||
GUI.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
_foldoutHandEvents = UxrEditorUtils.FoldoutStylish("Special Hand Pose Events", _foldoutHandEvents);
|
||||
|
||||
if (_foldoutHandEvents)
|
||||
{
|
||||
EditorGUILayout.LabelField("Hand poses based on controller input events:", EditorStyles.boldLabel);
|
||||
|
||||
if (string.IsNullOrEmpty(avatar.PrefabGuid) || !avatar.GetAllHandPoses().Any())
|
||||
{
|
||||
EditorGUILayout.HelpBox($"To start using this functionality add hand poses to the {nameof(UxrAvatar)} component first.", MessageType.Info);
|
||||
}
|
||||
else
|
||||
{
|
||||
_reorderableEventList?.DoLayoutList();
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by Unity to draw gizmos. It's used to display some visual aids when the avatar has a
|
||||
/// <see cref="UxrAvatarRigType.HalfOrFullBody" /> configuration.
|
||||
/// </summary>
|
||||
private void OnSceneGUI()
|
||||
{
|
||||
UxrStandardAvatarController standardAvatarController = (UxrStandardAvatarController)serializedObject.targetObject;
|
||||
UxrAvatar avatar = standardAvatarController.Avatar;
|
||||
|
||||
if (standardAvatarController && standardAvatarController.UseBodyIK && avatar && avatar.AvatarRigType == UxrAvatarRigType.HalfOrFullBody)
|
||||
{
|
||||
Transform avatarTransform = avatar.transform;
|
||||
|
||||
float neckBaseHeight = _propBodyIKSettings.FindPropertyRelative(UxrIKBodySettingsDrawer.PropertyNeckBaseHeight).floatValue;
|
||||
float neckForwardOffset = _propBodyIKSettings.FindPropertyRelative(UxrIKBodySettingsDrawer.PropertyNeckForwardOffset).floatValue;
|
||||
float eyesBaseHeight = _propBodyIKSettings.FindPropertyRelative(UxrIKBodySettingsDrawer.PropertyEyesBaseHeight).floatValue;
|
||||
float eyesForwardOffset = _propBodyIKSettings.FindPropertyRelative(UxrIKBodySettingsDrawer.PropertyEyesForwardOffset).floatValue;
|
||||
|
||||
float neckRadius = 0.08f;
|
||||
float eyesSeparation = 0.065f;
|
||||
float eyesRadius = 0.01f;
|
||||
|
||||
if (avatar.AvatarRig.Head.Neck == null)
|
||||
{
|
||||
Handles.DrawSolidDisc(avatarTransform.position + avatarTransform.GetScaledVector(0.0f, neckBaseHeight, neckForwardOffset), avatarTransform.up, neckRadius);
|
||||
}
|
||||
|
||||
Handles.DrawSolidDisc(avatarTransform.position + avatarTransform.GetScaledVector(-eyesSeparation * 0.5f, eyesBaseHeight, eyesForwardOffset), avatarTransform.forward, eyesRadius);
|
||||
Handles.DrawSolidDisc(avatarTransform.position + avatarTransform.GetScaledVector(eyesSeparation * 0.5f, eyesBaseHeight, eyesForwardOffset), avatarTransform.forward, eyesRadius);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Creates a reorderable list for the given controller events.
|
||||
/// </summary>
|
||||
/// <param name="serializedObject">Serialized object representing the selected component(s)</param>
|
||||
/// <param name="propertyListControllerEvents">The serialized property with the controller events</param>
|
||||
/// <param name="drawCallback">A callback to draw the list</param>
|
||||
/// <returns></returns>
|
||||
private static ReorderableList CreateReorderableList(SerializedObject serializedObject, SerializedProperty propertyListControllerEvents, ReorderableList.ElementCallbackDelegate drawCallback)
|
||||
{
|
||||
ReorderableList reorderableEventList = new ReorderableList(serializedObject, propertyListControllerEvents, true, true, true, true);
|
||||
reorderableEventList.drawHeaderCallback = rect => { EditorGUI.LabelField(rect, "Drag elements to reorder them by priority from top to bottom"); };
|
||||
reorderableEventList.drawElementCallback = drawCallback;
|
||||
return reorderableEventList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that draws an event entry in the inspector.
|
||||
/// </summary>
|
||||
/// <param name="rect">The rect where to draw the element</param>
|
||||
/// <param name="index">The element index in the list</param>
|
||||
/// <param name="isActive">Whether the element is active</param>
|
||||
/// <param name="isFocused">Whether the element is focused</param>
|
||||
private void DrawControllerEventCallback(Rect rect, int index, bool isActive, bool isFocused)
|
||||
{
|
||||
UxrStandardAvatarController selectedController = (UxrStandardAvatarController)serializedObject.targetObject;
|
||||
UxrAvatar avatar = selectedController.Avatar;
|
||||
SerializedProperty element = _reorderableEventList.serializedProperty.GetArrayElementAtIndex(index);
|
||||
|
||||
int nLineIndex = 0;
|
||||
|
||||
Rect GetCurrentRect()
|
||||
{
|
||||
return new Rect(rect.x, rect.y + EditorGUIUtility.singleLineHeight * nLineIndex, rect.width, EditorGUIUtility.singleLineHeight);
|
||||
}
|
||||
|
||||
// Animation type
|
||||
|
||||
EditorGUI.PropertyField(GetCurrentRect(), element.FindPropertyRelative("_animationType"), new GUIContent("Animation type"));
|
||||
|
||||
nLineIndex++;
|
||||
|
||||
// Controller button mask
|
||||
|
||||
int buttons = EditorGUI.MaskField(GetCurrentRect(), new GUIContent("Controller button(s)"), element.FindPropertyRelative("_buttons").intValue, UxrEditorUtils.GetControllerButtonNames().ToArray());
|
||||
element.FindPropertyRelative("_buttons").intValue = buttons;
|
||||
|
||||
nLineIndex++;
|
||||
|
||||
// List animator parameters
|
||||
|
||||
UxrEditorUtils.HandPoseDropdown(GetCurrentRect(), new GUIContent("Hand Pose"), avatar, element.FindPropertyRelative("_handPose"), out UxrHandPoseAsset selectedHandPose);
|
||||
|
||||
nLineIndex++;
|
||||
|
||||
if (selectedHandPose && selectedHandPose.PoseType == UxrHandPoseType.Blend)
|
||||
{
|
||||
element.FindPropertyRelative("_poseBlendValue").floatValue = EditorGUI.Slider(GetCurrentRect(), new GUIContent("Pose Blend"), element.FindPropertyRelative("_poseBlendValue").floatValue, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Types & Data
|
||||
|
||||
private GUIContent ContentAllowHandTracking { get; } = new GUIContent("Allow Hand Tracking", "Switches to hand-tracking to update the avatar hands when available");
|
||||
private GUIContent ContentUseArmIK { get; } = new GUIContent("Use Arm IK", "Whether to try to naturally orient the arms using the position of the hands");
|
||||
private GUIContent ContentArmIKElbowAperture { get; } = new GUIContent("Elbow Neutral Aperture", "Controls how close the elbows will be to the body when arms are computed using inverse kinematics");
|
||||
private GUIContent ContentArmIKOverExtendMode { get; } = new GUIContent("Arm Over-Extend", "Controls what to do when the user extends the hands over the avatar's arm reach");
|
||||
private GUIContent ContentUseBodyIK { get; } = new GUIContent("Use Body IK", "Whether to try to naturally orient the avatar body using the positions of the head and hand");
|
||||
private GUIContent ContentBodyIKSettings { get; } = new GUIContent("Body IK Settings");
|
||||
private GUIContent ContentUseLegIK { get; } = new GUIContent("Use Leg IK (TBD)", "");
|
||||
|
||||
private SerializedProperty _propAllowHandTracking;
|
||||
private SerializedProperty _propUseArmIK;
|
||||
private SerializedProperty _propArmIKElbowAperture;
|
||||
private SerializedProperty _propArmIKOverExtendMode;
|
||||
private SerializedProperty _propUseBodyIK;
|
||||
private SerializedProperty _propBodyIKSettings;
|
||||
//private SerializedProperty _propUseLegIK;
|
||||
private SerializedProperty _propListControllerEvents;
|
||||
|
||||
private bool _foldoutGeneral = true;
|
||||
private bool _foldoutIK = true;
|
||||
private bool _foldoutHandEvents = true;
|
||||
private ReorderableList _reorderableEventList;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/UltimateXR/Editor/Avatar/Controllers/UxrStandardAvatarControllerEditor.cs.meta
vendored
Normal file
12
Assets/ThirdParty/UltimateXR/Editor/Avatar/Controllers/UxrStandardAvatarControllerEditor.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b019ea387b41a1438953b9ff201213b
|
||||
timeCreated: 1501659089
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
123
Assets/ThirdParty/UltimateXR/Editor/Avatar/GizmoMat.mat
vendored
Normal file
123
Assets/ThirdParty/UltimateXR/Editor/Avatar/GizmoMat.mat
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &-837949187144976569
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 11
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 4
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: GizmoMat
|
||||
m_Shader: {fileID: 4800000, guid: 937ba134f74480c4687ca81e9780b6f9, type: 3}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BaseMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _SpecGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_Lightmaps:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_LightmapsInd:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_ShadowMasks:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _AlphaClip: 0
|
||||
- _Blend: 0
|
||||
- _BumpScale: 1
|
||||
- _ClearCoatMask: 0
|
||||
- _ClearCoatSmoothness: 0
|
||||
- _Cull: 2
|
||||
- _Cutoff: 0.5
|
||||
- _DetailAlbedoMapScale: 1
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _EnvironmentReflections: 1
|
||||
- _GlossMapScale: 0
|
||||
- _Glossiness: 0
|
||||
- _GlossyReflections: 0
|
||||
- _Metallic: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.005
|
||||
- _QueueOffset: 0
|
||||
- _ReceiveShadows: 1
|
||||
- _Smoothness: 0.5
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _Surface: 0
|
||||
- _WorkflowMode: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _Color: {r: 0.0087973215, g: 0.6792453, b: 0, a: 0.47058824}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
8
Assets/ThirdParty/UltimateXR/Editor/Avatar/GizmoMat.mat.meta
vendored
Normal file
8
Assets/ThirdParty/UltimateXR/Editor/Avatar/GizmoMat.mat.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efed6a9e4d429f64fb8335d6c1b71f6b
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
188
Assets/ThirdParty/UltimateXR/Editor/Avatar/SmallHandGizmoLeft.prefab
vendored
Normal file
188
Assets/ThirdParty/UltimateXR/Editor/Avatar/SmallHandGizmoLeft.prefab
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &3105755673493717711
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6660199555974101477}
|
||||
m_Layer: 0
|
||||
m_Name: SmallHandGizmoLeft
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &6660199555974101477
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3105755673493717711}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 8739749207329967463}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1001 &9134261997500295820
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 6660199555974101477}
|
||||
m_Modifications:
|
||||
- target: {fileID: -8679921383154817045, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_RootOrder
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -6709857489335223893, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_IsActive
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5654198184702395596, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_Materials.Array.data[0]
|
||||
value:
|
||||
objectReference: {fileID: 2100000, guid: efed6a9e4d429f64fb8335d6c1b71f6b, type: 2}
|
||||
- target: {fileID: -3386177114557159912, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -3386177114557159912, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -3386177114557159912, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -3386177114557159912, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -3386177114557159912, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -1276430613889393907, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Wrist
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 919132149155446097, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Hand
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3291163720618517394, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3291163720618517394, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3291163720618517394, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3291163720618517394, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3291163720618517394, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3291163720618517394, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3291163720618517394, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352927432503674278, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352927432503674278, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352927432503674278, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352927432503674278, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352927432503674278, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352927432503674278, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352927432503674278, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4542265952940996083, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
propertyPath: m_Materials.Array.data[0]
|
||||
value:
|
||||
objectReference: {fileID: 2100000, guid: efed6a9e4d429f64fb8335d6c1b71f6b, type: 2}
|
||||
m_RemovedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
--- !u!4 &8739749207329967463 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: 7521758fa660fff47b173d40956b49fb, type: 3}
|
||||
m_PrefabInstance: {fileID: 9134261997500295820}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
7
Assets/ThirdParty/UltimateXR/Editor/Avatar/SmallHandGizmoLeft.prefab.meta
vendored
Normal file
7
Assets/ThirdParty/UltimateXR/Editor/Avatar/SmallHandGizmoLeft.prefab.meta
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 672e7f52fe868134a80bf396141fe261
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
188
Assets/ThirdParty/UltimateXR/Editor/Avatar/SmallHandGizmoRight.prefab
vendored
Normal file
188
Assets/ThirdParty/UltimateXR/Editor/Avatar/SmallHandGizmoRight.prefab
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &4805418415246262332
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8582211912875862288}
|
||||
m_Layer: 0
|
||||
m_Name: SmallHandGizmoRight
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &8582211912875862288
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4805418415246262332}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 7394772466370446829}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1001 &6995562589688488454
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 8582211912875862288}
|
||||
m_Modifications:
|
||||
- target: {fileID: -8695551014827756411, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Wrist
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_RootOrder
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8679921383154817045, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -8646571443531358356, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_Materials.Array.data[0]
|
||||
value:
|
||||
objectReference: {fileID: 2100000, guid: efed6a9e4d429f64fb8335d6c1b71f6b, type: 2}
|
||||
- target: {fileID: -7327828634711335260, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_Materials.Array.data[0]
|
||||
value:
|
||||
objectReference: {fileID: 2100000, guid: efed6a9e4d429f64fb8335d6c1b71f6b, type: 2}
|
||||
- target: {fileID: -5193524538114237147, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5193524538114237147, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5193524538114237147, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5193524538114237147, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5193524538114237147, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5193524538114237147, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -5193524538114237147, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -147837933818791889, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -147837933818791889, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -147837933818791889, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -147837933818791889, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -147837933818791889, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -147837933818791889, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: -147837933818791889, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 919132149155446097, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Hand
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5426830260529530398, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5426830260529530398, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5426830260529530398, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5426830260529530398, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5426830260529530398, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8857101846222818459, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
propertyPath: m_IsActive
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
--- !u!4 &7394772466370446829 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: cb9671829f1949c46a89cad7c5fa47dd, type: 3}
|
||||
m_PrefabInstance: {fileID: 6995562589688488454}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
7
Assets/ThirdParty/UltimateXR/Editor/Avatar/SmallHandGizmoRight.prefab.meta
vendored
Normal file
7
Assets/ThirdParty/UltimateXR/Editor/Avatar/SmallHandGizmoRight.prefab.meta
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a1c1014903295a408b755f1fed2863e
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
855
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrAvatarEditor.cs
vendored
Normal file
855
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrAvatarEditor.cs
vendored
Normal file
@@ -0,0 +1,855 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrAvatarEditor.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UltimateXR.Animation.IK;
|
||||
using UltimateXR.Avatar;
|
||||
using UltimateXR.Avatar.Controllers;
|
||||
using UltimateXR.Avatar.Rig;
|
||||
using UltimateXR.Core;
|
||||
using UltimateXR.Devices;
|
||||
using UltimateXR.Editor.Animation.IK;
|
||||
using UltimateXR.Editor.Avatar.Controllers;
|
||||
using UltimateXR.Editor.Manipulation.HandPoses;
|
||||
using UltimateXR.Extensions.System.Collections;
|
||||
using UltimateXR.Extensions.Unity;
|
||||
using UltimateXR.Manipulation.HandPoses;
|
||||
using UltimateXR.Networking;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace UltimateXR.Editor.Avatar
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom editor for <see cref="UxrAvatar" />.
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(UxrAvatar))]
|
||||
public class UxrAvatarEditor : UnityEditor.Editor
|
||||
{
|
||||
#region Public Types & Data
|
||||
|
||||
public const string PropertyParentPrefab = "_parentPrefab";
|
||||
public const string PropertyPrefabGuid = "_prefabGuid";
|
||||
public const string PropertyHandPoses = "_handPoses";
|
||||
public const string PropertyDefaultHandPose = "_defaultHandPose";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unity
|
||||
|
||||
/// <summary>
|
||||
/// Caches serialized properties and initializes the avatar rig expandable field.
|
||||
/// </summary>
|
||||
private void OnEnable()
|
||||
{
|
||||
_propertyPrefabGuid = serializedObject.FindProperty(PropertyPrefabGuid);
|
||||
_propertyParentPrefab = serializedObject.FindProperty(PropertyParentPrefab);
|
||||
_propertyAvatarMode = serializedObject.FindProperty("_avatarMode");
|
||||
_propertyRenderMode = serializedObject.FindProperty("_renderMode");
|
||||
_propertyShowControllerHands = serializedObject.FindProperty("_showControllerHands");
|
||||
_propertyAvatarRenderers = serializedObject.FindProperty("_avatarRenderers");
|
||||
_propertyRigType = serializedObject.FindProperty("_rigType");
|
||||
_propertyRigExpandedInitialized = serializedObject.FindProperty("_rigExpandedInitialized");
|
||||
_propertyRigFoldout = serializedObject.FindProperty("_rigFoldout");
|
||||
_propertyRig = serializedObject.FindProperty("_rig");
|
||||
_propertyHandPosesFoldout = serializedObject.FindProperty("_handPosesFoldout");
|
||||
_propertyHandPoses = serializedObject.FindProperty(PropertyHandPoses);
|
||||
|
||||
// Expand rig when created, only once.
|
||||
|
||||
if (_propertyRigExpandedInitialized.boolValue == false)
|
||||
{
|
||||
_propertyRigExpandedInitialized.boolValue = true;
|
||||
_propertyRig.isExpanded = true;
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the custom inspector and handles events.
|
||||
/// </summary>
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
UxrAvatar avatar = (UxrAvatar)serializedObject.targetObject;
|
||||
|
||||
if (avatar == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject prefab = null;
|
||||
GameObject parentPrefab = null;
|
||||
bool isPrefabStageSelected = false;
|
||||
|
||||
if (avatar.gameObject.IsPrefabRoot())
|
||||
{
|
||||
PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
|
||||
if (prefabStage != null && prefabStage.prefabContentsRoot == avatar.gameObject)
|
||||
{
|
||||
// Get prefab from prefab window which is open
|
||||
prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabStage.assetPath);
|
||||
isPrefabStageSelected = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
prefab = avatar.gameObject;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UxrEditorUtils.GetInParentPrefab(avatar.gameObject, out prefab);
|
||||
|
||||
PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
|
||||
if (prefabStage == null || prefabStage.prefabContentsRoot != avatar.gameObject)
|
||||
{
|
||||
// It's not open in prefab window.
|
||||
// Fix for avatar prefabs nested in another higher-level prefab
|
||||
while (prefab != null && prefab.gameObject.transform.parent != null)
|
||||
{
|
||||
UxrEditorUtils.GetInParentPrefab(prefab.gameObject, out prefab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prefab != null)
|
||||
{
|
||||
UxrEditorUtils.GetInParentPrefab(prefab.gameObject, out parentPrefab);
|
||||
}
|
||||
|
||||
UxrAvatar avatarPrefab = prefab != null ? prefab.GetComponent<UxrAvatar>() : null;
|
||||
string avatarPrefabGuid = prefab != null ? AssetDatabase.GUIDFromAssetPath(AssetDatabase.GetAssetPath(prefab)).ToString() : null;
|
||||
UxrAvatar avatarParentPrefab = parentPrefab != null ? parentPrefab.GetComponent<UxrAvatar>() : null;
|
||||
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
// Check if we need to get and store the prefab information:
|
||||
|
||||
SerializedObject targetAvatarPrefabObject = avatarPrefab != null ? new SerializedObject(avatarPrefab) : null;
|
||||
SerializedProperty propertyPrefabGuid = targetAvatarPrefabObject?.FindProperty(PropertyPrefabGuid);
|
||||
SerializedProperty propertyParentPrefab = targetAvatarPrefabObject?.FindProperty(PropertyParentPrefab);
|
||||
|
||||
if (propertyPrefabGuid != null && !string.IsNullOrEmpty(avatarPrefabGuid) && propertyPrefabGuid.stringValue != avatarPrefabGuid)
|
||||
{
|
||||
// Prefab information not added yet: add.
|
||||
propertyPrefabGuid.stringValue = avatarPrefabGuid;
|
||||
targetAvatarPrefabObject.ApplyModifiedProperties();
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
if (propertyParentPrefab != null && !ReferenceEquals(propertyParentPrefab.objectReferenceValue, parentPrefab))
|
||||
{
|
||||
// Parent prefab information not added yet: add.
|
||||
propertyParentPrefab.objectReferenceValue = parentPrefab;
|
||||
targetAvatarPrefabObject.ApplyModifiedProperties();
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
// Force instances getting parent prefab from their source prefab
|
||||
if (prefab != null && avatar.gameObject != prefab && propertyParentPrefab != null && _propertyParentPrefab.prefabOverride && !isPrefabStageSelected)
|
||||
{
|
||||
_propertyParentPrefab.prefabOverride = false;
|
||||
}
|
||||
|
||||
if (targetAvatarPrefabObject == null && (_propertyPrefabGuid.stringValue != string.Empty || _propertyParentPrefab.objectReferenceValue != null))
|
||||
{
|
||||
// Prefab information unlinked. Probably used "unpack prefab" functionality in Unity. Set references to null.
|
||||
_propertyPrefabGuid.stringValue = string.Empty;
|
||||
_propertyParentPrefab.objectReferenceValue = null;
|
||||
}
|
||||
|
||||
SerializedProperty propertyHandPoses = targetAvatarPrefabObject?.FindProperty(PropertyHandPoses);
|
||||
|
||||
if (propertyHandPoses != null)
|
||||
{
|
||||
// Check if we need to eliminate empty hand poses, references deleted without using the editor.
|
||||
|
||||
int deletedCount = 0;
|
||||
|
||||
for (int i = 0; i < propertyHandPoses.arraySize; ++i)
|
||||
{
|
||||
if (propertyHandPoses.GetArrayElementAtIndex(i).objectReferenceValue == null)
|
||||
{
|
||||
propertyHandPoses.DeleteArrayElementAtIndex(i);
|
||||
deletedCount++;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
if (deletedCount > 0)
|
||||
{
|
||||
targetAvatarPrefabObject.ApplyModifiedProperties();
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
// Check if we need to eliminate duplicated hand poses generated through prefab variants.
|
||||
|
||||
if (avatarPrefab != null && avatarParentPrefab != null)
|
||||
{
|
||||
IEnumerable<UxrHandPoseAsset> netHandPoses = avatarPrefab.GetHandPoses().Where(handPose => avatarParentPrefab.GetHandPoses().All(handPose2 => handPose != handPose2));
|
||||
|
||||
if (netHandPoses.Count() != propertyHandPoses.arraySize)
|
||||
{
|
||||
UxrEditorUtils.AssignSerializedPropertyArray(propertyHandPoses, netHandPoses);
|
||||
targetAvatarPrefabObject.ApplyModifiedProperties();
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!avatar.gameObject.IsPrefabRoot())
|
||||
{
|
||||
// Assistant
|
||||
|
||||
Camera camera = avatar.GetComponentInChildren<Camera>();
|
||||
Scene currentScene = avatar.gameObject.scene;
|
||||
|
||||
if (!UxrEditorUtils.PathIsInUltimateXR(currentScene.path) && prefab != null && UxrEditorUtils.PathIsInUltimateXR(AssetDatabase.GetAssetPath(prefab)))
|
||||
{
|
||||
EditorGUILayout.HelpBox(NeedsPrefabVariant, MessageType.Warning);
|
||||
|
||||
if (GUILayout.Button(ContentFix, GUILayout.Width(FixButtonWidth)))
|
||||
{
|
||||
if (UxrEditorUtils.CreateAvatarPrefab(avatar, "Save prefab variant", avatar.gameObject.name + "Variant", out prefab, out GameObject newInstance))
|
||||
{
|
||||
if (newInstance == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog(UxrConstants.Editor.Error, "The prefab variant was created but it could not be instantiated in the scene. Try doing it manually.", UxrConstants.Editor.Ok);
|
||||
}
|
||||
else
|
||||
{
|
||||
Selection.activeGameObject = newInstance.gameObject;
|
||||
avatar = newInstance.GetComponent<UxrAvatar>();
|
||||
avatar.name = prefab.name;
|
||||
}
|
||||
|
||||
// If in prefab stage, save
|
||||
PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
|
||||
|
||||
if (prefabStage != null && avatar.transform.parent != null)
|
||||
{
|
||||
// @TODO: Should save in innermost parent prefab, but currently the only way I found to force a save is using MarkSceneDirty
|
||||
EditorSceneManager.MarkSceneDirty(prefabStage.scene);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (camera == null)
|
||||
{
|
||||
camera = FindObjectOfType<Camera>();
|
||||
|
||||
if (camera == null || camera.SafeGetComponentInParent<UxrAvatar>() != null)
|
||||
{
|
||||
EditorGUILayout.HelpBox(NeedsCameraNewHelp, MessageType.Warning);
|
||||
|
||||
if (GUILayout.Button(ContentFix, GUILayout.Width(FixButtonWidth)))
|
||||
{
|
||||
GameObject cameraController = new GameObject("Camera Controller");
|
||||
cameraController.transform.SetPositionAndRotation(avatar.transform.position, avatar.transform.rotation);
|
||||
cameraController.transform.parent = avatar.transform;
|
||||
cameraController.transform.SetAsFirstSibling();
|
||||
Undo.RegisterCreatedObjectUndo(cameraController, "Create Camera Controller");
|
||||
|
||||
GameObject cameraObject = new GameObject("Camera");
|
||||
cameraObject.transform.SetPositionAndRotation(cameraController.transform.position, cameraController.transform.rotation);
|
||||
cameraObject.transform.parent = cameraController.transform;
|
||||
cameraObject.tag = "MainCamera";
|
||||
Undo.RegisterCreatedObjectUndo(cameraObject, "Create Camera");
|
||||
|
||||
Camera newCamera = cameraObject.AddComponent<Camera>();
|
||||
newCamera.nearClipPlane = 0.01f;
|
||||
cameraObject.AddComponent<AudioListener>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox(NeedsCameraReparentHelp, MessageType.Warning);
|
||||
|
||||
if (camera.transform.parent == null)
|
||||
{
|
||||
if (GUILayout.Button(ContentFix, GUILayout.Width(FixButtonWidth)))
|
||||
{
|
||||
GameObject cameraController = new GameObject("Camera Controller");
|
||||
cameraController.transform.SetPositionAndRotation(avatar.transform.position, avatar.transform.rotation);
|
||||
cameraController.transform.parent = avatar.transform;
|
||||
cameraController.transform.SetAsFirstSibling();
|
||||
Undo.RegisterCreatedObjectUndo(cameraController, "Create Camera Controller");
|
||||
|
||||
Undo.RecordObject(camera, "Set Camera Near");
|
||||
camera.nearClipPlane = 0.01f;
|
||||
|
||||
Undo.RecordObject(camera.transform, "Move Camera");
|
||||
camera.transform.SetPositionAndRotation(cameraController.transform.position, cameraController.transform.rotation);
|
||||
|
||||
Undo.SetTransformParent(camera.transform, cameraController.transform, "Re-parent Camera");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (camera.transform.parent == avatar.transform)
|
||||
{
|
||||
EditorGUILayout.HelpBox(NeedsCameraParentHelp, MessageType.Warning);
|
||||
|
||||
if (GUILayout.Button(ContentFix, GUILayout.Width(FixButtonWidth)))
|
||||
{
|
||||
GameObject cameraController = new GameObject("Camera Controller");
|
||||
cameraController.transform.SetPositionAndRotation(camera.transform.position, camera.transform.rotation);
|
||||
cameraController.transform.parent = avatar.transform;
|
||||
cameraController.transform.SetAsFirstSibling();
|
||||
Undo.RegisterCreatedObjectUndo(cameraController, "Create Camera Controller");
|
||||
Undo.SetTransformParent(camera.transform, cameraController.transform, "Re-parent Camera");
|
||||
Undo.RecordObject(camera, "Set Camera Near");
|
||||
camera.nearClipPlane = 0.01f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UxrAvatarController avatarController = avatar.GetComponentInChildren<UxrAvatarController>();
|
||||
|
||||
if (avatarController == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox(NeedsAvatarControllerHelp, MessageType.Warning);
|
||||
|
||||
if (GUILayout.Button(ContentFix, GUILayout.Width(FixButtonWidth)))
|
||||
{
|
||||
UxrStandardAvatarController standardAvatarController = avatar.gameObject.AddComponent<UxrStandardAvatarController>();
|
||||
Undo.RegisterCreatedObjectUndo(standardAvatarController, "Create Avatar Controller");
|
||||
}
|
||||
}
|
||||
else if (!avatar.AvatarRig.HasFullHandData())
|
||||
{
|
||||
EditorGUILayout.HelpBox(NeedsFingerSetup, MessageType.Warning);
|
||||
|
||||
if (GUILayout.Button(ContentFix, GUILayout.Width(FixButtonWidth)))
|
||||
{
|
||||
avatar.TryToInferMissingRigElements();
|
||||
|
||||
if (avatar.AvatarRig.HasAnyUpperBodyIKReference())
|
||||
{
|
||||
// Make avatar full-body if it has any upper body reference
|
||||
_propertyRigType.enumValueIndex = (int)UxrAvatarRigType.HalfOrFullBody;
|
||||
}
|
||||
|
||||
RefreshRigSerializedProperty(avatar);
|
||||
|
||||
if (!avatar.AvatarRig.HasFullHandData())
|
||||
{
|
||||
EditorUtility.DisplayDialog("Missing data", "Could not try to figure out all hand and finger bone references. Try setting them up manually under the Avatar rig section.", UxrConstants.Editor.Ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UxrTrackingDevice avatarTracking = avatar.GetComponentInChildren<UxrTrackingDevice>();
|
||||
|
||||
if (avatarTracking == null)
|
||||
{
|
||||
EditorGUILayout.HelpBox(NeedsIntegrationHelp, MessageType.Warning);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
string integrationPrefabGuid = null;
|
||||
|
||||
if (GUILayout.Button(ContentBigHandsIntegration, GUILayout.Width(FixButtonWidth)))
|
||||
{
|
||||
integrationPrefabGuid = BigHandsIntegrationGuid;
|
||||
}
|
||||
|
||||
if (GUILayout.Button(ContentSmallHandsIntegration, GUILayout.Width(FixButtonWidth)))
|
||||
{
|
||||
integrationPrefabGuid = SmallHandsIntegrationGuid;
|
||||
}
|
||||
|
||||
if (integrationPrefabGuid != null)
|
||||
{
|
||||
// Add hand integration and try to place on avatar hands
|
||||
|
||||
GameObject handsIntegrationAsset = AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GUIDToAssetPath(integrationPrefabGuid));
|
||||
|
||||
if (handsIntegrationAsset != null)
|
||||
{
|
||||
GameObject handsIntegration = PrefabUtility.InstantiatePrefab(handsIntegrationAsset, avatar.transform) as GameObject;
|
||||
|
||||
if (handsIntegration)
|
||||
{
|
||||
handsIntegration.name = handsIntegrationAsset.name;
|
||||
Undo.RegisterCreatedObjectUndo(handsIntegration, "Add Hands Integration");
|
||||
|
||||
handsIntegration.GetComponentsInChildren<UxrHandIntegration>().ForEach(i => i.TryToMatchHand());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
else if (avatar.GetComponent<IUxrNetworkAvatar>() != null)
|
||||
{
|
||||
EditorGUILayout.HelpBox(IsMultiplayerPrefab, MessageType.Warning);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox("Avatar is ready to rock!", MessageType.Info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
// Rest of inspector
|
||||
|
||||
_foldoutGeneral = UxrEditorUtils.FoldoutStylish("General parameters:", _foldoutGeneral);
|
||||
|
||||
if (_foldoutGeneral)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
EditorGUILayout.ObjectField(ContentPrefab, prefab, typeof(GameObject), false);
|
||||
EditorGUILayout.PropertyField(_propertyParentPrefab, ContentParentPrefab);
|
||||
GUI.enabled = true;
|
||||
EditorGUILayout.PropertyField(_propertyAvatarMode, ContentAvatarMode);
|
||||
}
|
||||
|
||||
// Renderers
|
||||
|
||||
_foldoutRendering = UxrEditorUtils.FoldoutStylish("Avatar rendering:", _foldoutRendering);
|
||||
|
||||
if (_foldoutRendering)
|
||||
{
|
||||
_propertyRenderMode.intValue = EditorGUILayout.MaskField(ContentRenderMode, _propertyRenderMode.intValue, UxrEditorUtils.GetAvatarRenderModeNames().SplitCamelCase().ToArray());
|
||||
EditorGUILayout.PropertyField(_propertyShowControllerHands, ContentShowControllerHands);
|
||||
EditorGUILayout.PropertyField(_propertyAvatarRenderers, ContentAvatarRenderers, true);
|
||||
}
|
||||
|
||||
// Rig
|
||||
|
||||
_propertyRigFoldout.boolValue = UxrEditorUtils.FoldoutStylish("Avatar rig:", _propertyRigFoldout.boolValue);
|
||||
|
||||
if (_propertyRigFoldout.boolValue)
|
||||
{
|
||||
if (_propertyRigType.enumValueIndex == (int)UxrAvatarRigType.HandsOnly)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propertyRigType, ContentRigType);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button(ContentTryToFillGuessing, GUILayout.Width(ButtonWidth)))
|
||||
{
|
||||
avatar.TryToInferMissingRigElements();
|
||||
RefreshRigSerializedProperty(avatar);
|
||||
}
|
||||
|
||||
if (GUILayout.Button(ContentClearRig, GUILayout.Width(ButtonWidth)))
|
||||
{
|
||||
avatar.ClearRigElements();
|
||||
RefreshRigSerializedProperty(avatar);
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.PropertyField(_propertyRig.FindPropertyRelative("_head").FindPropertyRelative("_head"), ContentHead);
|
||||
EditorGUILayout.PropertyField(_propertyRig.FindPropertyRelative("_leftArm").FindPropertyRelative("_hand"), ContentLeftHand);
|
||||
EditorGUILayout.PropertyField(_propertyRig.FindPropertyRelative("_rightArm").FindPropertyRelative("_hand"), ContentRightHand);
|
||||
}
|
||||
else if (_propertyRigType.enumValueIndex == (int)UxrAvatarRigType.HalfOrFullBody)
|
||||
{
|
||||
EditorGUILayout.PropertyField(_propertyRigType, ContentRigType);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
if (GUILayout.Button(ContentAutoFillFromAnimator, GUILayout.Width(ButtonWidth)))
|
||||
{
|
||||
if (!avatar.SetupRigElementsFromAnimator())
|
||||
{
|
||||
EditorUtility.DisplayDialog("Animator data is missing", "Could not find any Animator component with humanoid data. Please use a model with a humanoid avatar to use autofill.", UxrConstants.Editor.Ok);
|
||||
}
|
||||
else
|
||||
{
|
||||
RefreshRigSerializedProperty(avatar);
|
||||
}
|
||||
}
|
||||
|
||||
if (GUILayout.Button(ContentTryToFillGuessing, GUILayout.Width(ButtonWidth)))
|
||||
{
|
||||
avatar.TryToInferMissingRigElements();
|
||||
RefreshRigSerializedProperty(avatar);
|
||||
}
|
||||
|
||||
if (GUILayout.Button(ContentClearRig, GUILayout.Width(ButtonWidth)))
|
||||
{
|
||||
avatar.ClearRigElements();
|
||||
RefreshRigSerializedProperty(avatar);
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space();
|
||||
|
||||
EditorGUILayout.PropertyField(_propertyRig, ContentRig);
|
||||
}
|
||||
}
|
||||
|
||||
// Hand poses
|
||||
|
||||
bool createPrefab = false;
|
||||
|
||||
_propertyHandPosesFoldout.boolValue = UxrEditorUtils.FoldoutStylish("Hand poses:", _propertyHandPosesFoldout.boolValue);
|
||||
|
||||
if (_propertyHandPosesFoldout.boolValue)
|
||||
{
|
||||
if (string.IsNullOrEmpty(avatar.PrefabGuid))
|
||||
{
|
||||
GUILayout.Label("Avatar requires a prefab in order to use hand poses.");
|
||||
|
||||
if (UxrEditorUtils.CenteredButton(ContentCreatePrefab))
|
||||
{
|
||||
// Create prefab at the end.
|
||||
createPrefab = true;
|
||||
}
|
||||
}
|
||||
else if (!avatar.GetAllHandPoses().Any())
|
||||
{
|
||||
GUILayout.Label("No hand poses available. Use the Hand Pose Editor to add hand poses.");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (UxrAvatar avatarChainPrefab in avatar.GetPrefabChain())
|
||||
{
|
||||
IEnumerable<UxrHandPoseAsset> handPoses = avatarChainPrefab.GetHandPoses();
|
||||
|
||||
if (handPoses.Any())
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
if (avatarChainPrefab != avatarPrefab)
|
||||
{
|
||||
GUILayout.Label($"{handPoses.Count()} inherited from {avatarChainPrefab.name}:");
|
||||
|
||||
if (GUILayout.Button(ContentSelectPrefab))
|
||||
{
|
||||
Selection.activeObject = AssetDatabase.LoadAssetAtPath<UxrAvatar>(AssetDatabase.GetAssetPath(avatarChainPrefab));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Label($"{handPoses.Count()} in {avatarChainPrefab.name}:");
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
foreach (UxrHandPoseAsset pose in handPoses)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField($"{pose.name}: ", $"Type: {pose.PoseType.ToString()}");
|
||||
|
||||
if (GUILayout.Button(ContentSelectPoseAsset))
|
||||
{
|
||||
Selection.activeObject = AssetDatabase.LoadAssetAtPath<UxrHandPoseAsset>(AssetDatabase.GetAssetPath(pose));
|
||||
}
|
||||
|
||||
if (!avatar.IsInPrefab())
|
||||
{
|
||||
if (!avatar.IsHandPoseOverriden(pose) && GUILayout.Button(ContentOpenPose))
|
||||
{
|
||||
UxrHandPoseEditorWindow.Open(avatar, pose);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
// EditorGUILayout.PropertyField(serializedObject.FindProperty("_handPoses"));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(avatar.PrefabGuid) && !avatar.IsInPrefab() && !UxrHandPoseEditorWindow.IsVisible && UxrEditorUtils.CenteredButton(ContentOpenHandPoseEditor, -1))
|
||||
{
|
||||
UxrHandPoseEditorWindow.Open(avatar);
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
if (createPrefab)
|
||||
{
|
||||
if (UxrEditorUtils.CreateAvatarPrefab(avatar, "Save prefab", avatar.gameObject.name, out prefab, out GameObject newInstance))
|
||||
{
|
||||
if (newInstance == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog(UxrConstants.Editor.Error, "The prefab was created but it could not be instantiated in the scene. Try doing it manually.", UxrConstants.Editor.Ok);
|
||||
}
|
||||
else
|
||||
{
|
||||
Selection.activeGameObject = newInstance.gameObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws visual guides on the avatar.
|
||||
/// </summary>
|
||||
private void OnSceneGUI()
|
||||
{
|
||||
UxrAvatar avatar = (UxrAvatar)serializedObject.targetObject;
|
||||
|
||||
if (avatar == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
// Draw finger tips and finger print positions
|
||||
|
||||
Color handlesColor = Handles.color;
|
||||
Handles.matrix = Matrix4x4.identity;
|
||||
|
||||
foreach (UxrAvatarArmInfo arm in avatar.AvatarRigInfo.Arms)
|
||||
{
|
||||
foreach (UxrAvatarFingerInfo finger in arm.Fingers)
|
||||
{
|
||||
Handles.color = ColorExt.ColorAlpha(Color.blue, UxrEditorUtils.HandlesAlpha);
|
||||
Handles.DrawSolidDisc(finger.TipPosition, finger.TipDirection, 0.004f);
|
||||
Handles.color = ColorExt.ColorAlpha(Color.green, UxrEditorUtils.HandlesAlpha);
|
||||
Handles.DrawSolidDisc(finger.FingerPrintPosition, finger.FingerPrintDirection, 0.004f);
|
||||
}
|
||||
}
|
||||
|
||||
Handles.color = handlesColor;
|
||||
*/
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the rig information.
|
||||
/// </summary>
|
||||
/// <param name="avatar">Avatar whose rig to refresh</param>
|
||||
private void RefreshRigSerializedProperty(UxrAvatar avatar)
|
||||
{
|
||||
// Head
|
||||
|
||||
serializedObject.FindProperty("_rig._head._leftEye").objectReferenceValue = avatar.AvatarRig.Head.LeftEye;
|
||||
serializedObject.FindProperty("_rig._head._rightEye").objectReferenceValue = avatar.AvatarRig.Head.RightEye;
|
||||
serializedObject.FindProperty("_rig._head._jaw").objectReferenceValue = avatar.AvatarRig.Head.Jaw;
|
||||
serializedObject.FindProperty("_rig._head._head").objectReferenceValue = avatar.AvatarRig.Head.Head;
|
||||
serializedObject.FindProperty("_rig._head._neck").objectReferenceValue = avatar.AvatarRig.Head.Neck;
|
||||
|
||||
// Body
|
||||
|
||||
serializedObject.FindProperty("_rig._upperChest").objectReferenceValue = avatar.AvatarRig.UpperChest;
|
||||
serializedObject.FindProperty("_rig._chest").objectReferenceValue = avatar.AvatarRig.Chest;
|
||||
serializedObject.FindProperty("_rig._spine").objectReferenceValue = avatar.AvatarRig.Spine;
|
||||
serializedObject.FindProperty("_rig._hips").objectReferenceValue = avatar.AvatarRig.Hips;
|
||||
|
||||
// Left arm
|
||||
|
||||
serializedObject.FindProperty("_rig._leftArm._clavicle").objectReferenceValue = avatar.AvatarRig.LeftArm.Clavicle;
|
||||
serializedObject.FindProperty("_rig._leftArm._upperArm").objectReferenceValue = avatar.AvatarRig.LeftArm.UpperArm;
|
||||
serializedObject.FindProperty("_rig._leftArm._forearm").objectReferenceValue = avatar.AvatarRig.LeftArm.Forearm;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._wrist").objectReferenceValue = avatar.LeftHandBone;
|
||||
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._thumb._metacarpal").objectReferenceValue = avatar.LeftHand.Thumb.Metacarpal;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._thumb._proximal").objectReferenceValue = avatar.LeftHand.Thumb.Proximal;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._thumb._intermediate").objectReferenceValue = avatar.LeftHand.Thumb.Intermediate;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._thumb._distal").objectReferenceValue = avatar.LeftHand.Thumb.Distal;
|
||||
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._index._metacarpal").objectReferenceValue = avatar.LeftHand.Index.Metacarpal;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._index._proximal").objectReferenceValue = avatar.LeftHand.Index.Proximal;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._index._intermediate").objectReferenceValue = avatar.LeftHand.Index.Intermediate;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._index._distal").objectReferenceValue = avatar.LeftHand.Index.Distal;
|
||||
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._middle._metacarpal").objectReferenceValue = avatar.LeftHand.Middle.Metacarpal;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._middle._proximal").objectReferenceValue = avatar.LeftHand.Middle.Proximal;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._middle._intermediate").objectReferenceValue = avatar.LeftHand.Middle.Intermediate;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._middle._distal").objectReferenceValue = avatar.LeftHand.Middle.Distal;
|
||||
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._ring._metacarpal").objectReferenceValue = avatar.LeftHand.Ring.Metacarpal;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._ring._proximal").objectReferenceValue = avatar.LeftHand.Ring.Proximal;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._ring._intermediate").objectReferenceValue = avatar.LeftHand.Ring.Intermediate;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._ring._distal").objectReferenceValue = avatar.LeftHand.Ring.Distal;
|
||||
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._little._metacarpal").objectReferenceValue = avatar.LeftHand.Little.Metacarpal;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._little._proximal").objectReferenceValue = avatar.LeftHand.Little.Proximal;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._little._intermediate").objectReferenceValue = avatar.LeftHand.Little.Intermediate;
|
||||
serializedObject.FindProperty("_rig._leftArm._hand._little._distal").objectReferenceValue = avatar.LeftHand.Little.Distal;
|
||||
|
||||
// Right arm
|
||||
|
||||
serializedObject.FindProperty("_rig._rightArm._clavicle").objectReferenceValue = avatar.AvatarRig.RightArm.Clavicle;
|
||||
serializedObject.FindProperty("_rig._rightArm._upperArm").objectReferenceValue = avatar.AvatarRig.RightArm.UpperArm;
|
||||
serializedObject.FindProperty("_rig._rightArm._forearm").objectReferenceValue = avatar.AvatarRig.RightArm.Forearm;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._wrist").objectReferenceValue = avatar.RightHandBone;
|
||||
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._thumb._metacarpal").objectReferenceValue = avatar.RightHand.Thumb.Metacarpal;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._thumb._proximal").objectReferenceValue = avatar.RightHand.Thumb.Proximal;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._thumb._intermediate").objectReferenceValue = avatar.RightHand.Thumb.Intermediate;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._thumb._distal").objectReferenceValue = avatar.RightHand.Thumb.Distal;
|
||||
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._index._metacarpal").objectReferenceValue = avatar.RightHand.Index.Metacarpal;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._index._proximal").objectReferenceValue = avatar.RightHand.Index.Proximal;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._index._intermediate").objectReferenceValue = avatar.RightHand.Index.Intermediate;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._index._distal").objectReferenceValue = avatar.RightHand.Index.Distal;
|
||||
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._middle._metacarpal").objectReferenceValue = avatar.RightHand.Middle.Metacarpal;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._middle._proximal").objectReferenceValue = avatar.RightHand.Middle.Proximal;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._middle._intermediate").objectReferenceValue = avatar.RightHand.Middle.Intermediate;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._middle._distal").objectReferenceValue = avatar.RightHand.Middle.Distal;
|
||||
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._ring._metacarpal").objectReferenceValue = avatar.RightHand.Ring.Metacarpal;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._ring._proximal").objectReferenceValue = avatar.RightHand.Ring.Proximal;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._ring._intermediate").objectReferenceValue = avatar.RightHand.Ring.Intermediate;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._ring._distal").objectReferenceValue = avatar.RightHand.Ring.Distal;
|
||||
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._little._metacarpal").objectReferenceValue = avatar.RightHand.Little.Metacarpal;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._little._proximal").objectReferenceValue = avatar.RightHand.Little.Proximal;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._little._intermediate").objectReferenceValue = avatar.RightHand.Little.Intermediate;
|
||||
serializedObject.FindProperty("_rig._rightArm._hand._little._distal").objectReferenceValue = avatar.RightHand.Little.Distal;
|
||||
|
||||
// Left leg
|
||||
|
||||
serializedObject.FindProperty("_rig._leftLeg._upperLeg").objectReferenceValue = avatar.AvatarRig.LeftLeg.UpperLeg;
|
||||
serializedObject.FindProperty("_rig._leftLeg._lowerLeg").objectReferenceValue = avatar.AvatarRig.LeftLeg.LowerLeg;
|
||||
serializedObject.FindProperty("_rig._leftLeg._foot").objectReferenceValue = avatar.AvatarRig.LeftLeg.Foot;
|
||||
serializedObject.FindProperty("_rig._leftLeg._toes").objectReferenceValue = avatar.AvatarRig.LeftLeg.Toes;
|
||||
|
||||
// Right leg
|
||||
|
||||
serializedObject.FindProperty("_rig._rightLeg._upperLeg").objectReferenceValue = avatar.AvatarRig.RightLeg.UpperLeg;
|
||||
serializedObject.FindProperty("_rig._rightLeg._lowerLeg").objectReferenceValue = avatar.AvatarRig.RightLeg.LowerLeg;
|
||||
serializedObject.FindProperty("_rig._rightLeg._foot").objectReferenceValue = avatar.AvatarRig.RightLeg.Foot;
|
||||
serializedObject.FindProperty("_rig._rightLeg._toes").objectReferenceValue = avatar.AvatarRig.RightLeg.Toes;
|
||||
|
||||
// Clear torsion nodes if they exist
|
||||
|
||||
if (avatar.AvatarRig.LeftArm.Forearm == null && avatar.AvatarRig.RightArm.Forearm == null)
|
||||
{
|
||||
avatar.GetComponentsInChildren<UxrWristTorsionIKSolver>().ForEach(Undo.DestroyObjectImmediate);
|
||||
}
|
||||
|
||||
// Update standard avatar controller info
|
||||
|
||||
UxrAvatarController avatarController = avatar.GetComponent<UxrAvatarController>();
|
||||
|
||||
if (avatarController is UxrStandardAvatarController standardAvatarController)
|
||||
{
|
||||
SerializedObject serializedAvatarController = new SerializedObject(standardAvatarController);
|
||||
SerializedProperty propIKSettings = serializedAvatarController.FindProperty(UxrStandardAvatarControllerEditor.PropBodyIKSettings);
|
||||
|
||||
serializedAvatarController.Update();
|
||||
|
||||
// Try to set eye base height and forward offset
|
||||
|
||||
if (avatar.AvatarRig.Head.LeftEye && avatar.AvatarRig.Head.RightEye)
|
||||
{
|
||||
Vector3 eyeLeft = avatar.transform.InverseTransformPoint(avatar.AvatarRig.Head.LeftEye.position);
|
||||
Vector3 eyeRight = avatar.transform.InverseTransformPoint(avatar.AvatarRig.Head.RightEye.position);
|
||||
|
||||
propIKSettings.FindPropertyRelative(UxrIKBodySettingsDrawer.PropertyEyesBaseHeight).floatValue = (avatar.AvatarRig.Head.LeftEye.position.y + avatar.AvatarRig.Head.RightEye.position.y) * 0.5f - avatar.transform.position.y;
|
||||
propIKSettings.FindPropertyRelative(UxrIKBodySettingsDrawer.PropertyEyesForwardOffset).floatValue = (eyeLeft.z + eyeRight.z) * 0.5f + 0.02f;
|
||||
}
|
||||
else if (avatar.AvatarRig.Head.Head != null)
|
||||
{
|
||||
propIKSettings.FindPropertyRelative(UxrIKBodySettingsDrawer.PropertyEyesBaseHeight).floatValue = (avatar.AvatarRig.Head.Head.position.y - avatar.transform.position.y) + 0.1f;
|
||||
propIKSettings.FindPropertyRelative(UxrIKBodySettingsDrawer.PropertyEyesForwardOffset).floatValue = 0.15f;
|
||||
}
|
||||
|
||||
// If a neck wasn't found, try to set neck base height and forward setting using the head node
|
||||
|
||||
if (avatar.AvatarRig.Head.Neck == null && avatar.AvatarRig.Head.Head != null)
|
||||
{
|
||||
propIKSettings.FindPropertyRelative(UxrIKBodySettingsDrawer.PropertyNeckBaseHeight).floatValue = (avatar.AvatarRig.Head.Head.position.y - avatar.transform.position.y) - 0.1f;
|
||||
propIKSettings.FindPropertyRelative(UxrIKBodySettingsDrawer.PropertyNeckForwardOffset).floatValue = 0.0f;
|
||||
}
|
||||
|
||||
serializedAvatarController.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Types & Data
|
||||
|
||||
private GUIContent ContentFix { get; } = new GUIContent("Fix", "Fixes the issue above automatically");
|
||||
private GUIContent ContentBigHandsIntegration { get; } = new GUIContent("Use Big hands", "Adds the BigHandsIntegration prefab to the avatar, which includes functionality to use tracking/input devices and also interact with the environment using manipulation, locomotion etc.");
|
||||
private GUIContent ContentSmallHandsIntegration { get; } = new GUIContent("Use Small hands", "Adds the SmallHandsIntegration prefab to the avatar, which includes functionality to use tracking/input devices and also interact with the environment using manipulation, locomotion etc.");
|
||||
private GUIContent ContentCreatePrefab { get; } = new GUIContent("Create Prefab", "Creates a prefab for this avatar");
|
||||
private GUIContent ContentAutoFillFromAnimator { get; } = new GUIContent("Autofill from Animator", "");
|
||||
private GUIContent ContentTryToFillGuessing { get; } = new GUIContent("Try to fill", "");
|
||||
private GUIContent ContentClearRig { get; } = new GUIContent("Clear", "");
|
||||
private GUIContent ContentSelectPrefab { get; } = new GUIContent("Select prefab", "");
|
||||
private GUIContent ContentSelectPoseAsset { get; } = new GUIContent("Select", "");
|
||||
private GUIContent ContentOpenPose { get; } = new GUIContent("Open", "");
|
||||
private GUIContent ContentOpenHandPoseEditor { get; } = new GUIContent("Open Hand Pose Editor...", "");
|
||||
private GUIContent ContentHead { get; } = new GUIContent("Head (optional)", "");
|
||||
private GUIContent ContentLeftHand { get; } = new GUIContent("Left Hand", "");
|
||||
private GUIContent ContentRightHand { get; } = new GUIContent("Right Hand", "");
|
||||
private GUIContent ContentPrefab { get; } = new GUIContent("Prefab", "");
|
||||
private GUIContent ContentParentPrefab { get; } = new GUIContent("Parent Prefab", "");
|
||||
private GUIContent ContentAvatarMode { get; } = new GUIContent("Avatar Mode", "Local Avatars are updated automatically using the headset and controllers, while UpdateExternally avatars are not updated and act as puppets that should be updated manually. They are useful in multiplayer applications for the remote avatars.");
|
||||
private GUIContent ContentRenderMode { get; } = new GUIContent("Render Mode", "Controls the way the avatar will be rendered. Avatar mode is the default but for tutorials, menus and other cases rendering the controllers may be more convenient");
|
||||
private GUIContent ContentShowControllerHands { get; } = new GUIContent("Show Controller Hands", "If the render mode is set to render the controllers, will the hands that come with them also be rendered? Set it to false to render the controllers only. Set it to true if you want some fancy hands with IK on top of them");
|
||||
private GUIContent ContentAvatarRenderers { get; } = new GUIContent("Avatar Renderers", "The list of renderers that make up the avatar when rendered in-game. This is used to switch between rendering the avatar or the controllers or both");
|
||||
private GUIContent ContentRigType { get; } = new GUIContent("Rig Type", "");
|
||||
private GUIContent ContentRig { get; } = new GUIContent("Rig", "");
|
||||
|
||||
private const int ButtonWidth = 140;
|
||||
private const int FixButtonWidth = 120;
|
||||
private const string NeedsPrefabVariant = "It is recommended to create a prefab variant in your project instead of using an UltimateXR prefab directly. When UltimateXR is updated, all the prefabs could be overwritten and changes would be lost. Using a prefab variant in your project allows to keep all changes and still get the improvements included in the updates.";
|
||||
private const string NeedsCameraNewHelp = "The avatar has no Camera in its hierarchy. It needs a Camera to render the view in VR";
|
||||
private const string NeedsCameraReparentHelp = "The scene camera needs to be placed in the avatar hierarchy to render the view correctly in VR";
|
||||
private const string NeedsCameraParentHelp = "In order to be able to reposition the camera at runtime please parent the camera to a child of the avatar root GameObject instead of being a child directly. We will call this the Camera Controller.";
|
||||
private const string NeedsAvatarControllerHelp = "The avatar needs an UxrAvatarController component that will take care of updating all its components. You can add an UxrStandardAvatarController component or provide your own for advanced custom avatar handling.";
|
||||
private const string NeedsFingerSetup = "The avatar rig has no hand or finger bone references assigned yet. They are required to use hand poses and set up hand integrations.";
|
||||
private const string NeedsIntegrationHelp = "The avatar has no support for tracking/input devices yet. You can use one of the below integrations to leverage this work for you. The hand size will only determine the type of hands that will be shown when the input controllers are visualized instead of the avatar hands.";
|
||||
private const string IsMultiplayerPrefab = "This avatar is a prefab intended for multiplayer. Multiplayer prefabs are spawned at runtime, either by the user or with the help of UxrNetworkManager, and should not be pre-instantiated in the scene. Please consider removing this avatar from the scene.";
|
||||
private const string BigHandsIntegrationGuid = "2f7a5d0166ab0d041bed38f7cc6affef";
|
||||
private const string SmallHandsIntegrationGuid = "dde1cc2a360069149a781772e8410006";
|
||||
|
||||
private SerializedProperty _propertyPrefabGuid;
|
||||
private SerializedProperty _propertyParentPrefab;
|
||||
private SerializedProperty _propertyAvatarMode;
|
||||
private SerializedProperty _propertyRenderMode;
|
||||
private SerializedProperty _propertyShowControllerHands;
|
||||
private SerializedProperty _propertyAvatarRenderers;
|
||||
private SerializedProperty _propertyRigType;
|
||||
private SerializedProperty _propertyRigExpandedInitialized;
|
||||
private SerializedProperty _propertyRigFoldout;
|
||||
private SerializedProperty _propertyRig;
|
||||
private SerializedProperty _propertyHandPosesFoldout;
|
||||
private SerializedProperty _propertyHandPoses;
|
||||
|
||||
private bool _foldoutGeneral = true;
|
||||
private bool _foldoutRendering = true;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrAvatarEditor.cs.meta
vendored
Normal file
12
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrAvatarEditor.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ab9e5d4f31d7c054b87190a33a3cabb6
|
||||
timeCreated: 1501659089
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
108
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrAvatarEditorExt.cs
vendored
Normal file
108
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrAvatarEditorExt.cs
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrAvatarEditorExt.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using UltimateXR.Avatar;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UltimateXR.Editor.Avatar
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="UxrAvatar" /> extensions available only for editor scripts.
|
||||
/// </summary>
|
||||
public static class UxrAvatarEditorExt
|
||||
{
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="UxrAvatar" />'s prefab, based on the Guid stored.
|
||||
/// </summary>
|
||||
/// <param name="self">Avatar to get the source prefab of</param>
|
||||
/// <returns>Prefab or null if it could not be found</returns>
|
||||
public static GameObject GetPrefab(this UxrAvatar self)
|
||||
{
|
||||
return AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GUIDToAssetPath(self.PrefabGuid));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="UxrAvatar" /> prefab's <see cref="UxrAvatar" /> component, based on the Guid stored.
|
||||
/// </summary>
|
||||
/// <param name="self">Avatar to get the source prefab of</param>
|
||||
/// <returns>Prefab or null if it could not be found</returns>
|
||||
public static UxrAvatar GetAvatarPrefab(this UxrAvatar self)
|
||||
{
|
||||
return GetFromGuid(self.PrefabGuid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a prefab's GUID.
|
||||
/// </summary>
|
||||
/// <param name="gameObject">Prefab to get the GUID of</param>
|
||||
/// <returns>GUID or empty string if it could not be found</returns>
|
||||
public static string GetGuid(GameObject gameObject)
|
||||
{
|
||||
return AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(gameObject));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="UxrAvatar" /> prefab, based on an asset GUID.
|
||||
/// </summary>
|
||||
/// <param name="avatarPrefabGuid">Asset GUID</param>
|
||||
/// <returns>Prefab or null if it could not be found</returns>
|
||||
public static UxrAvatar GetFromGuid(string avatarPrefabGuid)
|
||||
{
|
||||
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GUIDToAssetPath(avatarPrefabGuid));
|
||||
return prefab != null ? prefab.GetComponent<UxrAvatar>() : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the avatar prefab chain. This is the source prefab followed by all parent prefabs up to the root parent
|
||||
/// prefab.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Upwards prefab chain. If the avatar is a prefab itself, it will be the first item in the list.
|
||||
/// </returns>
|
||||
public static IEnumerable<UxrAvatar> GetPrefabChain(this UxrAvatar self)
|
||||
{
|
||||
UxrAvatar avatarPrefab = self.GetAvatarPrefab();
|
||||
|
||||
if (avatarPrefab != null)
|
||||
{
|
||||
yield return avatarPrefab;
|
||||
}
|
||||
|
||||
UxrAvatar current = self.ParentAvatarPrefab;
|
||||
|
||||
while (current != null)
|
||||
{
|
||||
yield return current;
|
||||
|
||||
current = current.ParentAvatarPrefab;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the avatar is or comes from the given prefab.
|
||||
/// </summary>
|
||||
/// <param name="self">Avatar</param>
|
||||
/// <param name="prefab">Prefab</param>
|
||||
/// <returns>Whether the avatar is or comes from the given prefab</returns>
|
||||
public static bool IsInPrefabChain(this UxrAvatar self, GameObject prefab)
|
||||
{
|
||||
foreach (UxrAvatar avatarPrefab in self.GetPrefabChain())
|
||||
{
|
||||
if (avatarPrefab != null && avatarPrefab.gameObject == prefab)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
11
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrAvatarEditorExt.cs.meta
vendored
Normal file
11
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrAvatarEditorExt.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e99978505dd0ec4faf3fb7e0fb22a76
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
23
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrHandIntegrationEditor.RenderPipeline.cs
vendored
Normal file
23
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrHandIntegrationEditor.RenderPipeline.cs
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrHandIntegrationEditor.RenderPipeline.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
namespace UltimateXR.Editor.Avatar
|
||||
{
|
||||
public partial class UxrHandIntegrationEditor
|
||||
{
|
||||
#region Private Types & Data
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates the supported render pipeline material variations.
|
||||
/// </summary>
|
||||
private enum RenderPipeline
|
||||
{
|
||||
Brp = 0,
|
||||
Urp
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
3
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrHandIntegrationEditor.RenderPipeline.cs.meta
vendored
Normal file
3
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrHandIntegrationEditor.RenderPipeline.cs.meta
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffadeb7d00884d79bc722da4e20739aa
|
||||
timeCreated: 1653306477
|
||||
530
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrHandIntegrationEditor.cs
vendored
Normal file
530
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrHandIntegrationEditor.cs
vendored
Normal file
@@ -0,0 +1,530 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="UxrHandIntegrationEditor.cs" company="VRMADA">
|
||||
// Copyright (c) VRMADA, All rights reserved.
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UltimateXR.Avatar;
|
||||
using UltimateXR.Core;
|
||||
using UltimateXR.Devices.Visualization;
|
||||
using UltimateXR.Extensions.System.Collections;
|
||||
using UltimateXR.Extensions.System.IO;
|
||||
using UltimateXR.Extensions.Unity;
|
||||
using UltimateXR.Manipulation;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UltimateXR.Editor.Avatar
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom editor for <see cref="UxrHandIntegration" />.
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(UxrHandIntegration))]
|
||||
public partial class UxrHandIntegrationEditor : UnityEditor.Editor
|
||||
{
|
||||
#region Unity
|
||||
|
||||
/// <summary>
|
||||
/// Caches the serialized properties, the different variations and creates the temporal hand gizmo.
|
||||
/// </summary>
|
||||
private void OnEnable()
|
||||
{
|
||||
_propertyGizmoHandSize = serializedObject.FindProperty("_gizmoHandSize");
|
||||
_propertyHandSide = serializedObject.FindProperty("_handSide");
|
||||
_propertyObjectVariationName = serializedObject.FindProperty("_objectVariationName");
|
||||
_propertyMaterialVariationName = serializedObject.FindProperty("_materialVariationName");
|
||||
_propertySelectedRenderPipeline = serializedObject.FindProperty("_selectedRenderPipeline");
|
||||
|
||||
_handIntegration = serializedObject.targetObject as UxrHandIntegration;
|
||||
_objectVariationNames = GetCommonObjectVariationNames();
|
||||
_materialVariationNames = GetCommonMaterialVariationNames(_propertyObjectVariationName.name);
|
||||
|
||||
GetControllerPipelineRenderers(out _renderers, out _renderPipelineVariations, out _renderPipelineVariationStrings, out _selectedRenderPipelineIndex);
|
||||
|
||||
serializedObject.Update();
|
||||
_propertySelectedRenderPipeline.intValue = _selectedRenderPipelineIndex;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
UxrGrabber[] grabbers = _handIntegration.GetComponentsInChildren<UxrGrabber>();
|
||||
|
||||
foreach (UxrGrabber grabber in grabbers)
|
||||
{
|
||||
if (grabber.HandRenderer == null)
|
||||
{
|
||||
// Do nothing, we just try to force to get the hand renderer reference if it doesn't exist or is inactive
|
||||
}
|
||||
}
|
||||
|
||||
CreateTemporalObjects();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the temporal hand gizmo.
|
||||
/// </summary>
|
||||
private void OnDisable()
|
||||
{
|
||||
DestroyTemporalObjects();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
bool variationChanged = false;
|
||||
bool renderPipelineChanged = false;
|
||||
|
||||
// Gizmo hand size (read-only so that it can only be changed in debug mode).
|
||||
|
||||
GUI.enabled = false;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(_propertyGizmoHandSize, ContentGizmoHandSize);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
RegenerateTemporalObjects();
|
||||
}
|
||||
|
||||
GUI.enabled = true;
|
||||
|
||||
// Hand side
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(_propertyHandSide, ContentHandSide);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
RegenerateTemporalObjects();
|
||||
}
|
||||
|
||||
// Select object variation
|
||||
|
||||
if (_objectVariationNames.Count > 0)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
int handIndex = EditorGUILayout.Popup(ContentObjectVariationName, _objectVariationNames.IndexOf(_propertyObjectVariationName.stringValue), UxrEditorUtils.ToGUIContentArray(_objectVariationNames));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
variationChanged = true;
|
||||
_propertyObjectVariationName.stringValue = _objectVariationNames[handIndex];
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
_materialVariationNames = GetCommonMaterialVariationNames(_propertyObjectVariationName.stringValue);
|
||||
}
|
||||
|
||||
// Select material variation
|
||||
|
||||
if (_materialVariationNames.Count > 0)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
int materialIndex = EditorGUILayout.Popup(ContentMaterialVariationName, _materialVariationNames.IndexOf(_propertyMaterialVariationName.stringValue), UxrEditorUtils.ToGUIContentArray(_materialVariationNames));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
variationChanged = true;
|
||||
_propertyMaterialVariationName.stringValue = _materialVariationNames[materialIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// Select Render Pipeline variation
|
||||
|
||||
if (_renderPipelineVariations.Count > 1)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
_propertySelectedRenderPipeline.intValue = EditorGUILayout.Popup(ContentRenderPipeline, _propertySelectedRenderPipeline.intValue, UxrEditorUtils.ToGUIContentArray(_renderPipelineVariationStrings));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
renderPipelineChanged = true;
|
||||
_selectedRenderPipelineIndex = _propertySelectedRenderPipeline.intValue;
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
// Enable new variation
|
||||
|
||||
if (variationChanged)
|
||||
{
|
||||
EnableCurrentVariation(_propertyObjectVariationName.stringValue, _propertyMaterialVariationName.stringValue);
|
||||
}
|
||||
|
||||
if (renderPipelineChanged)
|
||||
{
|
||||
EnableCurrentRenderPipeline(_renderers, _renderPipelineVariations[_selectedRenderPipelineIndex]);
|
||||
}
|
||||
|
||||
// Alignment to avatar hand
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (UxrEditorUtils.CenteredButton(new GUIContent("Align to avatar")))
|
||||
{
|
||||
Undo.RegisterCompleteObjectUndo(_handIntegration.transform, "Align hand integration");
|
||||
|
||||
if (!_handIntegration.TryToMatchHand())
|
||||
{
|
||||
EditorUtility.DisplayDialog("Missing required bone references", $"The hand integration could not find an {nameof(UxrAvatar)} component up in the hierarchy or the {nameof(UxrAvatar)} is missing finger bone references in the rig section. The finger bones are required to try to align the hand integration with the avatar's hand.", UxrConstants.Editor.Ok);
|
||||
}
|
||||
}
|
||||
|
||||
// Check Undo/Redo/Revert:
|
||||
|
||||
if (_propertyGizmoHandSize.enumValueIndex != (int)_gizmoHandSize)
|
||||
{
|
||||
RegenerateTemporalObjects();
|
||||
}
|
||||
|
||||
if (_propertySelectedRenderPipeline.intValue != _selectedRenderPipelineIndex)
|
||||
{
|
||||
_selectedRenderPipelineIndex = _propertySelectedRenderPipeline.intValue;
|
||||
EnableCurrentRenderPipeline(_renderers, _renderPipelineVariations[_selectedRenderPipelineIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Trigger Methods
|
||||
|
||||
/// <summary>
|
||||
/// Called when there is an undo/redo.
|
||||
/// </summary>
|
||||
private void OnUndoRedo()
|
||||
{
|
||||
RegenerateTemporalObjects();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets all the common object variation names among the available <see cref="UxrControllerHand" /> components hanging
|
||||
/// from the object.
|
||||
/// </summary>
|
||||
/// <returns>Common available object variation names</returns>
|
||||
private IReadOnlyList<string> GetCommonObjectVariationNames()
|
||||
{
|
||||
List<string> objectVariationNames = new List<string>();
|
||||
|
||||
if (_handIntegration)
|
||||
{
|
||||
_controllerHands = _handIntegration.GetComponentsInChildren<UxrControllerHand>(true);
|
||||
bool isFirst = true;
|
||||
|
||||
foreach (UxrControllerHand hand in _controllerHands)
|
||||
{
|
||||
objectVariationNames = isFirst ? hand.Variations.Select(v => v.Name).ToList() : objectVariationNames.Intersect(hand.Variations.Select(v => v.Name)).ToList();
|
||||
isFirst = false;
|
||||
}
|
||||
}
|
||||
|
||||
return objectVariationNames;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all the common material variation names among the available <see cref="UxrControllerHand" /> components
|
||||
/// hanging from the object, for a given object variation.
|
||||
/// </summary>
|
||||
/// <returns>Common available material variation names for the given object variation</returns>
|
||||
private IReadOnlyList<string> GetCommonMaterialVariationNames(string objectVariationName)
|
||||
{
|
||||
List<string> materialVariationNames = new List<string>();
|
||||
|
||||
if (_handIntegration)
|
||||
{
|
||||
_controllerHands = _handIntegration.GetComponentsInChildren<UxrControllerHand>(true);
|
||||
bool isFirst = true;
|
||||
|
||||
foreach (UxrControllerHand hand in _controllerHands)
|
||||
{
|
||||
foreach (UxrControllerHand.ObjectVariation objectVariation in hand.Variations)
|
||||
{
|
||||
if (objectVariation.Name == objectVariationName)
|
||||
{
|
||||
materialVariationNames = isFirst ? objectVariation.MaterialVariations.Select(v => v.Name).ToList() : materialVariationNames.Intersect(objectVariation.MaterialVariations.Select(v => v.Name)).ToList();
|
||||
isFirst = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return materialVariationNames;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the available renderers that are part of controllers, the list of available material render pipeline
|
||||
/// variations and the currently selected render pipeline.
|
||||
/// </summary>
|
||||
/// <param name="renderers">Returns the renderers that are part of controllers, if any</param>
|
||||
/// <param name="renderPipelineVariations">Returns the available material render pipeline variations, if any</param>
|
||||
/// <param name="renderPipelineVariationStrings">
|
||||
/// Returns the UI strings that <paramref name="renderPipelineVariations" />
|
||||
/// should be mapped with
|
||||
/// </param>
|
||||
/// <param name="selectedRenderPipelineIndex">
|
||||
/// Returns the index in <paramref name="renderPipelineVariations" /> of the
|
||||
/// render pipeline that was found to be currently enabled
|
||||
/// </param>
|
||||
private void GetControllerPipelineRenderers(out List<Renderer> renderers, out List<RenderPipeline> renderPipelineVariations, out List<string> renderPipelineVariationStrings, out int selectedRenderPipelineIndex)
|
||||
{
|
||||
renderers = new List<Renderer>();
|
||||
renderPipelineVariations = new List<RenderPipeline>();
|
||||
renderPipelineVariationStrings = new List<string>();
|
||||
selectedRenderPipelineIndex = -1;
|
||||
|
||||
if (_handIntegration)
|
||||
{
|
||||
foreach (Renderer renderer in _handIntegration.GetComponentsInChildren<Renderer>(true))
|
||||
{
|
||||
foreach (Material material in renderer.sharedMaterials.Where(material => material != null))
|
||||
{
|
||||
if (material.name.Contains(MaterialUrp))
|
||||
{
|
||||
renderers.Add(renderer);
|
||||
|
||||
if (!renderPipelineVariations.Contains(RenderPipeline.Urp))
|
||||
{
|
||||
renderPipelineVariations.Add(RenderPipeline.Urp);
|
||||
renderPipelineVariationStrings.Add(UrpUI);
|
||||
}
|
||||
|
||||
selectedRenderPipelineIndex = renderPipelineVariations.IndexOf(RenderPipeline.Urp);
|
||||
|
||||
if (!renderPipelineVariations.Contains(RenderPipeline.Brp) && GetRenderPipelineVariant(material, RenderPipeline.Brp))
|
||||
{
|
||||
renderPipelineVariations.Add(RenderPipeline.Brp);
|
||||
renderPipelineVariationStrings.Add(BrpUI);
|
||||
}
|
||||
}
|
||||
else if (material.name.Contains(MaterialBrp))
|
||||
{
|
||||
renderers.Add(renderer);
|
||||
|
||||
if (!renderPipelineVariations.Contains(RenderPipeline.Brp))
|
||||
{
|
||||
renderPipelineVariations.Add(RenderPipeline.Brp);
|
||||
renderPipelineVariationStrings.Add(BrpUI);
|
||||
}
|
||||
|
||||
selectedRenderPipelineIndex = renderPipelineVariations.IndexOf(RenderPipeline.Brp);
|
||||
|
||||
if (!renderPipelineVariations.Contains(RenderPipeline.Urp) && GetRenderPipelineVariant(material, RenderPipeline.Urp))
|
||||
{
|
||||
renderPipelineVariations.Add(RenderPipeline.Urp);
|
||||
renderPipelineVariationStrings.Add(UrpUI);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the given material variation if it exists.
|
||||
/// </summary>
|
||||
/// <param name="material">Material to get the variation of</param>
|
||||
/// <param name="renderPipeline">Render pipeline to get the variation for</param>
|
||||
/// <returns>The material variation for the given render pipeline if it exists</returns>
|
||||
private Material GetRenderPipelineVariant(Material material, RenderPipeline renderPipeline)
|
||||
{
|
||||
string materialName = material.name;
|
||||
string directory = Path.GetDirectoryName(AssetDatabase.GetAssetPath(material));
|
||||
|
||||
if (directory == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (renderPipeline == RenderPipeline.Brp)
|
||||
{
|
||||
if (materialName.Contains(MaterialUrp))
|
||||
{
|
||||
return AssetDatabase.LoadAssetAtPath<Material>(PathExt.Combine(directory, materialName.Replace(MaterialUrp, MaterialBrp)) + ".mat");
|
||||
}
|
||||
}
|
||||
else if (renderPipeline == RenderPipeline.Urp)
|
||||
{
|
||||
if (materialName.Contains(MaterialBrp))
|
||||
{
|
||||
return AssetDatabase.LoadAssetAtPath<Material>(PathExt.Combine(directory, materialName.Replace(MaterialBrp, MaterialUrp)) + ".mat");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the current object/material variation.
|
||||
/// </summary>
|
||||
/// <param name="objectVariationName">Object variation name</param>
|
||||
/// <param name="materialVariationName">Material variation name</param>
|
||||
private void EnableCurrentVariation(string objectVariationName, string materialVariationName)
|
||||
{
|
||||
if (_handIntegration)
|
||||
{
|
||||
foreach (UxrControllerHand hand in _handIntegration.GetComponentsInChildren<UxrControllerHand>(true))
|
||||
{
|
||||
// First pass: Disable all, because the selected variation may share a GameObject with another variation
|
||||
|
||||
foreach (UxrControllerHand.ObjectVariation objectVariation in hand.Variations)
|
||||
{
|
||||
objectVariation.GameObject.SetActive(false);
|
||||
}
|
||||
|
||||
// Second pass: Enable selected one and assign material
|
||||
|
||||
UxrControllerHand.ObjectVariation selectedObjectVariation = hand.Variations.FirstOrDefault(v => v.Name == objectVariationName);
|
||||
|
||||
if (selectedObjectVariation != null)
|
||||
{
|
||||
selectedObjectVariation.GameObject.SetActive(true);
|
||||
|
||||
UxrControllerHand.ObjectVariation.MaterialVariation selectedMaterialVariation = selectedObjectVariation.MaterialVariations.FirstOrDefault(v => v.Name == materialVariationName);
|
||||
|
||||
if (selectedMaterialVariation != null)
|
||||
{
|
||||
foreach (Renderer renderer in selectedObjectVariation.GameObject.GetComponentsInChildren<Renderer>(true))
|
||||
{
|
||||
renderer.sharedMaterial = selectedMaterialVariation.Material;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the materials for the given render pipeline.
|
||||
/// </summary>
|
||||
/// <param name="renderers">List of renderers whose materials to process</param>
|
||||
/// <param name="renderPipeline">Render pipeline to enable</param>
|
||||
private void EnableCurrentRenderPipeline(IReadOnlyList<Renderer> renderers, RenderPipeline renderPipeline)
|
||||
{
|
||||
foreach (Renderer renderer in renderers)
|
||||
{
|
||||
Material[] sharedMaterials = renderer.sharedMaterials;
|
||||
|
||||
for (int i = 0; i < sharedMaterials.Length; ++i)
|
||||
{
|
||||
Material materialVariation = GetRenderPipelineVariant(sharedMaterials[i], renderPipeline);
|
||||
|
||||
if (materialVariation != null)
|
||||
{
|
||||
sharedMaterials[i] = materialVariation;
|
||||
}
|
||||
}
|
||||
|
||||
renderer.sharedMaterials = sharedMaterials;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Regenerates the hand gizmo.
|
||||
/// </summary>
|
||||
private void RegenerateTemporalObjects()
|
||||
{
|
||||
DestroyTemporalObjects();
|
||||
CreateTemporalObjects();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the hand gizmo.
|
||||
/// </summary>
|
||||
private void CreateTemporalObjects()
|
||||
{
|
||||
string handAssetGuid = null;
|
||||
|
||||
if (_propertyGizmoHandSize.enumValueIndex == (int)UxrHandIntegration.GizmoHandSize.Big)
|
||||
{
|
||||
handAssetGuid = _handIntegration.HandSide == UxrHandSide.Left ? LeftBigHandAssetGuid : RightBigHandAssetGuid;
|
||||
_gizmoHandSize = UxrHandIntegration.GizmoHandSize.Big;
|
||||
}
|
||||
else if (_propertyGizmoHandSize.enumValueIndex == (int)UxrHandIntegration.GizmoHandSize.Small)
|
||||
{
|
||||
handAssetGuid = _handIntegration.HandSide == UxrHandSide.Left ? LeftSmallHandAssetGuid : RightSmallHandAssetGuid;
|
||||
_gizmoHandSize = UxrHandIntegration.GizmoHandSize.Small;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(handAssetGuid))
|
||||
{
|
||||
GameObject handAsset = AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GUIDToAssetPath(handAssetGuid));
|
||||
|
||||
if (handAsset == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_handGizmoRoot = Instantiate(handAsset);
|
||||
_handGizmoRoot.hideFlags = HideFlags.HideAndDontSave;
|
||||
_handGizmoRenderer = _handGizmoRoot.GetComponentInChildren<Renderer>();
|
||||
|
||||
if (_handGizmoRoot != null)
|
||||
{
|
||||
_handGizmoRoot.transform.SetParent(_handIntegration.transform);
|
||||
_handGizmoRoot.transform.SetPositionAndRotation(_handIntegration.transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Hand gizmo could not be loaded");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the hand gizmo.
|
||||
/// </summary>
|
||||
private void DestroyTemporalObjects()
|
||||
{
|
||||
if (_handGizmoRoot != null)
|
||||
{
|
||||
DestroyImmediate(_handGizmoRoot);
|
||||
}
|
||||
|
||||
_handGizmoRoot = null;
|
||||
_handGizmoRenderer = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Types & Data
|
||||
|
||||
private GUIContent ContentGizmoHandSize => new GUIContent("Gizmo Hand Size", "The hand size ");
|
||||
private GUIContent ContentHandSide => new GUIContent("Hand Side");
|
||||
private GUIContent ContentObjectVariationName => new GUIContent("Hand", "The type of hand that is shown with the controller");
|
||||
private GUIContent ContentMaterialVariationName => new GUIContent("Material", "The hand material");
|
||||
private GUIContent ContentRenderPipeline => new GUIContent("Render Pipeline", "The render pipeline that will be used, so that the correct materials are loaded");
|
||||
|
||||
private const string LeftBigHandAssetGuid = "93019d606e943b7429d29c694143ad6e";
|
||||
private const string RightBigHandAssetGuid = "d45d3edc285cfd64a86fddd771e13f47";
|
||||
private const string LeftSmallHandAssetGuid = "672e7f52fe868134a80bf396141fe261";
|
||||
private const string RightSmallHandAssetGuid = "0a1c1014903295a408b755f1fed2863e";
|
||||
|
||||
private const string MaterialBrp = "_BRP";
|
||||
private const string MaterialUrp = "_URP";
|
||||
private const string BrpUI = "Built-in Render Pipeline";
|
||||
private const string UrpUI = "Universal Render Pipeline";
|
||||
|
||||
private SerializedProperty _propertyGizmoHandSize;
|
||||
private SerializedProperty _propertyHandSide;
|
||||
private SerializedProperty _propertyObjectVariationName;
|
||||
private SerializedProperty _propertyMaterialVariationName;
|
||||
private SerializedProperty _propertySelectedRenderPipeline;
|
||||
|
||||
private UxrHandIntegration _handIntegration;
|
||||
private UxrHandIntegration.GizmoHandSize _gizmoHandSize;
|
||||
private GameObject _handGizmoRoot;
|
||||
private Renderer _handGizmoRenderer;
|
||||
private IReadOnlyList<UxrControllerHand> _controllerHands;
|
||||
private IReadOnlyList<string> _objectVariationNames;
|
||||
private IReadOnlyList<string> _materialVariationNames;
|
||||
private List<RenderPipeline> _renderPipelineVariations;
|
||||
private List<string> _renderPipelineVariationStrings;
|
||||
private List<Renderer> _renderers;
|
||||
private int _selectedRenderPipelineIndex;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
11
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrHandIntegrationEditor.cs.meta
vendored
Normal file
11
Assets/ThirdParty/UltimateXR/Editor/Avatar/UxrHandIntegrationEditor.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39a38dfa3b85bb9429b657870ef60ce6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user