diff options
Diffstat (limited to '_ActiveRagdoll/Actions')
-rw-r--r-- | _ActiveRagdoll/Actions/Gravity.cs | 52 | ||||
-rw-r--r-- | _ActiveRagdoll/Actions/Holding.cs | 289 | ||||
-rw-r--r-- | _ActiveRagdoll/Actions/PlayerDeath.cs | 126 | ||||
-rw-r--r-- | _ActiveRagdoll/Actions/PlayerKnockback.cs | 53 | ||||
-rw-r--r-- | _ActiveRagdoll/Actions/SetAnimationByInput.cs | 41 | ||||
-rw-r--r-- | _ActiveRagdoll/Actions/SetAnimationByVelocity.cs | 12 | ||||
-rw-r--r-- | _ActiveRagdoll/Actions/StayInPlace.cs | 51 |
7 files changed, 624 insertions, 0 deletions
diff --git a/_ActiveRagdoll/Actions/Gravity.cs b/_ActiveRagdoll/Actions/Gravity.cs new file mode 100644 index 0000000..42f3125 --- /dev/null +++ b/_ActiveRagdoll/Actions/Gravity.cs @@ -0,0 +1,52 @@ +using UnityEngine; + +public class Gravity : MonoBehaviour +{ + public float baseGravity;//5 + + public float scalingGravity;//70 + + private RigidbodyHolder allRigs;//14个全部 + + private StandingDataHandler standingData; + + private Holding holding; + + private PlayerDeath death; + + private void Start() + { + death = GetComponent<PlayerDeath>(); + allRigs = GetComponent<RigidbodyHolder>(); + standingData = GetComponent<StandingDataHandler>(); + holding = GetComponent<Holding>(); + } + + private void FixedUpdate() + { + if (death.dead) + { + return; + } + for (int i = 0; i < allRigs.GetAllRigs().Length; i++) + { + // standingData.sinceGrounded是离地时间 + Vector3 g = Vector3.down * baseGravity + Vector3.down * scalingGravity * standingData.sinceGrounded; + // 重力=持久的基础重力+随着离地状态变化的重力,离地时增加额外重力 + allRigs.GetAllRigs()[i].AddForce(g, ForceMode.Acceleration); + //Debug.Log(g); + //Debug.Log(standingData.sinceGrounded); + } + if ((bool)holding) + { + if ((bool)holding.heldObject) + { + holding.heldObject.rig.AddForce(Vector3.down * baseGravity + Vector3.down * scalingGravity * standingData.sinceGrounded, ForceMode.Acceleration); + } + if ((bool)holding.heldObjectOffHand) + { + holding.heldObjectOffHand.rig.AddForce(Vector3.down * baseGravity + Vector3.down * scalingGravity * standingData.sinceGrounded, ForceMode.Acceleration); + } + } + } +} diff --git a/_ActiveRagdoll/Actions/Holding.cs b/_ActiveRagdoll/Actions/Holding.cs new file mode 100644 index 0000000..eb27095 --- /dev/null +++ b/_ActiveRagdoll/Actions/Holding.cs @@ -0,0 +1,289 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +//Player Holding 动作-拿武器 +public class Holding : MonoBehaviour +{ + [HideInInspector] + public HoldableObject heldObject; + + [HideInInspector] + public HoldableObject heldObjectOffHand; + + [HideInInspector] + public Transform baseTransform; + + private Rigidbody rightHand; + + private Rigidbody leftHand; + + [HideInInspector] + public ConfigurableJoint leftHandJoint; + + [HideInInspector] + public ConfigurableJoint rightHandJoint; + + public float grabForce; + + [HideInInspector] + public bool isGrabbing; + + private Transform rotaionTarget; + + private bool hasMainHandWeapon; + + private PlayerDeath death; + + public LayerMask mask = default(LayerMask); + + private Strength str; + + private float strength = 1f; + + private PID leftHandPID; + + private PID rightHandPID; + + private StandingDataHandler standingData; + + private void Awake() + { + death = GetComponent<PlayerDeath>(); + standingData = GetComponent<StandingDataHandler>(); + str = GetComponent<Strength>(); + if (!baseTransform) + { + baseTransform = GetComponentInChildren<HoldingBaseTransform>().transform; + } + rightHand = GetComponentInChildren<HandRight>().GetComponent<Rigidbody>(); + leftHand = GetComponentInChildren<HandLeft>().GetComponent<Rigidbody>(); + rotaionTarget = base.transform.GetComponentInChildren<RotationTarget>().transform; + mask = LayerMask.GetMask("Map"); + leftHandPID = leftHand.GetComponent<PID>(); + rightHandPID = rightHand.GetComponent<PID>(); + } + + private void Update() + { + if (!death.dead && (bool)heldObject) + { + strength = str.strength; + if (((bool)rightHandJoint || !heldObject.rightHandPos) && ((bool)leftHandJoint || !heldObject.leftHandPos) && (!heldObjectOffHand || (((bool)rightHandJoint || !heldObjectOffHand.rightHandPos) && ((bool)leftHandJoint || !heldObjectOffHand.leftHandPos)))) + { + isGrabbing = false; + } + } + } + + private void FixedUpdate() + { + if (death.dead || isGrabbing) + { + return; + } + if ((bool)heldObject) + { + HoldObjectInPlace(heldObject.rig, heldObject, offHand: false, rightHand); + if (!heldObjectOffHand && (bool)leftHandJoint) + { + HoldObjectInPlace(heldObject.rig, heldObject, offHand: false, leftHand, justHand: true); + } + } + if ((bool)heldObjectOffHand) + { + HoldObjectInPlace(heldObjectOffHand.rig, heldObjectOffHand, offHand: true, leftHand); + } + } + + private void HoldObjectInPlace(Rigidbody rigi, HoldableObject held, bool offHand, Rigidbody hand, bool justHand = false) + { + Vector3 holdingPosition = held.holdingPosition; + if (offHand) + { + holdingPosition.x *= -1f; + } + holdingPosition = baseTransform.TransformPoint(holdingPosition); + Vector3 holdingRotation = held.holdingRotation; + Vector3 targetRotation = baseTransform.TransformDirection(holdingRotation); + Vector3 targetRotationUp = baseTransform.TransformDirection(held.holdingUpRotation); + if (!justHand) + { + held.pid.DoPID(holdingPosition, targetRotation, targetRotationUp, strength); + } + PID pID = rightHandPID; + Vector3 localPosition = held.rightHandPos.localPosition; + if (hand == leftHand) + { + localPosition = held.leftHandPos.localPosition; + pID = leftHandPID; + } + Vector3 position = held.holdingPosition + localPosition; + if (offHand) + { + position.x *= -1f; + } + position = baseTransform.TransformPoint(position); + Debug.DrawLine(position, position + Vector3.up); + Debug.DrawLine(holdingPosition, holdingPosition + Vector3.up); + pID.DoPID(position, Vector3.zero, Vector3.zero, strength); + } + + public void StartHolding(HoldableObject holdableObject, bool hasOffHand) + { + holdableObject.isHeld = true; + isGrabbing = true; + bool offHand = false; + if (!hasMainHandWeapon) + { + hasMainHandWeapon = true; + heldObject = holdableObject; + if ((bool)heldObject.rightHandPos) + { + StartCoroutine(Grab(mainHand: true, rightHand, heldObject, offHand: false)); + } + if ((bool)heldObject.leftHandPos && !hasOffHand) + { + StartCoroutine(Grab(mainHand: false, leftHand, heldObject, offHand: false)); + } + } + else + { + offHand = true; + heldObjectOffHand = holdableObject; + heldObjectOffHand.leftHandPos = heldObjectOffHand.rightHandPos; + if ((bool)heldObjectOffHand.rightHandPos) + { + StartCoroutine(Grab(mainHand: false, leftHand, heldObjectOffHand, offHand: true)); + } + } + StartCoroutine(HoldweaponStill(holdableObject.rig, offHand, holdableObject)); + } + + private IEnumerator Grab(bool mainHand, Rigidbody hand, HoldableObject held, bool offHand) + { + while (isGrabbing) + { + if (mainHand) + { + if (!rightHandJoint) + { + ReachForPoint(rightHand, rightHand.transform.GetChild(0).position, held.rightHandPos, isLeft: false, held.rig, held, offHand); + rightHand.GetComponentInChildren<Collider>().enabled = false; + } + } + else if (!leftHandJoint) + { + ReachForPoint(leftHand, leftHand.transform.GetChild(0).position, held.leftHandPos, isLeft: true, held.rig, held, offHand); + leftHand.GetComponentInChildren<Collider>().enabled = false; + } + yield return null; + } + leftHand.GetComponentInChildren<Collider>().enabled = true; + rightHand.GetComponentInChildren<Collider>().enabled = true; + } + + private IEnumerator HoldweaponStill(Rigidbody rigToGrab, bool offHand, HoldableObject held) + { + while (isGrabbing) + { + Vector3 pos = held.holdingPosition; + if (offHand) + { + pos.x *= -1f; + } + rigToGrab.transform.position = baseTransform.TransformPoint(pos); + rigToGrab.transform.rotation = Quaternion.LookRotation(baseTransform.TransformDirection(heldObject.holdingRotation)); + yield return null; + } + } + + public void Drop() + { + List<HoldableObject> list = new List<HoldableObject>(); + if ((bool)heldObject) + { + list.Add(heldObject); + } + if ((bool)heldObjectOffHand) + { + list.Add(heldObjectOffHand); + } + for (int i = 0; i < list.Count; i++) + { + list[i].holder = null; + list[i].isHeld = false; + list[i].rig.useGravity = true; + list[i].rig.drag = 0f; + list[i].rig.angularDrag = 0f; + Collider[] componentsInChildren = list[i].GetComponentsInChildren<Collider>(); + foreach (Collider collider in componentsInChildren) + { + collider.material = null; + } + } + heldObject = null; + heldObjectOffHand = null; + if ((bool)rightHandJoint) + { + Object.Destroy(rightHandJoint); + } + if ((bool)leftHandJoint) + { + Object.Destroy(leftHandJoint); + } + hasMainHandWeapon = false; + } + + private void ReachForPoint(Rigidbody rigToReach, Vector3 forcePosition, Transform targetPositionTransform, bool isLeft, Rigidbody rigToGrab, HoldableObject held, bool offHand) + { + Vector3 normalized = (targetPositionTransform.position - forcePosition).normalized; + rigToReach.AddForceAtPosition(normalized * grabForce * Mathf.Clamp(Time.deltaTime, 0f, 0.1f), forcePosition, ForceMode.Acceleration); + if (Vector3.Distance(targetPositionTransform.position, forcePosition) < 0.5f) + { + ConnectRig(rigToReach, rigToGrab, targetPositionTransform, isLeft, held, offHand); + } + } + + private void ConnectRig(Rigidbody startRig, Rigidbody targetRig, Transform targetPositionTransform, bool isLeft, HoldableObject held, bool offHand) + { + ConfigurableJoint configurableJoint = startRig.gameObject.AddComponent<ConfigurableJoint>(); + if (offHand) + { + targetPositionTransform.localRotation = Quaternion.Euler(targetPositionTransform.localEulerAngles.x, 0f - targetPositionTransform.localEulerAngles.y, targetPositionTransform.localEulerAngles.z); + } + startRig.transform.rotation = targetPositionTransform.rotation; + startRig.transform.position += targetPositionTransform.position - startRig.transform.GetChild(0).position; + configurableJoint.connectedBody = targetRig; + configurableJoint.projectionMode = JointProjectionMode.PositionAndRotation; + configurableJoint.xMotion = ConfigurableJointMotion.Locked; + configurableJoint.yMotion = ConfigurableJointMotion.Locked; + configurableJoint.zMotion = ConfigurableJointMotion.Locked; + configurableJoint.angularXMotion = ConfigurableJointMotion.Limited; + configurableJoint.angularYMotion = ConfigurableJointMotion.Limited; + configurableJoint.angularZMotion = ConfigurableJointMotion.Limited; + SoftJointLimit highAngularXLimit = configurableJoint.highAngularXLimit; + highAngularXLimit.limit = held.swingAngles.y; + configurableJoint.highAngularXLimit = highAngularXLimit; + highAngularXLimit.limit = held.swingAngles.x; + configurableJoint.lowAngularXLimit = highAngularXLimit; + highAngularXLimit.limit = held.twistAngles.x; + configurableJoint.angularYLimit = highAngularXLimit; + highAngularXLimit.limit = held.twistAngles.y; + configurableJoint.angularZLimit = highAngularXLimit; + SoftJointLimitSpring angularXLimitSpring = configurableJoint.angularXLimitSpring; + angularXLimitSpring.spring = held.swingSpring; + configurableJoint.angularXLimitSpring = angularXLimitSpring; + angularXLimitSpring.spring = held.twistSpring; + configurableJoint.angularYZLimitSpring = angularXLimitSpring; + configurableJoint.anchor = startRig.transform.InverseTransformPoint(startRig.transform.GetChild(0).position); + if (isLeft) + { + leftHandJoint = configurableJoint; + } + else + { + rightHandJoint = configurableJoint; + } + } +} diff --git a/_ActiveRagdoll/Actions/PlayerDeath.cs b/_ActiveRagdoll/Actions/PlayerDeath.cs new file mode 100644 index 0000000..637e713 --- /dev/null +++ b/_ActiveRagdoll/Actions/PlayerDeath.cs @@ -0,0 +1,126 @@ +using UnityEngine; + +//Player PlayerDeath 动作-角色死亡 +public class PlayerDeath : MonoBehaviour +{ + public bool dead; + + private bool isFrozen; + + public float muscleFunction = 1f; + + public bool terminalState; + + private DamageEffects damageEffects; + + private RagdollHandler ragdoll; + + private Transform hip; + + public float health = 100f; + + public ParticleSystem[] damageParticles; + + private HasControl hasControll; + + private Holding holding; + + private void Start() + { + damageEffects = GetComponent<DamageEffects>(); + ragdoll = GetComponent<RagdollHandler>(); + hip = GetComponentInChildren<Hip>().transform; + hasControll = GetComponent<HasControl>(); + holding = GetComponent<Holding>(); + } + + private void Update() + { + if (health < 100f) + { + health += Time.deltaTime * 10f; + health = Mathf.Clamp(health, -10f, 100f); + } + if (hip.transform.position.y < -10f) + { + Die(); + } + if (terminalState && muscleFunction > 0f) + { + muscleFunction -= Time.deltaTime * 1f; + } + if (muscleFunction < 0f && !isFrozen) + { + FreezeBody(); + } + } + + public void TakeDamage(Vector3 damage, Vector3 hitPoint, Rigidbody hitRig = null) + { + if (hasControll.hasControl) + { + damageEffects.TakeDamage(damage, hitPoint); + } + if (hitPoint != Vector3.zero) + { + for (int i = 0; i < damageParticles.Length; i++) + { + damageParticles[i].transform.rotation = Quaternion.LookRotation(damage); + damageParticles[i].transform.position = hitPoint; + damageParticles[i].Play(); + } + } + health -= damage.magnitude; + if (!(health <= 0f)) + { + return; + } + if ((bool)hitRig) + { + ConfigurableJoint component = hitRig.GetComponent<ConfigurableJoint>(); + if ((bool)component) + { + Object.Destroy(component); + } + } + Kill(); + } + + public void FreezeBody() + { + isFrozen = true; + Joint[] componentsInChildren = GetComponentsInChildren<Joint>(); + for (int i = 0; i < componentsInChildren.Length; i++) + { + ConfigurableJoint configurableJoint = (ConfigurableJoint)componentsInChildren[i]; + Rigidbody component = configurableJoint.GetComponent<Rigidbody>(); + JointDrive angularXDrive = configurableJoint.angularXDrive; + angularXDrive.positionSpring = 5f * component.mass; + angularXDrive.positionDamper = 1f * component.mass; + configurableJoint.angularXDrive = angularXDrive; + configurableJoint.angularYZDrive = angularXDrive; + configurableJoint.SetTargetRotationLocal(configurableJoint.transform.localRotation, configurableJoint.gameObject.GetComponent<StartRotation>().startRotationLocal); + } + } + + public void Die() + { + if (!dead) + { + holding.Drop(); + dead = true; + ragdoll.ragdollValue = 0f; + Collider[] componentsInChildren = GetComponentsInChildren<Collider>(); + foreach (Collider collider in componentsInChildren) + { + collider.material = null; + } + } + } + + public void Kill() + { + terminalState = true; + Die(); + } +} diff --git a/_ActiveRagdoll/Actions/PlayerKnockback.cs b/_ActiveRagdoll/Actions/PlayerKnockback.cs new file mode 100644 index 0000000..d4839bf --- /dev/null +++ b/_ActiveRagdoll/Actions/PlayerKnockback.cs @@ -0,0 +1,53 @@ +using UnityEngine; + +//Player PlayerKnockback 动作-击退 +public class PlayerKnockback : MonoBehaviour +{ + private RigidbodyHolder allRigs;//14 + + private StandingDataHandler standing; + + private WeaponHandler weapons; + + private void Start() + { + allRigs = GetComponent<RigidbodyHolder>(); + standing = GetComponent<StandingDataHandler>(); + weapons = GetComponent<WeaponHandler>(); + } + + private void Update() + { + if (Input.GetKeyDown(KeyCode.K)) //kill + { + AddSeriousKnockback(); + } + } + + public void AddForce(Vector3 force, Rigidbody rig) + { + if (force.magnitude > 200f) + { + AddSeriousKnockback(); + force *= 0.1f; + } + for (int i = 0; i < allRigs.GetAllRigs().Length; i++) + { + float num = 1f; + if (rig == allRigs.GetAllRigs()[i]) + { + num *= 1f; + } + allRigs.GetAllRigs()[i].AddForce(force * num * 20f, ForceMode.Acceleration); + } + } + + private void AddSeriousKnockback() + { + GetComponent<PlayerDeath>().Kill(); + } + + private void AddNormalKnockback() + { + } +} diff --git a/_ActiveRagdoll/Actions/SetAnimationByInput.cs b/_ActiveRagdoll/Actions/SetAnimationByInput.cs new file mode 100644 index 0000000..41948ec --- /dev/null +++ b/_ActiveRagdoll/Actions/SetAnimationByInput.cs @@ -0,0 +1,41 @@ +using UnityEngine; + +//Player SetAnimationByInput 根据键盘输入切换动作 +public class SetAnimationByInput : MonoBehaviour +{ + private InputHandler input; + + private AnimationHandler anim; + + private StandingDataHandler standingData; + + private void Start() + { + anim = GetComponent<AnimationHandler>(); + input = GetComponent<InputHandler>(); + standingData = GetComponent<StandingDataHandler>(); + } + + private void Update() + { + if ((double)standingData.sinceGrounded > 0.2) + { + anim.animationState = 3; + } + else if (input.inputMovementDirection.magnitude > 0.1f) + { + if (input.isSpringting) + { + anim.animationState = 1; + } + else + { + anim.animationState = 2; + } + } + else + { + anim.animationState = 0; + } + } +} diff --git a/_ActiveRagdoll/Actions/SetAnimationByVelocity.cs b/_ActiveRagdoll/Actions/SetAnimationByVelocity.cs new file mode 100644 index 0000000..c737363 --- /dev/null +++ b/_ActiveRagdoll/Actions/SetAnimationByVelocity.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +public class SetAnimationByVelocity : MonoBehaviour +{ + private void Start() + { + } + + private void Update() + { + } +} diff --git a/_ActiveRagdoll/Actions/StayInPlace.cs b/_ActiveRagdoll/Actions/StayInPlace.cs new file mode 100644 index 0000000..c8bdf4b --- /dev/null +++ b/_ActiveRagdoll/Actions/StayInPlace.cs @@ -0,0 +1,51 @@ +using UnityEngine; + +//Player StayInPlace 动作-移动到停止时停下来 +public class StayInPlace : MonoBehaviour +{ + private InputHandler input; + + public Rigidbody rig; // Hip + + public float force;// 100 + + private Vector3 stopPosition; + + private bool isBroken; + + private PlayerDeath death; + + private Strength str; + + private float strength = 1f; + + private void Start() + { + str = GetComponent<Strength>(); + input = GetComponent<InputHandler>(); + death = GetComponent<PlayerDeath>(); + stopPosition = rig.position; + } + + private void FixedUpdate() + { + if (death.dead) + { + return; + } + strength = str.strength; + if (input.inputMovementDirection.magnitude > 0.1f) // 移动 + { + stopPosition = rig.position + rig.velocity * 0.25f; + isBroken = false; + } + else if (!isBroken) // 移动到停下 + { + if (Vector3.Distance(stopPosition, rig.position) > 1f) + { + isBroken = true; + } + rig.AddForce((stopPosition - rig.position) * force * strength, ForceMode.Acceleration); + } + } +} |