前提・実現したいこと
現在、unityのStandard Assetes内のThirdPersonCharacterを用いてキャラクターを操作できるようなプログラムを作っています。
これに手を加えて、空中でも移動キーの入力に応じて移動する方向・速度を変えられるようなプログラムにしたいと考えています。
発生している問題・エラーメッセージ
配布されている状態ではジャンプしている状態で移動キーを入力しても、キャラクターの向いている方向だけは変更できるものの、
ジャンプした時点で跳んだ方向・距離は固定されて着地までそれらに対する操作を受け付けなくなります。
該当のソースコード
以下はThirdPersonCharacterの内容です。
C#
1using UnityEngine; 2 3namespace UnityStandardAssets.Characters.ThirdPerson 4{ 5 [RequireComponent(typeof(Rigidbody))] 6 [RequireComponent(typeof(CapsuleCollider))] 7 [RequireComponent(typeof(Animator))] 8 public class ThirdPersonCharacter : MonoBehaviour 9 { 10 [SerializeField] float m_MovingTurnSpeed = 360; 11 [SerializeField] float m_StationaryTurnSpeed = 180; 12 [SerializeField] float m_JumpPower = 12f; 13 [Range(1f, 4f)][SerializeField] float m_GravityMultiplier = 2f; 14 [SerializeField] float m_RunCycleLegOffset = 0.2f; //specific to the character in sample assets, will need to be modified to work with others 15 [SerializeField] float m_MoveSpeedMultiplier = 1f; 16 [SerializeField] float m_AnimSpeedMultiplier = 1f; 17 [SerializeField] float m_GroundCheckDistance = 0.1f; 18 19 Rigidbody m_Rigidbody; 20 Animator m_Animator; 21 bool m_IsGrounded; 22 float m_OrigGroundCheckDistance; 23 const float k_Half = 0.5f; 24 float m_TurnAmount; 25 float m_ForwardAmount; 26 Vector3 m_GroundNormal; 27 float m_CapsuleHeight; 28 Vector3 m_CapsuleCenter; 29 CapsuleCollider m_Capsule; 30 bool m_Crouching; 31 32 33 void Start() 34 { 35 36 m_Animator = GetComponent<Animator>(); 37 m_Rigidbody = GetComponent<Rigidbody>(); 38 m_Capsule = GetComponent<CapsuleCollider>(); 39 m_CapsuleHeight = m_Capsule.height; 40 m_CapsuleCenter = m_Capsule.center; 41 42 m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ; 43 m_OrigGroundCheckDistance = m_GroundCheckDistance; 44 } 45 46 47 public void Move(Vector3 move, bool crouch, bool jump) 48 { 49 50 // convert the world relative moveInput vector into a local-relative 51 // turn amount and forward amount required to head in the desired 52 // direction. 53 if (move.magnitude > 1f) move.Normalize(); 54 move = transform.InverseTransformDirection(move); 55 CheckGroundStatus(); 56 move = Vector3.ProjectOnPlane(move, m_GroundNormal); 57 m_TurnAmount = Mathf.Atan2(move.x, move.z); 58 m_ForwardAmount = move.z; 59 60 ApplyExtraTurnRotation(); 61 62 // control and velocity handling is different when grounded and airborne: 63 if (m_IsGrounded) 64 { 65 HandleGroundedMovement(crouch, jump); 66 } 67 else 68 { 69 HandleAirborneMovement(); 70 } 71 72 ScaleCapsuleForCrouching(crouch); 73 PreventStandingInLowHeadroom(); 74 75 // send input and other state parameters to the animator 76 UpdateAnimator(move); 77 78 } 79 80 81 void ScaleCapsuleForCrouching(bool crouch) 82 { 83 if (m_IsGrounded && crouch) 84 { 85 if (m_Crouching) return; 86 m_Capsule.height = m_Capsule.height / 2f; 87 m_Capsule.center = m_Capsule.center / 2f; 88 m_Crouching = true; 89 } 90 else 91 { 92 Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up); 93 float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_Half; 94 if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength, Physics.AllLayers, QueryTriggerInteraction.Ignore)) 95 { 96 m_Crouching = true; 97 return; 98 } 99 m_Capsule.height = m_CapsuleHeight; 100 m_Capsule.center = m_CapsuleCenter; 101 m_Crouching = false; 102 } 103 } 104 105 void PreventStandingInLowHeadroom() 106 { 107 // prevent standing up in crouch-only zones 108 if (!m_Crouching) 109 { 110 Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up); 111 float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_Half; 112 if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength, Physics.AllLayers, QueryTriggerInteraction.Ignore)) 113 { 114 m_Crouching = true; 115 } 116 } 117 } 118 119 120 void UpdateAnimator(Vector3 move) 121 { 122 // update the animator parameters 123 m_Animator.SetFloat("Forward", m_ForwardAmount, 0.1f, Time.deltaTime); 124 m_Animator.SetFloat("Turn", m_TurnAmount, 0.1f, Time.deltaTime); 125 m_Animator.SetBool("Crouch", m_Crouching); 126 m_Animator.SetBool("OnGround", m_IsGrounded); 127 if (!m_IsGrounded) 128 { 129 m_Animator.SetFloat("Jump", m_Rigidbody.velocity.y); 130 } 131 132 // calculate which leg is behind, so as to leave that leg trailing in the jump animation 133 // (This code is reliant on the specific run cycle offset in our animations, 134 // and assumes one leg passes the other at the normalized clip times of 0.0 and 0.5) 135 float runCycle = 136 Mathf.Repeat( 137 m_Animator.GetCurrentAnimatorStateInfo(0).normalizedTime + m_RunCycleLegOffset, 1); 138 float jumpLeg = (runCycle < k_Half ? 1 : -1) * m_ForwardAmount; 139 if (m_IsGrounded) 140 { 141 m_Animator.SetFloat("JumpLeg", jumpLeg); 142 } 143 144 // the anim speed multiplier allows the overall speed of walking/running to be tweaked in the inspector, 145 // which affects the movement speed because of the root motion. 146 if (m_IsGrounded && move.magnitude > 0) 147 { 148 m_Animator.speed = m_AnimSpeedMultiplier; 149 } 150 else 151 { 152 // don't use that while airborne 153 m_Animator.speed = 1; 154 } 155 } 156 157 158 void HandleAirborneMovement() 159 { 160 // apply extra gravity from multiplier: 161 Vector3 extraGravityForce = (Physics.gravity * m_GravityMultiplier) - Physics.gravity; 162 m_Rigidbody.AddForce(extraGravityForce); 163 164 165 m_GroundCheckDistance = m_Rigidbody.velocity.y < 0 ? m_OrigGroundCheckDistance : 0.05f; 166 } 167 168 169 void HandleGroundedMovement(bool crouch, bool jump) 170 { 171 // check whether conditions are right to allow a jump: 172 if (jump && !crouch && m_Animator.GetCurrentAnimatorStateInfo(0).IsName("Grounded")) 173 { 174 // jump! 175 m_Rigidbody.velocity = new Vector3(m_Rigidbody.velocity.x, m_JumpPower, m_Rigidbody.velocity.z); 176 m_IsGrounded = false; 177 m_Animator.applyRootMotion = false; 178 m_GroundCheckDistance = 0.1f; 179 } 180 } 181 182 void ApplyExtraTurnRotation() 183 { 184 // help the character turn faster (this is in addition to root rotation in the animation) 185 float turnSpeed = Mathf.Lerp(m_StationaryTurnSpeed, m_MovingTurnSpeed, m_ForwardAmount); 186 transform.Rotate(0, m_TurnAmount * turnSpeed * Time.deltaTime, 0); 187 } 188 189 190 public void OnAnimatorMove() 191 { 192 // we implement this function to override the default root motion. 193 // this allows us to modify the positional speed before it's applied. 194 if (m_IsGrounded && Time.deltaTime > 0) 195 { 196 Vector3 v = (m_Animator.deltaPosition * m_MoveSpeedMultiplier) / Time.deltaTime; 197 198 // we preserve the existing y part of the current velocity. 199 v.y = m_Rigidbody.velocity.y; 200 m_Rigidbody.velocity = v; 201 } 202 } 203 204 205 void CheckGroundStatus() 206 { 207 RaycastHit hitInfo; 208#if UNITY_EDITOR 209 // helper to visualise the ground check ray in the scene view 210 Debug.DrawLine(transform.position + (Vector3.up * 0.1f), transform.position + (Vector3.up * 0.1f) + (Vector3.down * m_GroundCheckDistance)); 211#endif 212 // 0.1f is a small offset to start the ray from inside the character 213 // it is also good to note that the transform position in the sample assets is at the base of the character 214 if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance)) 215 { 216 m_GroundNormal = hitInfo.normal; 217 m_IsGrounded = true; 218 m_Animator.applyRootMotion = true; 219 } 220 else 221 { 222 m_IsGrounded = false; 223 m_GroundNormal = Vector3.up; 224 m_Animator.applyRootMotion = false; 225 } 226 } 227 } 228}
試したこと
ネット上の情報は隅々まで調べましたが、有効な情報は得られませんでした。
また、プログラムの一部をコメントアウトする方法を様々な位置で試してみましたが、いずれも上手く動きませんでした。
補足情報(FW/ツールのバージョンなど)
Unity バージョン:2020.3.4f1
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/14 10:40