void redirectSkeleton() { if (this.StreamingClient == null) { return; } // Create a lookup from Mecanim anatomy bone names to OptiTrack streaming bone names. CacheBoneNameMap(this.StreamingClient.BoneNamingConvention, this.SkeletonAssetName); // Retrieve the OptiTrack skeleton definition. m_skeletonDef = this.StreamingClient.GetSkeletonDefinitionByName(this.SkeletonAssetName); if (m_skeletonDef == null) { StreamingClient.TriggerUpdateDefinitions(); Debug.LogError( GetType().FullName + ": Could not find skeleton definition with the name \"" + this.SkeletonAssetName + "\"", this); this.enabled = false; return; } else { Debug.Log("find a skeleton"); } // Create a hierarchy of GameObjects that will receive the skeletal pose data. string rootObjectName = "OptiTrack Skeleton - " + this.SkeletonAssetName; m_rootObject = new GameObject(rootObjectName); m_boneObjectMap = new Dictionary <Int32, GameObject>(m_skeletonDef.Bones.Count); for (int boneDefIdx = 0; boneDefIdx < m_skeletonDef.Bones.Count; ++boneDefIdx) { OptitrackSkeletonDefinition.BoneDefinition boneDef = m_skeletonDef.Bones[boneDefIdx]; GameObject boneObject = new GameObject(boneDef.Name); boneObject.transform.parent = boneDef.ParentId == 0 ? m_rootObject.transform : m_boneObjectMap[boneDef.ParentId].transform; boneObject.transform.localPosition = boneDef.Offset.V3; m_boneObjectMap[boneDef.Id] = boneObject; } // Hook up retargeting between those GameObjects and the destination Avatar. MecanimSetup(rootObjectName); // Can't reparent this until after Mecanim setup, or else Mecanim gets confused. m_rootObject.transform.parent = this.StreamingClient.transform; m_rootObject.transform.localPosition = Vector3.zero; m_rootObject.transform.localRotation = Quaternion.identity; }