public static void RetrievePersistentData(UltimateRope rope) { RopeData ropeData = s_hashInstanceID2RopeData[rope.GetInstanceID()]; // Attributes foreach(FieldInfo fieldInfo in rope.GetType().GetFields()) { fieldInfo.SetValue(rope, ropeData.m_hashFieldName2Value[fieldInfo.Name]); } // Physics if(ropeData.m_bDeleted) { rope.DeleteRope(); } else { // Set rope tranform info SetTransformInfo(ropeData.m_transformInfoRope, rope.gameObject); // Set rope start transform info if(rope.RopeStart != null) { if(ropeData.m_transformInfoStart.goObject == null) { rope.RopeStart = new GameObject(ropeData.m_transformInfoStart.strObjectName); } SetTransformInfo(ropeData.m_transformInfoStart, rope.RopeStart); } // Delete all dynamic links to reset them, so that even after creating/deleting/breaking links during playmode they get recreated correctly after playmode if(rope.RopeType != UltimateRope.ERopeType.ImportBones) { rope.DeleteRopeLinks(); } int nLinearLinkIndex = 0; for(int nNode = 0; nNode < rope.RopeNodes.Count; nNode++) { if(rope.RopeType != UltimateRope.ERopeType.ImportBones) { for(int nJoint = 0; nJoint < rope.RopeNodes[nNode].linkJoints.Length; nJoint++) { rope.RopeNodes[nNode].linkJointBreaksProcessed[nJoint] = ropeData.m_aaJointsProcessed[nNode][nJoint]; } if(rope.RopeNodes[nNode].goNode != null) { if(ropeData.m_transformInfoSegments[nNode].goObject == null) { rope.RopeNodes[nNode].goNode = new GameObject(ropeData.m_transformInfoSegments[nNode].strObjectName); } SetTransformInfo(ropeData.m_transformInfoSegments[nNode], rope.RopeNodes[nNode].goNode); } } if(rope.RopeType != UltimateRope.ERopeType.ImportBones) { rope.RopeNodes[nNode].segmentLinks = new GameObject[rope.RopeNodes[nNode].nTotalLinks]; } for(int nLink = 0; nLink < rope.RopeNodes[nNode].segmentLinks.Length; nLink++) { if(rope.RopeType != UltimateRope.ERopeType.ImportBones) { if(rope.RopeType == UltimateRope.ERopeType.Procedural) { rope.RopeNodes[nNode].segmentLinks[nLink] = new GameObject(ropeData.m_aLinkTransformInfo[nLinearLinkIndex].strObjectName); } else if(rope.RopeType == UltimateRope.ERopeType.LinkedObjects) { rope.RopeNodes[nNode].segmentLinks[nLink] = GameObject.Instantiate(rope.LinkObject) as GameObject; rope.RopeNodes[nNode].segmentLinks[nLink].name = ropeData.m_aLinkTransformInfo[nLinearLinkIndex].strObjectName; } rope.RopeNodes[nNode].segmentLinks[nLink].AddComponent<UltimateRopeLink>(); rope.RopeNodes[nNode].segmentLinks[nLink].transform.parent = (rope.FirstNodeIsCoil() && nNode == 0) ? rope.CoilObject.transform : rope.gameObject.transform; if(rope.RopeNodes[nNode].bIsCoil == false) { rope.RopeNodes[nNode].segmentLinks[nLink].AddComponent<Rigidbody>(); rope.RopeNodes[nNode].segmentLinks[nLink].rigidbody.isKinematic = ropeData.m_aLinkTransformInfo[nLinearLinkIndex].bExtensibleKinematic || ropeData.m_aLinkTransformInfo[nLinearLinkIndex].bLinkMarkedKinematic; } } SetTransformInfo(ropeData.m_aLinkTransformInfo[nLinearLinkIndex], rope.RopeNodes[nNode].segmentLinks[nLink]); if(rope.RopeType == UltimateRope.ERopeType.ImportBones) { rope.RopeNodes[nNode].segmentLinks[nLink].transform.parent = rope.ImportedBones[nLinearLinkIndex].bIsStatic ? rope.ImportedBones[nLinearLinkIndex].tfNonBoneParent : rope.transform; } if(ropeData.m_aLinkTransformInfo[nLinearLinkIndex].bExtensibleKinematic) { UltimateRopeLink ropeLink = rope.RopeNodes[nNode].segmentLinks[nLink].GetComponent<UltimateRopeLink>(); if(ropeLink != null) ropeLink.ExtensibleKinematic = true; rope.RopeNodes[nNode].segmentLinks[nLink].transform.parent = nNode > rope.m_nFirstNonCoilNode ? rope.RopeNodes[nNode - 1].goNode.transform : rope.RopeStart.transform; rope.RopeNodes[nNode].segmentLinks[nLink].transform.position = rope.RopeNodes[nNode].segmentLinks[nLink].transform.parent.position; Vector3 v3WorldForward = rope.RopeNodes[nNode].segmentLinks[nLink].transform.parent.TransformDirection(rope.RopeNodes[nNode].m_v3LocalDirectionForward); Vector3 v3WorldUp = rope.RopeNodes[nNode].segmentLinks[nLink].transform.parent.TransformDirection(rope.RopeNodes[nNode].m_v3LocalDirectionUp); rope.RopeNodes[nNode].segmentLinks[nLink].transform.rotation = Quaternion.LookRotation(v3WorldForward, v3WorldUp); } nLinearLinkIndex++; } } rope.SetupRopeLinks(); // Mesh SkinnedMeshRenderer skin = rope.GetComponent<SkinnedMeshRenderer>(); if(ropeData.m_bSkin == false) { if(skin != null) { UnityEngine.Object.DestroyImmediate(skin); } } else { if(skin == null) { skin = rope.gameObject.AddComponent<SkinnedMeshRenderer>(); } int nVertices = ropeData.m_av3SkinVertices.Length; int nTrianglesRope = ropeData.m_anSkinTrianglesRope.Length; int nTrianglesSections = ropeData.m_anSkinTrianglesSections.Length; Vector3[] av3SkinVertices = new Vector3 [nVertices]; Vector2[] av2SkinMapping = new Vector2 [nVertices]; Vector4[] av4SkinTangents = ropeData.m_av4SkinTangents != null ? new Vector4[ropeData.m_av4SkinTangents.Length] : null; BoneWeight[] aSkinBoneWeights = new BoneWeight[nVertices]; int[] anSkinTrianglesRope = new int [nTrianglesRope]; int[] anSkinTrianglesSections = new int [nTrianglesSections]; Matrix4x4[] amtxSkinBindPoses = new Matrix4x4 [ropeData.m_amtxSkinBindPoses.Length]; Mesh mesh = new Mesh(); RopeData.MakeSkinDeepCopy(ropeData.m_av3SkinVertices, ropeData.m_av2SkinMapping, ropeData.m_av4SkinTangents, ropeData.m_aSkinBoneWeights, ropeData.m_anSkinTrianglesRope, ropeData.m_anSkinTrianglesSections, ropeData.m_amtxSkinBindPoses, av3SkinVertices, av2SkinMapping, av4SkinTangents, aSkinBoneWeights, anSkinTrianglesRope, anSkinTrianglesSections, amtxSkinBindPoses); Transform[] aBones = new Transform[rope.TotalLinks]; nLinearLinkIndex = 0; for(int nNode = 0; nNode < rope.RopeNodes.Count; nNode++) { for(int nLink = 0; nLink < rope.RopeNodes[nNode].segmentLinks.Length; nLink++) { aBones[nLinearLinkIndex++] = rope.RopeNodes[nNode].segmentLinks[nLink].transform; } } mesh.vertices = av3SkinVertices; mesh.uv = av2SkinMapping; mesh.boneWeights = aSkinBoneWeights; mesh.bindposes = amtxSkinBindPoses; mesh.subMeshCount = 2; mesh.SetTriangles(anSkinTrianglesRope, 0); mesh.SetTriangles(anSkinTrianglesSections, 1); mesh.RecalculateNormals(); if(av4SkinTangents != null) { if(av4SkinTangents.Length == nVertices) { mesh.tangents = av4SkinTangents; } } skin.bones = aBones; skin.sharedMesh = mesh; Material[] ropeMaterials = new Material[2]; ropeMaterials[0] = rope.RopeMaterial; ropeMaterials[1] = rope.RopeSectionMaterial; skin.materials = ropeMaterials; } } }
public static void StorePersistentData(UltimateRope rope) { RopeData ropeData = new RopeData(rope); // Attributes foreach(FieldInfo fieldInfo in rope.GetType().GetFields()) { if(Attribute.IsDefined(fieldInfo, typeof(RopePersistAttribute))) { ropeData.m_hashFieldName2Value.Add(fieldInfo.Name, fieldInfo.GetValue(rope)); } } // Physics if(rope.Deleted) { ropeData.m_bDeleted = true; } else { ropeData.m_aaJointsBroken = new bool[rope.RopeNodes.Count][]; ropeData.m_aaJointsProcessed = new bool[rope.RopeNodes.Count][]; ropeData.m_transformInfoRope = ComputeTransformInfo(rope, rope.gameObject, rope.transform.parent != null ? rope.transform.parent.gameObject : null); if(rope.RopeStart != null) { ropeData.m_transformInfoStart = ComputeTransformInfo(rope, rope.RopeStart, rope.RopeStart.transform.parent != null ? rope.RopeStart.transform.parent.gameObject : null); } int nLinearLinkIndex = 0; for(int nNode = 0; nNode < rope.RopeNodes.Count; nNode++) { if(rope.RopeNodes[nNode].goNode != null) { ropeData.m_transformInfoSegments[nNode] = ComputeTransformInfo(rope, rope.RopeNodes[nNode].goNode, rope.RopeNodes[nNode].goNode.transform.parent != null ? rope.RopeNodes[nNode].goNode.transform.parent.gameObject : null); } foreach(GameObject link in rope.RopeNodes[nNode].segmentLinks) { ropeData.m_aLinkTransformInfo[nLinearLinkIndex] = ComputeTransformInfo(rope, link, rope.RopeType == UltimateRope.ERopeType.ImportBones ? rope.ImportedBones[nLinearLinkIndex].tfNonBoneParent.gameObject : rope.RopeNodes[nNode].goNode.transform.gameObject); nLinearLinkIndex++; } ropeData.m_aaJointsBroken[nNode] = new bool[rope.RopeNodes[nNode].linkJoints.Length]; ropeData.m_aaJointsProcessed[nNode] = new bool[rope.RopeNodes[nNode].linkJointBreaksProcessed.Length]; for(int nJoint = 0; nJoint < rope.RopeNodes[nNode].linkJoints.Length; nJoint++) { ropeData.m_aaJointsBroken[nNode][nJoint] = rope.RopeNodes[nNode].linkJoints[nJoint] == null; } for(int nJoint = 0; nJoint < rope.RopeNodes[nNode].linkJoints.Length; nJoint++) { ropeData.m_aaJointsProcessed[nNode][nJoint] = rope.RopeNodes[nNode].linkJointBreaksProcessed[nJoint]; } } ropeData.m_bDeleted = false; } s_hashInstanceID2RopeData.Add(rope.GetInstanceID(), ropeData); }