summaryrefslogtreecommitdiff
path: root/ActiveRagdoll/Assets/Scripts/PlayerController.cs
diff options
context:
space:
mode:
authorchai <215380520@qq.com>2023-10-18 10:16:32 +0800
committerchai <215380520@qq.com>2023-10-18 10:16:32 +0800
commit4ccd4bc6d126e0e0f51a50aa10c85b9bf48b1210 (patch)
tree9ac931da935b59a8d7c57ff0b6d90b88a0e5a479 /ActiveRagdoll/Assets/Scripts/PlayerController.cs
+ init
Diffstat (limited to 'ActiveRagdoll/Assets/Scripts/PlayerController.cs')
-rw-r--r--ActiveRagdoll/Assets/Scripts/PlayerController.cs315
1 files changed, 315 insertions, 0 deletions
diff --git a/ActiveRagdoll/Assets/Scripts/PlayerController.cs b/ActiveRagdoll/Assets/Scripts/PlayerController.cs
new file mode 100644
index 0000000..21eaa01
--- /dev/null
+++ b/ActiveRagdoll/Assets/Scripts/PlayerController.cs
@@ -0,0 +1,315 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Unity.VisualScripting;
+using UnityEngine;
+using UnityEngine.Scripting.APIUpdating;
+
+/// <summary>
+/// 角色控制器
+/// </summary>
+public class PlayerController : MonoBehaviour
+{
+ #region 序列化
+ public Rigidbody[] m_RigsToLift;
+ public ConstantForce m_LeftKneeForce;
+ public ConstantForce m_RightKneeForce;
+ [Header("Gravity")]
+ public Vector3 m_ExtraGravity;
+ [Header("TurnBody")]
+ public float m_TorqueForce;
+ [Header("Stand")]
+ public float m_StandHeight;
+ public float m_StandUpForceMultiplier;
+ public AnimationCurve m_StandUpForceCurve;
+ [Header("Move")]
+ public float m_HorizontalMoveForce;
+ public float m_JumpForce;
+ public float m_SwitchLegInterval;
+ public float m_LegAngle;
+ public float m_TorsoForce;
+ [Header("动画")]
+ public JointAnimation m_MoveAnimation;
+ #endregion
+
+ #region 公有字段
+ [NonSerialized] public CharacterInformation info;
+
+ public Vector3 forward
+ {
+ get
+ {
+ return -transform.forward;
+ }
+ }
+
+ #endregion
+
+ #region 私有字段
+ private Rigidbody[] m_AllRigidBodies;
+ private Rigidbody m_HipRigidBody;
+ private Rigidbody m_HeadRigidBody;
+ private Rigidbody m_TorsoRigidBody;
+ private Rigidbody m_LegLeftRigidBody;
+ private Rigidbody m_LegRightRigidBody;
+
+ private Quaternion m_TowardDirection; // 朝向角度
+
+ private bool m_LastMove;
+ private bool m_DoJump;
+ private bool m_DoMoveLeft;
+ private bool m_DoMoveRight;
+
+ private float m_StepSwitchTimer;
+ private bool m_IsLeftForward;
+
+ private float m_FallenGravityFactor;
+
+ #endregion
+
+ private void Awake()
+ {
+ InitRigidBodies();
+
+ m_HipRigidBody = transform.Find("Rigidbodies/Hip").GetComponent<Rigidbody>();
+ m_HeadRigidBody = transform.Find("Rigidbodies/Head").GetComponent<Rigidbody>();
+ m_TorsoRigidBody = transform.Find("Rigidbodies/Torso").GetComponent<Rigidbody>();
+ m_LegLeftRigidBody = transform.Find("Rigidbodies/Leg_Left").GetComponent<Rigidbody>();
+ m_LegRightRigidBody = transform.Find("Rigidbodies/Leg_Right").GetComponent<Rigidbody>();
+
+ info = GetComponent<CharacterInformation>();
+
+ m_TowardDirection = Quaternion.Euler(0, -90, 0);
+ m_DoJump = false;
+ m_LastMove = false;
+ }
+
+ private void Update()
+ {
+ m_DoMoveLeft = false;
+ m_DoMoveRight = false;
+
+ if (Input.GetKey(KeyCode.A))
+ {
+ m_TowardDirection = Quaternion.Euler(0, -90, 0);
+ }
+ if (Input.GetKey(KeyCode.D))
+ {
+ m_TowardDirection = Quaternion.Euler(0, 90, 0);
+ }
+ if (Input.GetKeyDown(KeyCode.W))
+ {
+ m_DoJump = true;
+ }
+ if (Input.GetKey(KeyCode.A))
+ {
+ m_DoMoveLeft = true;
+ }
+ if (Input.GetKey(KeyCode.D))
+ {
+ m_DoMoveRight = true;
+ }
+
+ m_StepSwitchTimer += Time.deltaTime;
+ if(m_StepSwitchTimer > m_SwitchLegInterval && Vector3.Angle(m_LegLeftRigidBody.transform.up, m_LegRightRigidBody.transform.up) > m_LegAngle)
+ {
+ m_IsLeftForward = !m_IsLeftForward;
+ m_StepSwitchTimer = m_StepSwitchTimer - m_SwitchLegInterval;
+ }
+ }
+
+ private void FixedUpdate()
+ {
+ StandUp();
+ TurnBody();
+ OnMove();
+ }
+
+ private void OnMove()
+ {
+ if (!(m_DoMoveLeft || m_DoMoveRight || m_DoJump))
+ {
+ m_LastMove = false;
+ return;
+ }
+
+ //if (info.sinceTurn != 0)
+ //{
+ // return;
+ //}
+
+ if (!m_LastMove) // enter move
+ {
+ m_StepSwitchTimer = 0;
+
+ m_LastMove = true;
+ }
+
+ m_MoveAnimation.Animate();
+
+ if(m_DoMoveLeft)
+ {
+ MoveLeft();
+ }
+ if (m_DoMoveRight)
+ {
+ MoveRight();
+ }
+ if (m_DoJump)
+ {
+ Jump();
+ m_DoJump = false;
+ }
+ }
+
+ void MoveLeft()
+ {
+ DoActionToAllRigidbodies((rig, i) => {
+ rig.AddForce(Vector3.left * m_HorizontalMoveForce * Time.fixedDeltaTime, ForceMode.Acceleration);
+ });
+ m_TorsoRigidBody.AddForce(Vector3.left * m_TorsoForce, ForceMode.Force);
+ }
+
+ void MoveRight()
+ {
+ DoActionToAllRigidbodies((rig, i) =>
+ {
+ rig.AddForce(Vector3.right * m_HorizontalMoveForce * Time.fixedDeltaTime, ForceMode.Acceleration);
+ });
+ m_TorsoRigidBody.AddForce(Vector3.right * m_TorsoForce, ForceMode.Force);
+ }
+
+ void Jump()
+ {
+ if(info.isGrounded || info.sinceGrounded < 0.2f)
+ {
+ Debug.Log("Jump");
+ DoActionToAllRigidbodies((rig) => {
+ rig.AddForce(Vector3.up * m_JumpForce * Time.fixedDeltaTime, ForceMode.VelocityChange);
+ });
+ }
+ }
+
+ private void StandUp()
+ {
+ if (!info.isGrounded) // air
+ {
+ m_FallenGravityFactor += Time.fixedDeltaTime;
+ //m_FallenGravityFactor = Mathf.Clamp(m_FallenGravityFactor, 0, 1);
+
+ ApplyExtraGravity();
+ }
+ else // grounded
+ {
+ m_FallenGravityFactor = 0;
+
+ //Vector3 standUpForce = m_StandUpForce * Vector3.up * (m_StandHeight - info.shortestDistanceFromHeadToGround);
+ float headHeight = info.HeadRayCast();
+ if(headHeight < m_StandHeight)
+ {
+ float t = 1 - (m_StandHeight - headHeight) / m_StandHeight;
+ t = Mathf.Clamp(t, 0, 1);
+ //Debug.Log(t);
+ Vector3 standUpForce = m_StandUpForceMultiplier * m_StandUpForceCurve.Evaluate(t) * Vector3.up;
+ for (int i = 0; i < m_RigsToLift.Length; i++)
+ {
+ m_RigsToLift[i].AddForce(info.GetTotalMass() * standUpForce + info.GetTotalMass() * -Physics.gravity, ForceMode.Force);
+ }
+ }
+ }
+
+ if(info.sinceGrounded < 0.3f)
+ {
+ m_LeftKneeForce.enabled = true;
+ m_RightKneeForce.enabled = true;
+ }
+ else
+ {
+ m_LeftKneeForce.enabled = false;
+ m_RightKneeForce.enabled = false;
+ }
+ }
+
+ private void TurnBody()
+ {
+ Vector3 properForward = m_TowardDirection * -Vector3.forward;
+ float angel = Vector3.Angle(m_HipRigidBody.transform.forward, properForward);
+ Vector3 dir = Vector3.Cross(m_HipRigidBody.transform.forward, properForward);
+ if(Mathf.Abs(angel) < 5f)
+ {
+ info.sinceTurn = 0;
+ }
+ if(dir.y > 0)
+ {
+ m_HipRigidBody.AddTorque(Vector3.up * angel * m_TorqueForce, ForceMode.Acceleration) ;
+ }
+ else if(dir.y < 0)
+ {
+ m_HipRigidBody.AddTorque(-Vector3.up * angel * m_TorqueForce, ForceMode.Acceleration);
+ }
+ }
+
+ /// <summary>
+ /// 初始化rigidbody
+ /// </summary>
+ private void InitRigidBodies() //初始化刚体,编号
+ {
+ this.m_AllRigidBodies = base.GetComponentsInChildren<Rigidbody>();
+ DoActionToAllRigidbodies((rig, i) => {
+ });
+
+ IgnoreCollision();
+ }
+
+ /// <summary>
+ /// 屏蔽身体各部件之间的碰撞
+ /// </summary>
+ public void IgnoreCollision()
+ {
+ for (int i = 0; i < m_AllRigidBodies.Length - 1; i++)
+ {
+ for (int j = i + 1; j < m_AllRigidBodies.Length; j++)
+ {
+ Collider collider1 = m_AllRigidBodies[i].GetComponent<Collider>();
+ Collider collider2 = m_AllRigidBodies[j].GetComponent<Collider>();
+ Physics.IgnoreCollision(collider1, collider2, true);
+ }
+ }
+ }
+
+ private void ApplyExtraGravity()
+ {
+ DoActionToAllRigidbodies((rig) => {
+ rig.AddForce(m_ExtraGravity * m_FallenGravityFactor, ForceMode.Acceleration);
+ });
+ }
+
+ private void DoActionToAllRigidbodies(Action<Rigidbody> action)
+ {
+ DoActionToAllRigidbodies((rig, i) => {
+ action(rig);
+ });
+ }
+
+ private void DoActionToAllRigidbodies(Action<Rigidbody, int> action)
+ {
+ for (int i = 0; i < m_AllRigidBodies.Length; ++i)
+ {
+ if (action != null)
+ {
+ action(m_AllRigidBodies[i], i);
+ }
+ }
+ }
+
+ public bool StepLeft()
+ {
+ return m_IsLeftForward;
+ }
+
+ public bool StepRight()
+ {
+ return !m_IsLeftForward;
+ }
+
+} \ No newline at end of file