protected virtual void OnSceneGUI() { RagdollJoint ragdoll = (RagdollJoint)target; bool drawCones = false; if (ragdoll.EditPivots) { EditorUtilities.EditPivot(ragdoll.worldFromA, ragdoll.worldFromB, ragdoll.AutoSetConnected, ref ragdoll.PositionLocal, ref ragdoll.PositionInConnectedEntity, ragdoll); } if (ragdoll.EditAxes) { m_AxisEditor.Update(ragdoll.worldFromA, ragdoll.worldFromB, ragdoll.AutoSetConnected, ragdoll.PositionLocal, ragdoll.PositionInConnectedEntity, ref ragdoll.TwistAxisLocal, ref ragdoll.TwistAxisInConnectedEntity, ref ragdoll.PerpendicularAxisLocal, ref ragdoll.PerpendicularAxisInConnectedEntity, ragdoll); drawCones = true; } if (ragdoll.EditLimits) { EditorUtilities.EditLimits(ragdoll.worldFromA, ragdoll.worldFromB, ragdoll.PositionLocal, ragdoll.TwistAxisLocal, ragdoll.TwistAxisInConnectedEntity, ragdoll.PerpendicularAxisLocal, ragdoll.PerpendicularAxisInConnectedEntity, ref ragdoll.MinTwistAngle, ref ragdoll.MaxTwistAngle, m_LimitHandle, ragdoll); } if (drawCones) { float3 pivotB = math.transform(ragdoll.worldFromB, ragdoll.PositionInConnectedEntity); float3 axisB = math.rotate(ragdoll.worldFromB, ragdoll.TwistAxisInConnectedEntity); DrawCone(pivotB, axisB, math.radians(ragdoll.MaxConeAngle), Color.yellow); float3 perpendicularB = math.rotate(ragdoll.worldFromB, ragdoll.PerpendicularAxisInConnectedEntity); DrawCone(pivotB, perpendicularB, math.radians(ragdoll.MinPerpendicularAngle), Color.red); DrawCone(pivotB, perpendicularB, math.radians(ragdoll.MaxPerpendicularAngle), Color.red); } }
public override void OnInspectorGUI() { RagdollJoint ragdoll = (RagdollJoint)target; EditorGUI.BeginChangeCheck(); GUILayout.BeginVertical(); GUILayout.Space(10.0f); GUILayout.BeginHorizontal(); GUILayout.Label("Editors:"); ragdoll.EditPivots = GUILayout.Toggle(ragdoll.EditPivots, new GUIContent("Pivot"), "Button"); ragdoll.EditAxes = GUILayout.Toggle(ragdoll.EditAxes, new GUIContent("Axis"), "Button"); ragdoll.EditLimits = GUILayout.Toggle(ragdoll.EditLimits, new GUIContent("Limits"), "Button"); GUILayout.EndHorizontal(); GUILayout.Space(10.0f); GUILayout.EndVertical(); DrawDefaultInspector(); if (EditorGUI.EndChangeCheck()) { SceneView.RepaintAll(); } }
public void Shoot(RagdollJoint joint, int damage, Vector3 impactForce, Vector3 point) { // Particle effect where hit Quaternion particleRotation = Quaternion.LookRotation(impactForce, Vector3.up); GameObject particles = Instantiate(HitParticles, point, particleRotation); Destroy(particles, HitParticleTime); Health = Mathf.Max(Health - damage, 0); Debug.Log(string.Format("Shot for {0} damage", damage)); if (Health == 0) { // Ragdoll on death col.enabled = false; m_movingCharacter.enabled = false; m_movingCharacter.rigidbody.isKinematic = true; animator.enabled = false; ragdoll.setRagdollActive(true); Debug.Log(string.Format("Killed, force of {0} applied at {1}", impactForce, point)); joint.Body.AddForceAtPosition(impactForce, point, ForceMode.Impulse); } }
public static void Load(string ragdoll, GameObject target, bool editor) { Dictionary <string, RagdollJoint> ragdollJointsDictionary = new Dictionary <string, RagdollJoint>(); RagdollJoint[] ragdollJoints = XMLSerializer.DeserializeObject <Ragdoll>(ragdoll).ragdollJoints; foreach (RagdollJoint rJ in ragdollJoints) { ragdollJointsDictionary[rJ.boneName] = rJ; } if (ragdollJointsDictionary.ContainsKey(target.name)) { // Root bone if (target.GetComponent <CharacterJoint>() != null) { DestroyImmediate(target.GetComponent <CharacterJoint>()); } if (target.GetComponent <Collider>() != null) { DestroyImmediate(target.GetComponent <Collider>()); } if (target.GetComponent <Rigidbody>() != null) { DestroyImmediate(target.GetComponent <Rigidbody>()); } Dictionary <string, GameObject> children = new Dictionary <string, GameObject>(); foreach (Transform t in target.GetComponentsInChildren <Transform>()) { children[t.gameObject.name] = t.gameObject; if (t.gameObject.GetComponent <CharacterJoint>() != null) { DestroyImmediate(t.gameObject.GetComponent <CharacterJoint>()); } if (t.gameObject.GetComponent <Collider>() != null) { DestroyImmediate(t.gameObject.GetComponent <Collider>()); } if (t.gameObject.GetComponent <Rigidbody>() != null) { DestroyImmediate(t.gameObject.GetComponent <Rigidbody>()); } } children[target.name] = target; RagdollJoint rJ = ragdollJointsDictionary[target.name]; if (rJ.boxColliderSettings != null) { BoxCollider bC = target.AddComponent <BoxCollider>(); bC.center = MathHelper.FromString(rJ.boxColliderSettings.center); bC.size = MathHelper.FromString(rJ.boxColliderSettings.size); } else if (rJ.sphereColliderSettings != null) { SphereCollider sC = target.AddComponent <SphereCollider>(); sC.center = MathHelper.FromString(rJ.sphereColliderSettings.center); sC.radius = rJ.sphereColliderSettings.radius; } else if (rJ.capsuleColliderSettings != null) { CapsuleCollider cC = target.AddComponent <CapsuleCollider>(); cC.center = MathHelper.FromString(rJ.capsuleColliderSettings.center); cC.radius = rJ.capsuleColliderSettings.radius; cC.height = rJ.capsuleColliderSettings.height; cC.direction = rJ.capsuleColliderSettings.direction; } else { Debug.LogError("Ragdoll Loader: collider type is not supported (" + target.name + ")"); } Rigidbody rB = target.AddComponent <Rigidbody>(); rB.mass = rJ.rigidbodySettings.mass; // Children if (editor) { Debug.Log("Ragdoll Loader: " + target.name + " joint processed"); } int count = 1; foreach (GameObject gO in children.Values) { if (gO.name == target.name) { continue; } if (ragdollJointsDictionary.ContainsKey(gO.name)) { rJ = ragdollJointsDictionary[gO.name]; if (rJ.boxColliderSettings != null) { BoxCollider bC = gO.AddComponent <BoxCollider>(); bC.center = MathHelper.FromString(rJ.boxColliderSettings.center); bC.size = MathHelper.FromString(rJ.boxColliderSettings.size); } else if (rJ.sphereColliderSettings != null) { SphereCollider sC = gO.AddComponent <SphereCollider>(); sC.center = MathHelper.FromString(rJ.sphereColliderSettings.center); sC.radius = rJ.sphereColliderSettings.radius; } else if (rJ.capsuleColliderSettings != null) { CapsuleCollider cC = gO.AddComponent <CapsuleCollider>(); cC.center = MathHelper.FromString(rJ.capsuleColliderSettings.center); cC.radius = rJ.capsuleColliderSettings.radius; cC.height = rJ.capsuleColliderSettings.height; cC.direction = rJ.capsuleColliderSettings.direction; } else { Debug.LogError("Ragdoll Loader: collider type is not supported (" + gO.name + ")"); } rB = gO.AddComponent <Rigidbody>(); rB.mass = rJ.rigidbodySettings.mass; if (editor) { Debug.Log("Ragdoll Loader: " + gO.name + " joint processed"); } count++; } else if (editor) { //Debug.LogWarning("AssignRagdoll: bone name not found in ragdoll (" + gO.name + ")"); } } foreach (GameObject gO in children.Values) { if (gO.name == target.name) { continue; } if (ragdollJointsDictionary.ContainsKey(gO.name)) { rJ = ragdollJointsDictionary[gO.name]; CharacterJoint cJ = gO.AddComponent <CharacterJoint>(); if (children.ContainsKey(rJ.characterJointSettings.connectedBody)) { cJ.connectedBody = children[rJ.characterJointSettings.connectedBody].GetComponent <Rigidbody>(); } else { Debug.LogError("Ragdoll Loader: connected joint not found (" + rJ.characterJointSettings.connectedBody + " with " + gO.name + ")"); } cJ.anchor = MathHelper.FromString(rJ.characterJointSettings.anchor); cJ.axis = MathHelper.FromString(rJ.characterJointSettings.axis); cJ.swingAxis = MathHelper.FromString(rJ.characterJointSettings.swingAxis); cJ.connectedAnchor = MathHelper.FromString(rJ.characterJointSettings.connectedAnchor); float spring = 225F; float damper = 10F; SoftJointLimitSpring sJLS = new SoftJointLimitSpring(); sJLS.damper = damper; sJLS.spring = spring; cJ.twistLimitSpring = sJLS; sJLS = new SoftJointLimitSpring(); sJLS.damper = damper; sJLS.spring = spring; cJ.swingLimitSpring = sJLS; float bounciness = .00F; // Joint bounciness when it hits the limit float contactDistance = 0; // 0 = Default SoftJointLimit sJL = new SoftJointLimit(); sJL.bounciness = bounciness;//rJ.characterJointSettings.lowTwistLimit_Bounciness; sJL.limit = rJ.characterJointSettings.lowTwistLimit_Limit; sJL.contactDistance = contactDistance; cJ.lowTwistLimit = sJL; sJL = new SoftJointLimit(); sJL.bounciness = bounciness;//rJ.characterJointSettings.highTwistLimit_Bounciness; sJL.limit = rJ.characterJointSettings.highTwistLimit_Limit; sJL.contactDistance = contactDistance; cJ.highTwistLimit = sJL; sJL = new SoftJointLimit(); sJL.bounciness = bounciness;//rJ.characterJointSettings.swing1Limit_Bounciness; sJL.limit = rJ.characterJointSettings.swing1Limit_Limit; sJL.contactDistance = contactDistance; cJ.swing1Limit = sJL; sJL = new SoftJointLimit(); sJL.bounciness = bounciness;//rJ.characterJointSettings.swing2Limit_Bounciness; sJL.limit = rJ.characterJointSettings.swing2Limit_Limit; sJL.contactDistance = contactDistance; cJ.swing2Limit = sJL; } } if (editor) { Debug.Log("Ragdoll Loader: " + count.ToString() + " joints processed"); Debug.Log("Success!"); } } else { Debug.LogError("Ragdoll Loader: target needs to be the root bone!"); } }
void OnWizardCreate() { if (!export) { string path = EditorUtility.OpenFilePanel("Load Ragdoll", "Assets", "xml"); if (path.Length != 0) { byte[] bytes = System.IO.File.ReadAllBytes(path); xml = XMLSerializer.ByteArrayToString(bytes); RagdollLoader.Load(xml, rootBone, true); } } else { if ((Selection.gameObjects == null) || (Selection.gameObjects.Length != 1)) { EditorUtility.DisplayDialog("Wrong selection", "Please select root bone to export the ragdoll", "OK"); return; } path = EditorUtility.SaveFilePanel("Save Ragdoll", "Assets", "Ragdoll", "xml"); GameObject gameObject = rootBone; List <RagdollJoint> ragdollJoints = new List <RagdollJoint>(); CharacterJoint[] jointsFromChildren = gameObject.GetComponents <CharacterJoint>(); if (jointsFromChildren.Length == 0) { Collider rootCollider = gameObject.GetComponent <Collider>(); Rigidbody rootRigidBody = gameObject.GetComponent <Rigidbody>(); if (rootCollider == null || rootRigidBody == null) { Debug.LogError("Ragdoll Exporter: root bone needs a collider and a rigidbody!"); return; } BoxColliderSettings boxColliderSettings = null; SphereColliderSettings sphereColliderSettings = null; CapsuleColliderSettings capsuleColliderSettings = null; if (rootCollider is BoxCollider) { BoxCollider cast = (BoxCollider)rootCollider; boxColliderSettings = new BoxColliderSettings(); boxColliderSettings.center = cast.center.ToString("G4"); boxColliderSettings.size = cast.size.ToString("G4"); } else if (rootCollider is SphereCollider) { SphereCollider cast = (SphereCollider)rootCollider; sphereColliderSettings = new SphereColliderSettings(); sphereColliderSettings.center = cast.center.ToString("G4"); sphereColliderSettings.radius = cast.radius; } else if (rootCollider is CapsuleCollider) { CapsuleCollider cast = (CapsuleCollider)rootCollider; capsuleColliderSettings = new CapsuleColliderSettings(); capsuleColliderSettings.center = cast.center.ToString("G4"); capsuleColliderSettings.radius = cast.radius; capsuleColliderSettings.height = cast.height; capsuleColliderSettings.direction = cast.direction; } RigidbodySettings rigidbodySettings = new RigidbodySettings(); rigidbodySettings.mass = rootRigidBody.mass; RagdollJoint ragdollJoint = new RagdollJoint(); ragdollJoint.boneName = gameObject.name; ragdollJoint.characterJointSettings = null; ragdollJoint.boxColliderSettings = boxColliderSettings; ragdollJoint.sphereColliderSettings = sphereColliderSettings; ragdollJoint.capsuleColliderSettings = capsuleColliderSettings; ragdollJoint.rigidbodySettings = rigidbodySettings; ragdollJoints.Add(ragdollJoint); } else { EditorUtility.DisplayDialog("Wrong selection", "Please select root bone to export the ragdoll", "OK"); return; } // Iterate over all character joints because it is easy to get rigidbody and collider from a joint but not the other way around jointsFromChildren = gameObject.GetComponentsInChildren <CharacterJoint>(); Debug.Log("Ragdoll Exporter: " + gameObject.name + " joint processed"); foreach (CharacterJoint joint in jointsFromChildren) { Rigidbody rigidbody = joint.gameObject.GetComponent <Rigidbody>(); Collider collider = joint.gameObject.GetComponent <Collider>(); if (rigidbody == null || collider == null) { Debug.LogWarning("Ragdoll Exporter: bone with CharacterJoint is missing a collider or rigidbody (" + joint.name + ")"); continue; } CharacterJointSettings characterJointSettings = new CharacterJointSettings(); characterJointSettings.connectedBody = joint.connectedBody.name; characterJointSettings.anchor = joint.anchor.ToString("G4"); characterJointSettings.axis = joint.axis.ToString("G4"); characterJointSettings.connectedAnchor = joint.connectedAnchor.ToString("G4"); characterJointSettings.swingAxis = joint.swingAxis.ToString("G4"); characterJointSettings.lowTwistLimit_Bounciness = joint.lowTwistLimit.bounciness; characterJointSettings.lowTwistLimit_Limit = joint.lowTwistLimit.limit; characterJointSettings.highTwistLimit_Bounciness = joint.highTwistLimit.bounciness; characterJointSettings.highTwistLimit_Limit = joint.highTwistLimit.limit; characterJointSettings.swing1Limit_Bounciness = joint.swing1Limit.bounciness; characterJointSettings.swing1Limit_Limit = joint.swing1Limit.limit; characterJointSettings.swing2Limit_Bounciness = joint.swing2Limit.bounciness; characterJointSettings.swing2Limit_Limit = joint.swing2Limit.limit; BoxColliderSettings boxColliderSettings = null; SphereColliderSettings sphereColliderSettings = null; CapsuleColliderSettings capsuleColliderSettings = null; if (collider is BoxCollider) { BoxCollider cast = (BoxCollider)collider; boxColliderSettings = new BoxColliderSettings(); boxColliderSettings.center = cast.center.ToString("G4"); boxColliderSettings.size = cast.size.ToString("G4"); } else if (collider is SphereCollider) { SphereCollider cast = (SphereCollider)collider; sphereColliderSettings = new SphereColliderSettings(); sphereColliderSettings.center = cast.center.ToString("G4"); sphereColliderSettings.radius = cast.radius; } else if (collider is CapsuleCollider) { CapsuleCollider cast = (CapsuleCollider)collider; capsuleColliderSettings = new CapsuleColliderSettings(); capsuleColliderSettings.center = cast.center.ToString("G4"); capsuleColliderSettings.radius = cast.radius; capsuleColliderSettings.height = cast.height; capsuleColliderSettings.direction = cast.direction; } RigidbodySettings rigidbodySettings = new RigidbodySettings(); rigidbodySettings.mass = rigidbody.mass; RagdollJoint ragdollJoint = new RagdollJoint(); ragdollJoint.boneName = joint.name; ragdollJoint.characterJointSettings = characterJointSettings; ragdollJoint.boxColliderSettings = boxColliderSettings; ragdollJoint.sphereColliderSettings = sphereColliderSettings; ragdollJoint.capsuleColliderSettings = capsuleColliderSettings; ragdollJoint.rigidbodySettings = rigidbodySettings; ragdollJoints.Add(ragdollJoint); Debug.Log("Ragdoll Exporter: " + joint.name + " joint processed"); } if (path == null || path == "") { Debug.Log("Ragdoll Exporter: operation cancelled"); return; } Ragdoll rD = new Ragdoll(); rD.ragdollJoints = ragdollJoints.ToArray(); string xml = XMLSerializer.SerializeObject(rD); using (StreamWriter writer = new StreamWriter(path, false)) { try { writer.Write(xml); } catch (System.Exception ex) { string msg = " threw:\n" + ex.ToString(); Debug.LogError(msg); EditorUtility.DisplayDialog("Error on export", msg, "OK"); } } Debug.Log("Ragdoll Exporter: " + (jointsFromChildren.Length + 1).ToString() + " joints processed"); Debug.Log("Success!"); } }
// Update is called once per frame void Update() { // Get forward and right direction on x-z plane relative to camera Vector3 cameraForward = Vector3.ProjectOnPlane(cam.transform.forward, Vector3.up); Vector3 cameraRight = new Vector3(cameraForward.z, 0, -cameraForward.x); Vector3.OrthoNormalize(ref cameraForward, ref cameraRight); m_movementInput = cameraForward * Input.GetAxis("Vertical") + cameraRight * Input.GetAxis("Horizontal"); m_movementInput *= Speed; if (Input.GetButtonDown("Jump")) { m_jump = true; } if (Input.GetButtonDown("Crouch")) { m_movingCharacter.SetCrouching(!m_movingCharacter.Crouched); m_animator.SetBool("Crouching", m_movingCharacter.Crouched); // Maybe can't be crouched in jump? } if (Input.GetButtonDown("Fire1")) { Ray clickRay = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(clickRay, out hit, float.PositiveInfinity, ShootMask, QueryTriggerInteraction.Collide)) { // second raycast from head to clicked position to check laser can hit Ray shotRay = new Ray(ShotOrigin.position, hit.point - ShotOrigin.position); if (Physics.Raycast(shotRay, out hit, ShotRange, ShootMask, QueryTriggerInteraction.Collide)) { // draw beam being shot GameObject laser = Instantiate(ShotLine); LineRenderer laserLine = laser.GetComponent <LineRenderer>(); laserLine.SetPosition(0, ShotOrigin.position); laserLine.SetPosition(1, hit.point); Destroy(laser, LaserEffectTime); RagdollJoint dollJoint = hit.collider.GetComponent <RagdollJoint>(); EnemyController enemy = hit.collider.GetComponentInParent <EnemyController>(); if (enemy != null && dollJoint != null) { // If hit an enemy, damage them int shotDamage = Damage; if (dollJoint.Part == RagdollPart.Head) { shotDamage = HeadshotDamage; Debug.Log("Headshot on enemy"); } else { Debug.Log("Shot enemy"); } Vector3 direction = hit.point - ShotOrigin.position; enemy.Shoot(dollJoint, shotDamage, direction.normalized * ShotForce, hit.point); } // If nothing hit, just put smoke effect GameObject smoke = Instantiate(SmokeEffect); smoke.transform.position = hit.point; smoke.transform.eulerAngles = new Vector3(-90, 0, 0); Destroy(smoke, 5); } } } // Quit game on esc if (Input.GetButtonDown("Cancel")) { Application.Quit(); } }