zrrz111

Untitled

Aug 8th, 2017
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 20.62 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System;
  4.  
  5. public class CreateRagdoll : MonoBehaviour {
  6.  
  7.     Transform root;
  8.  
  9.     Transform leftHips;
  10.     Transform leftKnee;
  11.     Transform leftFoot;
  12.  
  13.     Transform rightHips;
  14.     Transform rightKnee;
  15.     Transform rightFoot;
  16.  
  17.     Transform leftArm;
  18.     Transform leftElbow;
  19.  
  20.     Transform rightArm;
  21.     Transform rightElbow;
  22.  
  23.     Transform middleSpine;
  24.     Transform head;
  25.  
  26.     float totalMass = 20;
  27.     float strength = 0.0F;
  28.  
  29.     Vector3 right = Vector3.right;
  30.     Vector3 up = Vector3.up;
  31.     Vector3 forward = Vector3.forward;
  32.  
  33.     Vector3 worldRight = Vector3.right;
  34.     Vector3 worldUp = Vector3.up;
  35.     Vector3 worldForward = Vector3.forward;
  36.     public bool flipForward = false;
  37.  
  38.     class BoneInfo
  39.     {
  40.         public string name;
  41.  
  42.         public Transform anchor;
  43.         public CharacterJoint joint;
  44.         public BoneInfo parent;
  45.  
  46.         public float minLimit;
  47.         public float maxLimit;
  48.         public float swingLimit;
  49.  
  50.         public Vector3 axis;
  51.         public Vector3 normalAxis;
  52.  
  53.         public float radiusScale;
  54.         public System.Type colliderType;
  55.  
  56.         public ArrayList children = new ArrayList();
  57.         public float density;
  58.         public float summedMass;// The mass of this and all children bodies
  59.     }
  60.  
  61.     ArrayList bones;
  62.     BoneInfo rootBone;
  63.  
  64.     void Start() {
  65. //        Create(transform.Find("NG_BaseCharacter_V9_RiggedFix").gameObject); //Temp until i clean this up
  66.     }
  67.  
  68.     string CheckConsistency ()
  69.     {
  70.         PrepareBones();
  71.         Hashtable map = new Hashtable ();
  72.         foreach (BoneInfo bone in bones)
  73.         {
  74.             if (bone.anchor)
  75.             {
  76.                 if (map[bone.anchor] != null)
  77.                 {
  78.                     BoneInfo oldBone = (BoneInfo)map[bone.anchor];
  79.                     return System.String.Format("{0} and {1} may not be assigned to the same bone.", bone.name, oldBone.name);
  80.                 }
  81.                 map[bone.anchor] = bone;
  82.             }
  83.         }
  84.  
  85.         foreach (BoneInfo bone in bones)
  86.         {
  87.             if (bone.anchor == null)
  88.                 return String.Format("{0} has not been assigned yet.\n", bone.name);
  89.         }
  90.  
  91.         return "";
  92.     }
  93.  
  94. //    [MenuItem ("GameObject/Create Other/Ragdoll")]
  95. //    static void CreateWizard ()
  96. //    {
  97. //        ScriptableWizard.DisplayWizard("Create Ragdoll", typeof (RagdollBuilder));
  98. //    }
  99.  
  100.     void DecomposeVector(out Vector3 normalCompo, out Vector3 tangentCompo, Vector3 outwardDir, Vector3 outwardNormal)
  101.     {
  102.         outwardNormal = outwardNormal.normalized;
  103.         normalCompo = outwardNormal * Vector3.Dot(outwardDir, outwardNormal);
  104.         tangentCompo = outwardDir - normalCompo;
  105.     }
  106.  
  107.     void CalculateAxes ()
  108.     {
  109.         if (head != null && root != null)
  110.             up = CalculateDirectionAxis(root.InverseTransformPoint(head.position));
  111.         if (rightElbow != null && root != null)
  112.         {
  113.             Vector3 removed, temp;
  114.             DecomposeVector(out temp, out removed, root.InverseTransformPoint(rightElbow.position), up);
  115.             right = CalculateDirectionAxis(removed);
  116.         }
  117.  
  118.         forward = Vector3.Cross(right, up);
  119.         if (flipForward)
  120.             forward = -forward;
  121.     }  
  122.  
  123. //    void OnWizardUpdate ()
  124. //    {
  125. //        errorString = CheckConsistency ();
  126. //        CalculateAxes();
  127. //
  128. //        if (errorString.Length != 0)
  129. //        {
  130. //            helpString = "Drag all bones from the hierarchy into their slots.\nMake sure your character is in T-Stand.\n";
  131. //        }
  132. //        else
  133. //        {
  134. //            helpString = "Make sure your character is in T-Stand.\nMake sure the blue axis faces in the same direction the chracter is looking.\nUse flipForward to flip the direction";
  135. //        }
  136. //
  137. //        isValid = errorString.Length == 0;
  138. //    }
  139.  
  140.     void PrepareBones ()
  141.     {
  142.         if (root)
  143.         {
  144.             worldRight = root.TransformDirection(right);
  145.             worldUp = root.TransformDirection(up);
  146.             worldForward = root.TransformDirection(forward);
  147.         }
  148.  
  149.         bones = new ArrayList();
  150.  
  151.         rootBone = new BoneInfo ();
  152.         rootBone.name = "Root";
  153.         rootBone.anchor = root;
  154.         rootBone.parent = null;
  155.         rootBone.density = 2.5F;
  156.         bones.Add (rootBone);
  157.  
  158.         AddMirroredJoint ("Hips", leftHips, rightHips, "Root", worldRight, worldForward, -20, 70, 30, typeof(CapsuleCollider), 0.3F, 1.5F);
  159.         AddMirroredJoint ("Knee", leftKnee, rightKnee, "Hips", worldRight, worldForward, -80, 0, 0, typeof(CapsuleCollider), 0.25F, 1.5F);
  160.         //      AddMirroredJoint ("Hips", leftHips, rightHips, "Root", worldRight, worldForward, -0, -70, 30, typeof(CapsuleCollider), 0.3F, 1.5F);
  161.         //      AddMirroredJoint ("Knee", leftKnee, rightKnee, "Hips", worldRight, worldForward, -0, -50, 0, typeof(CapsuleCollider), .25F, 1.5F);
  162.  
  163.         AddJoint ("Middle Spine", middleSpine, "Root", worldRight, worldForward, -20, 20, 10, null, 1, 2.5F);
  164.  
  165.         AddMirroredJoint ("Arm", leftArm, rightArm, "Middle Spine", worldUp, worldForward, -70, 10, 50, typeof(CapsuleCollider), 0.25F, 1.0F);
  166.         AddMirroredJoint ("Elbow", leftElbow, rightElbow, "Arm", worldForward, worldUp, -90, 0, 0, typeof(CapsuleCollider), 0.20F, 1.0F);
  167.  
  168.         AddJoint ("Head", head, "Middle Spine", worldRight, worldForward, -40, 25, 25, null, 1, 1.0F);
  169.     }
  170.  
  171.     public void Create (GameObject character) {
  172.         RagdollUtility.BodyDefinition bodyDefinition = new RagdollUtility.BodyDefinition(character.transform);
  173.         root = bodyDefinition.GetTransform(HumanBodyBones.Hips);
  174.  
  175.         leftHips = bodyDefinition.GetTransform(HumanBodyBones.LeftUpperLeg);
  176.         leftKnee = bodyDefinition.GetTransform(HumanBodyBones.LeftLowerLeg);
  177.         leftFoot = bodyDefinition.GetTransform(HumanBodyBones.LeftFoot);
  178.  
  179.         rightHips = bodyDefinition.GetTransform(HumanBodyBones.RightUpperLeg);
  180.         rightKnee = bodyDefinition.GetTransform(HumanBodyBones.RightLowerLeg);
  181.         rightFoot = bodyDefinition.GetTransform(HumanBodyBones.RightFoot);
  182.  
  183.         middleSpine = bodyDefinition.GetTransform(HumanBodyBones.Chest);
  184.         head = bodyDefinition.GetTransform(HumanBodyBones.Head);
  185.  
  186.         leftArm = bodyDefinition.GetTransform(HumanBodyBones.LeftUpperArm);
  187.         leftElbow = bodyDefinition.GetTransform(HumanBodyBones.LeftLowerArm);
  188.  
  189.         rightArm = bodyDefinition.GetTransform(HumanBodyBones.RightUpperArm);
  190.         rightElbow = bodyDefinition.GetTransform(HumanBodyBones.RightLowerArm);
  191.  
  192.         totalMass = 62f;
  193.         strength = 0.0f;
  194.  
  195.         try {
  196.             CheckConsistency ();
  197.         } catch(NullReferenceException e) {
  198.             Debug.LogError("CheckConsistency: " + e);
  199.         }
  200.  
  201.         try {
  202.             CalculateAxes();
  203.         } catch(NullReferenceException e) {
  204.             Debug.LogError("CalculateAxes: " + e);
  205.         }
  206.  
  207.         try {
  208.             BuildCapsules();
  209.         } catch(NullReferenceException e) {
  210.             Debug.LogError("BuildCapsules: " + e);
  211.         }
  212.  
  213.         try {
  214.             AddBreastColliders();
  215.         } catch(NullReferenceException e) {
  216.             Debug.LogError("AddBreastColliders: " + e);
  217.         }
  218.  
  219.         try {
  220.             AddHeadCollider();
  221.         } catch(NullReferenceException e) {
  222.             Debug.LogError("AddHeadCollider: " + e);
  223.         }
  224.  
  225.         try {
  226.             BuildBodies ();
  227.         } catch(NullReferenceException e) {
  228.             Debug.LogError("BuildBodies: " + e);
  229.         }
  230.  
  231.         try {
  232.             BuildJoints ();
  233.         } catch(NullReferenceException e) {
  234.             Debug.LogError("BuildJoints: " + e);
  235.         }
  236.         try {
  237.             CalculateMass();
  238.         } catch(NullReferenceException e) {
  239.             Debug.LogError("CalculateMass: " + e);
  240.         }
  241.  
  242.         try {
  243.             CalculateSpringDampers();
  244.         } catch(NullReferenceException e) {
  245.             Debug.LogError("CalculateSpringDampers: " + e);
  246.         }
  247.     }
  248.  
  249.     BoneInfo FindBone (string name)
  250.     {
  251.         foreach (BoneInfo bone in bones)
  252.         {
  253.             if (bone.name == name)
  254.                 return bone;
  255.         }
  256.         return null;
  257.     }
  258.  
  259.     void AddMirroredJoint (string name, Transform leftAnchor, Transform rightAnchor, string parent, Vector3 worldTwistAxis, Vector3 worldSwingAxis, float minLimit, float maxLimit, float swingLimit, Type colliderType, float radiusScale, float density)
  260.     {
  261.         AddJoint ("Left " + name, leftAnchor, parent, worldTwistAxis, worldSwingAxis, minLimit, maxLimit, swingLimit, colliderType, radiusScale, density);
  262.         AddJoint ("Right " + name, rightAnchor, parent, worldTwistAxis, worldSwingAxis, minLimit, maxLimit, swingLimit, colliderType, radiusScale, density);
  263.     }
  264.  
  265.  
  266.     void AddJoint (string name, Transform anchor, string parent, Vector3 worldTwistAxis, Vector3 worldSwingAxis, float minLimit, float maxLimit, float swingLimit, Type colliderType, float radiusScale, float density)
  267.     {
  268.         BoneInfo bone = new BoneInfo();
  269.         bone.name = name;
  270.         bone.anchor = anchor;
  271.         bone.axis = worldTwistAxis;
  272.         bone.normalAxis = worldSwingAxis;
  273.         bone.minLimit = minLimit;
  274.         bone.maxLimit = maxLimit;
  275.         bone.swingLimit = swingLimit;
  276.         bone.density = density;
  277.         bone.colliderType = colliderType;
  278.         bone.radiusScale = radiusScale;
  279.  
  280.         if (FindBone (parent) != null)
  281.             bone.parent = FindBone (parent);
  282.         else if (name.StartsWith ("Left"))
  283.             bone.parent = FindBone ("Left " + parent);
  284.         else if (name.StartsWith ("Right"))
  285.             bone.parent = FindBone ("Right "+ parent);
  286.  
  287.  
  288.         bone.parent.children.Add(bone);
  289.         bones.Add (bone);
  290.     }
  291.  
  292.     void BuildCapsules ()
  293.     {
  294.         foreach (BoneInfo bone in bones)
  295.         {
  296.             if (bone.colliderType != typeof (CapsuleCollider))
  297.                 continue;
  298.  
  299.             int direction;
  300.             float distance;
  301.             if (bone.children.Count == 1)
  302.             {
  303.                 BoneInfo childBone = (BoneInfo)bone.children[0];
  304.                 Vector3 endPoint = childBone.anchor.position;
  305.                 CalculateDirection (bone.anchor.InverseTransformPoint(endPoint), out direction, out distance);
  306.             }
  307.             else
  308.             {
  309.                 Vector3 endPoint = (bone.anchor.position - bone.parent.anchor.position) + bone.anchor.position;
  310.                 CalculateDirection (bone.anchor.InverseTransformPoint(endPoint), out direction, out distance);
  311.  
  312.                 if (bone.anchor.GetComponentsInChildren(typeof(Transform)).Length > 1)
  313.                 {
  314.                     Bounds bounds = new Bounds();
  315.                     foreach (Transform child in bone.anchor.GetComponentsInChildren(typeof(Transform)))
  316.                     {
  317.                         bounds.Encapsulate(bone.anchor.InverseTransformPoint(child.position));
  318.                     }
  319.  
  320.                     if (distance > 0)
  321.                         distance = bounds.max[direction];
  322.                     else
  323.                         distance = bounds.min[direction];
  324.                 }
  325.             }
  326.  
  327.             CapsuleCollider collider = (CapsuleCollider)bone.anchor.gameObject.AddComponent <CapsuleCollider>();
  328.             collider.direction = direction;
  329.  
  330.             Vector3 center = Vector3.zero;
  331.             center[direction] = distance * 0.5F;
  332.             collider.center = center;
  333.             collider.height = Mathf.Abs (distance);
  334.             collider.radius = Mathf.Abs (distance * bone.radiusScale);
  335.         }
  336.     }
  337.  
  338.     void Cleanup ()
  339.     {
  340.         foreach (BoneInfo bone in bones)
  341.         {
  342.             if (!bone.anchor)
  343.                 continue;
  344.  
  345.             Component[] joints = bone.anchor.GetComponentsInChildren(typeof(Joint));
  346.             foreach (Joint joint in joints)
  347.                 DestroyImmediate(joint);
  348.  
  349.             Component[] bodies = bone.anchor.GetComponentsInChildren(typeof(Rigidbody));
  350.             foreach (Rigidbody body in bodies)
  351.                 DestroyImmediate(body);
  352.  
  353.             Component[] colliders = bone.anchor.GetComponentsInChildren(typeof(Collider));
  354.             foreach (Collider collider in colliders)
  355.                 DestroyImmediate(collider);
  356.         }
  357.     }
  358.  
  359.     void BuildBodies ()
  360.     {
  361.         foreach (BoneInfo bone in bones)
  362.         {
  363.             bone.anchor.gameObject.AddComponent<Rigidbody>();
  364.             //          bone.anchor.rigidbody.SetDensity (bone.density);
  365.             bone.anchor.GetComponent<Rigidbody>().mass = bone.density;
  366.         }
  367.     }
  368.  
  369.     void BuildJoints ()
  370.     {
  371.         foreach (BoneInfo bone in bones)
  372.         {
  373.             if (bone.parent == null)
  374.                 continue;
  375.  
  376.             CharacterJoint joint = (CharacterJoint)bone.anchor.gameObject.AddComponent <CharacterJoint>();
  377.             bone.joint = joint;
  378.  
  379.             // Setup connection and axis
  380.             joint.axis = CalculateDirectionAxis (bone.anchor.InverseTransformDirection(bone.axis));
  381.             joint.swingAxis = CalculateDirectionAxis (bone.anchor.InverseTransformDirection(bone.normalAxis));
  382.             joint.anchor = Vector3.zero;
  383.             joint.connectedBody = bone.parent.anchor.GetComponent<Rigidbody>();
  384.  
  385.             // Setup limits        
  386.             SoftJointLimit limit = new SoftJointLimit ();
  387.  
  388.             limit.limit = bone.minLimit;
  389.             joint.lowTwistLimit = limit;
  390.  
  391.             limit.limit = bone.maxLimit;
  392.             joint.highTwistLimit = limit;
  393.  
  394.             limit.limit = bone.swingLimit;
  395.             joint.swing1Limit = limit;
  396.  
  397.             limit.limit = 0;
  398.             joint.swing2Limit = limit;
  399.         }
  400.     }
  401.  
  402.     void CalculateMassRecurse (BoneInfo bone)
  403.     {
  404.         float mass = bone.anchor.GetComponent<Rigidbody>().mass;
  405.         foreach (BoneInfo child in bone.children)
  406.         {
  407.             CalculateMassRecurse (child);
  408.             mass += child.summedMass;
  409.         }
  410.         bone.summedMass = mass;
  411.     }
  412.  
  413.     void CalculateMass ()
  414.     {
  415.         // Calculate allChildMass by summing all bodies
  416.         CalculateMassRecurse (rootBone);
  417.  
  418.         // Rescale the mass so that the whole character weights totalMass
  419.         float massScale = totalMass / rootBone.summedMass;
  420.         foreach (BoneInfo bone in bones)
  421.             bone.anchor.GetComponent<Rigidbody>().mass *= massScale;
  422.  
  423.         // Recalculate allChildMass by summing all bodies
  424.         CalculateMassRecurse(rootBone);
  425.     }
  426.  
  427.     ///@todo: This should take into account the inertia tensor.
  428.     JointDrive CalculateSpringDamper (float frequency, float damping, float mass)
  429.     {
  430.         JointDrive drive = new JointDrive();
  431.         drive.positionSpring = 9 * frequency * frequency * mass;
  432.         drive.positionDamper = 4.5F * frequency * damping * mass;
  433.         return drive;
  434.     }
  435.  
  436.     void CalculateSpringDampers ()
  437.     {
  438.         // Calculate the rotation drive based on the strength and how much mass the character needs to pull around.
  439. //        foreach (BoneInfo bone in bones)
  440. //        {
  441. //            if (bone.joint)
  442. //                bone.joint.rotationDrive = CalculateSpringDamper (strength / 100.0F, 1, bone.summedMass);
  443. //                bone.joint.
  444. //        }
  445.     }
  446.    
  447.     static void CalculateDirection (Vector3 point, out int direction, out float distance)
  448.     {
  449.         // Calculate longest axis
  450.         direction = 0;
  451.         if (Mathf.Abs(point[1]) > Mathf.Abs(point[0]))
  452.             direction = 1;
  453.         if (Mathf.Abs(point[2]) >Mathf.Abs(point[direction]))
  454.             direction = 2;
  455.  
  456.         distance = point[direction];
  457.     }
  458.  
  459.     static Vector3 CalculateDirectionAxis (Vector3 point)
  460.     {
  461.         int direction = 0;
  462.         float distance;
  463.         CalculateDirection (point, out direction, out distance);
  464.         Vector3 axis = Vector3.zero;
  465.         if (distance > 0)
  466.             axis[direction] = 1.0F;
  467.         else
  468.             axis[direction] = -1.0F;
  469.         return axis;
  470.     }
  471.  
  472.     static int SmallestComponent (Vector3 point)
  473.     {
  474.         int direction = 0;
  475.         if (Mathf.Abs(point[1]) < Mathf.Abs(point[0]))
  476.             direction = 1;
  477.         if (Mathf.Abs(point[2]) < Mathf.Abs(point[direction]))
  478.             direction = 2;
  479.         return direction;
  480.     }
  481.  
  482.     static int LargestComponent (Vector3 point)
  483.     {
  484.         int direction = 0;
  485.         if (Mathf.Abs(point[1]) > Mathf.Abs(point[0]))
  486.             direction = 1;
  487.         if (Mathf.Abs(point[2]) > Mathf.Abs(point[direction]))
  488.             direction = 2;
  489.         return direction;
  490.     }
  491.  
  492.     static int SecondLargestComponent (Vector3 point)
  493.     {
  494.         int smallest = SmallestComponent (point);
  495.         int largest = LargestComponent (point);
  496.         if (smallest < largest)
  497.         {
  498.             int temp = largest;
  499.             largest = smallest;
  500.             smallest = temp;
  501.         }
  502.  
  503.         if (smallest == 0 && largest == 1)
  504.             return 2;
  505.         else if (smallest == 0 && largest == 2)
  506.             return 1;
  507.         else
  508.             return 0;
  509.     }
  510.  
  511.     Bounds Clip (Bounds bounds, Transform relativeTo, Transform clipTransform, bool below)
  512.     {
  513.         int axis = LargestComponent(bounds.size);
  514.  
  515.         if (Vector3.Dot (worldUp, relativeTo.TransformPoint(bounds.max)) > Vector3.Dot (worldUp, relativeTo.TransformPoint(bounds.min)) == below)
  516.         {
  517.             Vector3 min = bounds.min;
  518.             min[axis] = relativeTo.InverseTransformPoint (clipTransform.position)[axis];
  519.             bounds.min = min;
  520.         }
  521.         else
  522.         {
  523.             Vector3 max = bounds.max;
  524.             max[axis] = relativeTo.InverseTransformPoint (clipTransform.position)[axis];
  525.             bounds.max = max;
  526.         }
  527.         return bounds;
  528.     }
  529.  
  530.     Bounds GetBreastBounds (Transform relativeTo)
  531.     {
  532.         // Root bounds
  533.         Bounds bounds = new Bounds ();
  534.         bounds.Encapsulate (relativeTo.InverseTransformPoint (leftHips.position));
  535.         bounds.Encapsulate (relativeTo.InverseTransformPoint (rightHips.position));
  536.         bounds.Encapsulate (relativeTo.InverseTransformPoint (leftArm.position));
  537.         bounds.Encapsulate (relativeTo.InverseTransformPoint (rightArm.position));
  538.         Vector3 size = bounds.size;
  539.         size[SmallestComponent (bounds.size)] = size[LargestComponent (bounds.size)] / 2.0F;
  540.         bounds.size = size;
  541.         return bounds;      
  542.     }
  543.  
  544.     void AddBreastColliders ()
  545.     {
  546.         // Middle spine and root
  547.         if (middleSpine != null && root != null)
  548.         {
  549.             Bounds bounds;
  550.             BoxCollider box;
  551.  
  552.             // Middle spine bounds
  553.             bounds = Clip (GetBreastBounds (root), root, middleSpine, false);
  554.             box = (BoxCollider)root.gameObject.AddComponent<BoxCollider>();
  555.             box.center = bounds.center;
  556.             box.size = bounds.size;
  557.  
  558.             bounds = Clip (GetBreastBounds (middleSpine), middleSpine, middleSpine, true);
  559.             box = (BoxCollider)middleSpine.gameObject.AddComponent<BoxCollider>();
  560.             box.center = bounds.center;
  561.             box.size = bounds.size;
  562.         }
  563.         // Only root
  564.         else
  565.         {
  566.             Bounds bounds = new Bounds ();
  567.             bounds.Encapsulate (root.InverseTransformPoint (leftHips.position));
  568.             bounds.Encapsulate (root.InverseTransformPoint (rightHips.position));
  569.             bounds.Encapsulate (root.InverseTransformPoint (leftArm.position));
  570.             bounds.Encapsulate (root.InverseTransformPoint (rightArm.position));
  571.  
  572.             Vector3 size = bounds.size;
  573.             size[SmallestComponent (bounds.size)] = size[LargestComponent (bounds.size)] / 2.0F;
  574.  
  575.             BoxCollider box = (BoxCollider)root.gameObject.AddComponent<BoxCollider>();
  576.             box.center = bounds.center;
  577.             box.size = size;
  578.         }
  579.     }
  580.  
  581.     void AddHeadCollider ()
  582.     {
  583.         if (head.GetComponent<Collider>())
  584.             Destroy (head.GetComponent<Collider>());
  585.  
  586.         float radius = Vector3.Distance(leftArm.transform.position, rightArm.transform.position);
  587. //        radius /= 4;
  588.         radius *= 0.85f; //Big head hack
  589.  
  590.  
  591.         SphereCollider sphere = (SphereCollider)head.gameObject.AddComponent <SphereCollider>();
  592.         sphere.radius = radius;
  593.         Vector3 center = Vector3.zero;
  594.  
  595.         int direction;
  596.         float distance;
  597.         CalculateDirection (head.InverseTransformPoint(root.position), out direction, out distance);
  598.         if (distance > 0)
  599.             center[direction] = -radius;
  600.         else
  601.             center[direction] = radius;
  602.         sphere.center = center + new Vector3(0f, 0f, 0.05f);
  603.     }
  604. }
Advertisement
Add Comment
Please, Sign In to add comment