192 lines
5.0 KiB
C#
192 lines
5.0 KiB
C#
using UMA.CharacterSystem;
|
|
using UMA;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
[ExecuteInEditMode]
|
|
public class UMAMountedItem : MonoBehaviour
|
|
{
|
|
[Tooltip("The name of the bone. Case must match.")]
|
|
public string BoneName;
|
|
|
|
[Tooltip("Unique ID for this object. Example: 'RightHandMount")]
|
|
public string ID;
|
|
public Vector3 Position;
|
|
public Quaternion Orientation;
|
|
public string IgnoreTag = "UMAIgnore";
|
|
|
|
[Tooltip("If true the object will scale to bone DNA")]
|
|
public bool setScale = true;
|
|
|
|
[Tooltip("Mount this item in startup. Useful when instantiating prefabs.")]
|
|
public bool MountOnStart;
|
|
|
|
|
|
private int BoneHash;
|
|
private DynamicCharacterAvatar avatar;
|
|
private Transform MountPoint; // This is the mount point we create/update.
|
|
private UMAData lastUmaData;
|
|
|
|
// Start is called before the first frame update
|
|
void Start()
|
|
{
|
|
Initialize();
|
|
gameObject.tag = IgnoreTag;
|
|
}
|
|
|
|
private bool Initialize()
|
|
{
|
|
avatar = GetComponentInParent<DynamicCharacterAvatar>();
|
|
if (avatar == null)
|
|
{
|
|
return false;
|
|
}
|
|
avatar.CharacterUpdated.AddListener(new UnityAction<UMAData>(CharacterUpdated));
|
|
#if UNITY_EDITOR
|
|
if (!Application.isPlaying || MountOnStart)
|
|
{
|
|
MountPoint = EditorFindOrCreateMountpoint();
|
|
SetMountTransform();
|
|
}
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
// Used when mounting manually.
|
|
public bool MountItem()
|
|
{
|
|
if (avatar == null)
|
|
{
|
|
Initialize();
|
|
if (avatar == null)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
MountPoint = FindOrCreateMountpoint(avatar.umaData);
|
|
SetMountTransform();
|
|
return true;
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
public Transform EditorFindOrCreateMountpoint()
|
|
{
|
|
Transform BoneTransform = SkeletonTools.RecursiveFindBone(avatar.gameObject.transform, BoneName);
|
|
if (BoneTransform == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
foreach (Transform child in BoneTransform)
|
|
{
|
|
if (child.name == ID)
|
|
{
|
|
return child;
|
|
}
|
|
}
|
|
return CreateMountpoint(BoneTransform, avatar.gameObject.layer);
|
|
}
|
|
#endif
|
|
|
|
public void ResetMountPoint()
|
|
{
|
|
MountPoint = FindOrCreateMountpoint(avatar.umaData);
|
|
SetMountTransform();
|
|
}
|
|
|
|
public Transform FindOrCreateMountpoint(UMAData umaData)
|
|
{
|
|
if (string.IsNullOrEmpty(BoneName))
|
|
{
|
|
return null;
|
|
}
|
|
if (umaData == null || umaData.skeleton == null)
|
|
{
|
|
return null;
|
|
}
|
|
BoneHash = UMAUtils.StringToHash(BoneName);
|
|
Transform BoneTransform = umaData.skeleton.GetBoneTransform(BoneHash);
|
|
if (BoneTransform == null)
|
|
{
|
|
return null;
|
|
}
|
|
foreach (Transform child in BoneTransform)
|
|
{
|
|
if (child.name == ID)
|
|
{
|
|
UpdateMountPoint(child);
|
|
return child;
|
|
}
|
|
}
|
|
|
|
return CreateMountpoint(BoneTransform, umaData.gameObject.layer);
|
|
}
|
|
|
|
private void UpdateMountPoint(Transform newRoot)
|
|
{
|
|
newRoot.transform.localPosition = Position;
|
|
newRoot.transform.localRotation = Orientation;
|
|
newRoot.transform.localScale = Vector3.one;
|
|
}
|
|
|
|
private Transform CreateMountpoint(Transform BoneTransform, int Layer)
|
|
{
|
|
GameObject newRoot = new GameObject(ID);
|
|
newRoot.layer = Layer;
|
|
newRoot.transform.parent = BoneTransform;
|
|
newRoot.transform.localPosition = Position;
|
|
newRoot.transform.localRotation = Orientation;
|
|
newRoot.transform.localScale = Vector3.one;
|
|
return newRoot.transform;
|
|
}
|
|
|
|
public void CharacterUpdated(UMAData umaData)
|
|
{
|
|
// Debug.Log("Getting bone info");
|
|
MountPoint = FindOrCreateMountpoint(umaData);
|
|
lastUmaData = umaData;
|
|
}
|
|
|
|
void LateUpdate()
|
|
{
|
|
if (avatar == null)
|
|
{
|
|
if (!Initialize())
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
if (MountPoint != null)
|
|
{
|
|
// get the worldpos/orientation of the mounted object.
|
|
// copy to this object.
|
|
SetMountTransform();
|
|
}
|
|
else
|
|
{
|
|
if (lastUmaData != null)
|
|
{
|
|
FindOrCreateMountpoint(lastUmaData);
|
|
SetMountTransform();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SetMountTransform()
|
|
{
|
|
// Debug.Log("Setting mount transform");
|
|
if (MountPoint != null)
|
|
{
|
|
Vector3 globalScale = avatar.gameObject.transform.lossyScale;
|
|
|
|
transform.position = MountPoint.position;
|
|
transform.rotation = MountPoint.rotation;
|
|
if (setScale == true)
|
|
{
|
|
MountPoint.localScale = MountPoint.parent.localScale;
|
|
transform.localScale = MountPoint.localScale;
|
|
}
|
|
}
|
|
}
|
|
}
|