/// <summary> /// プレイヤーから左右に壁がないか探す /// </summary> private void WallCheck() { if (wallRanIntervalFlag) { if (rightKeyFlag) { Ray rightRay = new Ray(transform.position, transform.right); RaycastHit rightHit; Debug.DrawRay(rightRay.origin, rightRay.direction * wallCheckDistance); if (Physics.Raycast(rightRay, out rightHit, wallCheckDistance, layer)) { playereState = PlayereState.WallRun; wallRunState = WallRunState.Right; } } if (leftKeyFlag) { Ray leftRay = new Ray(transform.position, transform.right * -1); RaycastHit leftHit; Debug.DrawRay(leftRay.origin, leftRay.direction * wallCheckDistance); if (Physics.Raycast(leftRay, out leftHit, wallCheckDistance, layer)) { playereState = PlayereState.WallRun; wallRunState = WallRunState.Left; } } } }
/// <summary> /// スライディングの移動処理 /// </summary> private void SlidingMovemnet() { //characterVelocityMomentum = Vector3.zero; if (!ctrlKey) { playereState = PlayereState.Default; return; } if (maxSpeed <= (Mathf.Abs(characterVelocity.x) + Mathf.Abs(characterVelocity.z))) { characterVelocity.y = 0; characterVelocity = characterVelocity.normalized * maxSpeed; } Ray ray = new Ray(foot.transform.position, transform.up * -1); RaycastHit hit; Debug.DrawRay(ray.origin, ray.direction * 0.2f); if (ground) { if (GroundSlope() == 0) { Vector3 nor = characterVelocity; nor.y = 0; timer += Time.deltaTime * 5; characterVelocityMomentum = (nor.normalized * (1 - timer)) * Time.deltaTime * friction; characterVelocityY = 0; if (nor.magnitude <= 1) { playereState = PlayereState.Squat; } } //何かしらのオブジェクトにHitした場合 else if (Physics.Raycast(ray, out hit, 0.2f, layer)) { characterVelocityMomentum = hit.normal * 0.5f; //characterVelocityMomentum.y = 0; } if (Input.GetKeyDown(KeyCode.Space)) { characterVelocityY = 0; playereState = PlayereState.Default; Jump(jumpForce); wallRanIntervalFlag = false; StartCoroutine(WallRunInterval()); } } else { playereState = PlayereState.Default; //characterVelocityY = 0; } //重力を作成 float gravityDownForce = gravity * -1; //重力を加える characterVelocityY += gravityDownForce * Time.deltaTime; if (Physics.Raycast(ray, out hit, 0.2f, layer) && wallRanIntervalFlag) { controller.Move(hit.point - transform.position); ground = true; } // キャラクターのうごきに慣性を追加させる characterVelocity += characterVelocityMomentum; // 重力を適応 characterVelocity.y = characterVelocityY; // 移動を適応 controller.Move(characterVelocity * Time.deltaTime); }
/// <summary> /// しゃがみの移動処理 /// </summary> private void SquatMovemnet() { //カメラの向いている方向にプレイヤーを向ける playerAngle = cam.transform.eulerAngles; //プレイヤーが上下に回転しないようにxを固定 playerAngle.x = 0; //自身に適応 transform.eulerAngles = playerAngle; moveX = Input.GetAxisRaw("Horizontal"); moveZ = Input.GetAxisRaw("Vertical"); if (!ctrlKey && !CeilingCheck()) { playereState = PlayereState.Default; return; } //地面感知 if (controller.isGrounded) { //加速度を1にする addSpeed = 1; //カメラの向いている方向に歩く characterVelocity = transform.right * moveX + transform.forward * moveZ; characterVelocity = characterVelocity.normalized * walkSpeed * 0.5f; //重力を0に characterVelocityY = 0f; //ジャンプ if (Input.GetKeyDown(KeyCode.Space)) { gravity = 60; Jump(jumpForce); } //地面にいる間は慣性を受けない characterVelocityMomentum = Vector3.zero; } //地面から離れたら if (!controller.isGrounded) { //左右に壁があるかチェック WallCheck(); //空中にいる間に動ける方向を作成 characterVelocityMomentum = ((transform.right * moveX + transform.forward * moveZ) * (airSpeed * 0.5f) * Time.deltaTime) * addSpeed; if (Input.GetKeyDown(KeyCode.Space) && airJumpFlag) { characterVelocityMomentum.y = 0; Vector3 mag = characterVelocity; mag.y = 0; characterVelocity = characterVelocityMomentum.normalized * mag.magnitude; Jump(jumpForce); airJumpFlag = false; } } //重力を作成 float gravityDownForce = gravity * -1; //重力を加える characterVelocityY += gravityDownForce * Time.deltaTime; // キャラクターのうごきに慣性を追加させる characterVelocity += characterVelocityMomentum; if (maxSpeed <= (Mathf.Abs(characterVelocity.x) + Mathf.Abs(characterVelocity.z))) { characterVelocity.y = 0; characterVelocity = characterVelocity.normalized * maxSpeed; } // 重力を適応 characterVelocity.y = characterVelocityY; // 移動を適応 controller.Move(characterVelocity * Time.deltaTime); }
/// <summary> /// 壁走り /// </summary> private void WallRunMovemnet() { Vector3 test; test = characterVelocity; test.y = 0; Vector3 direction; int dir; int keyDir = 0; if (leftKeyFlag) { keyDir = 1; } else if (rightKeyFlag) { keyDir = 1; } switch (wallRunState) { default: case WallRunState.Right: direction = transform.right; dir = -1; break; case WallRunState.Left: direction = transform.right * -1; dir = 1; break; } if (wallRanIntervalFlag) { Ray ray = new Ray(transform.position, direction); RaycastHit hit; Debug.DrawRay(ray.origin, ray.direction * wallCheckDistance * keyDir); Ray forwardRay = new Ray(transform.position, transform.forward); RaycastHit forwardRayhit; if (Physics.Raycast(forwardRay, out forwardRayhit, wallCheckDistance)) { test.x = 0; test.z = 0; } //自身から左右に壁がないかチェック if (Physics.Raycast(ray, out hit, wallCheckDistance * keyDir, layer)) { airJumpFlag = true; transform.right = hit.normal * dir; characterVelocityMomentum = Vector3.zero; characterVelocity = transform.forward * test.magnitude; characterVelocityY = 0; characterVelocity += hit.normal * -1; controller.Move(characterVelocity * Time.deltaTime); //壁ジャンプ if (Input.GetKeyDown(KeyCode.Space)) { Vector3 vec = characterVelocity; vec.y = 0; AddForce((vec.normalized * -1) * wallJumpForce); AddForce(hit.normal * wallJumpForce); Jump(jumpForce); playereState = PlayereState.Default; wallRanIntervalFlag = false; StartCoroutine(WallRunInterval()); } //カメラのアングルを取得 var axis = Vector3.Cross(cam.transform.right, hit.normal); camAngle = Vector3.Angle(cam.transform.right, hit.normal) * (axis.x < 0 ? -1 : 1); //自身のアングルを取得 var testaxis = Vector3.Cross(transform.right, hit.normal); wallAngle = Vector3.Angle(transform.right, hit.normal) * (testaxis.x < 0 ? -1 : 1); //カメラの角度が正面から一定角度を超えた場合 if (Mathf.Abs(Mathf.Abs(camAngle) - Mathf.Abs(wallAngle)) >= breakAngle) { //ウォールランモードを解除 playereState = PlayereState.Default; //ウォールランフラグをオフ wallRanIntervalFlag = false; //一定時間ウォールランモードにしない StartCoroutine(WallRunInterval()); } } else { //フラグがオフならデフォルトモードに戻る playereState = PlayereState.Default; } } }
/// <summary> /// 移動の処理 /// </summary> private void Movemnet() { //カメラの向いている方向にプレイヤーを向ける playerAngle = cam.transform.eulerAngles; //プレイヤーが上下に回転しないようにxを固定 playerAngle.x = 0; playerAngle.z = 0; //自身に適応 transform.eulerAngles = playerAngle; moveX = Input.GetAxisRaw("Horizontal"); moveZ = Input.GetAxisRaw("Vertical"); Vector3 slidingCheck = characterVelocity; slidingCheck.y = 0; //スライディング状態 if (ctrlKey && ground && slidingCheck.magnitude > 0) { playereState = PlayereState.Sliding; return; } //しゃがみ状態 else if (ctrlKey && characterVelocity.x == 0 && characterVelocity.z == 0) { playereState = PlayereState.Squat; return; } //地面感知 if (controller.isGrounded) { //カメラの向いている方向に歩く characterVelocity = transform.right * moveX + transform.forward * moveZ; //重力を0に characterVelocityY = 0f; //正規化したほうにスピード分加速 characterVelocity = characterVelocity.normalized * walkSpeed; //ジャンプ if (Input.GetKeyDown(KeyCode.Space)) { characterVelocityY = 0; Jump(jumpForce); wallRanIntervalFlag = false; StartCoroutine(WallRunInterval()); } //地面にいる間は慣性を受けない characterVelocityMomentum = Vector3.zero; } //地面から離れたら if (!controller.isGrounded) { //左右に壁があるかチェック WallCheck(); //空中にいる間に動ける方向を作成 characterVelocityMomentum = ((transform.right * moveX + transform.forward * moveZ) * airSpeed * Time.deltaTime) * addSpeed; if (Input.GetKeyDown(KeyCode.Space) && airJumpFlag) { characterVelocityMomentum.y = 0; Vector3 mag = characterVelocity; mag.y = 0; characterVelocity = characterVelocityMomentum.normalized * mag.magnitude; Jump(jumpForce); airJumpFlag = false; } } //重力を作成 float gravityDownForce = gravity * -1; //重力を加える characterVelocityY += gravityDownForce * Time.deltaTime; //キャラクターのうごきに慣性を追加させる characterVelocity += characterVelocityMomentum; if (maxSpeed <= (Mathf.Abs(characterVelocity.x) + Mathf.Abs(characterVelocity.z))) { characterVelocity.y = 0; characterVelocity = characterVelocity.normalized * maxSpeed; } Ray ray = new Ray(foot.transform.position, transform.up * -1); RaycastHit hit; Debug.DrawRay(ray.origin, ray.direction * 0.2f); if (Physics.Raycast(ray, out hit, 1f, layer) && wallRanIntervalFlag) { controller.Move(hit.point - transform.position); ground = true; Debug.Log("地面"); } //重力を適応 characterVelocity.y = characterVelocityY; //移動を適応 controller.Move(characterVelocity * Time.deltaTime); }