実現したいこと
Unityの3Dのアクションゲームなのですが、プレイヤーが、WarpPoint1というタグ(以下W1)がついたオブジェクトに触れると、WarpPoint2(以下W2)のタグがついたオブジェクトの座標のところにワープするという処理です。具体的には、W1のオブジェクトに触れたら1秒間動けなくなり、W2にワープ。ワープ後も1秒間は動けなくなる。そして、ワープ後は10秒後動けなくなるという処理をしたいです。カメラの回転も考慮して、しっかり正面に向くようにしたいです。
発生している問題・分からないこと
W1からW2までワープするが、一瞬でなぜかW1にもどってきてしまいます。また、TPSカメラの位置をプレイヤーの背後にし、向きも、プレイヤーと同じ向きになるようにしたいです。ソースコードの一番下に、ワープ処理があります。
該当のソースコード
Unity
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.InputSystem; 5 6//キャラクターコンポーネントが追加されていない場合追加。また依存関係を表す。 7[RequireComponent(typeof(CharacterController))] 8public class Teleporter : MonoBehaviour 9{ 10 //Header(名前)でインスペクターに表示させる変数の意味を載せれる。 11 [Header("移動の速さ"), SerializeField] 12 private float _speed = 3; 13 14 [Header("しゃがみ時の移動速度調整(0以上1以下で値が大きいほど速い"), SerializeField, Range(0.01f, 1f)] 15 private float _crouchingspeed = 0.5f; 16 17 [Header("ジャンプする瞬間の速さ"), SerializeField] 18 private float _jumpSpeed = 7; 19 20 [Header("重力加速度"), SerializeField] 21 private float _gravity = 15; 22 23 [Header("落下時の速さ制限(Infinityで無制限)"), SerializeField] 24 private float _fallSpeed = 10; 25 26 [Header("落下の初速"), SerializeField] 27 private float _initFallSpeed = 2; 28 29 [Header("カメラ"), SerializeField] 30 private Camera _tagetcamera; 31 32 [Header("ワープのインターバル"), SerializeField] 33 private float _Warpinterval = 10f; 34 35 [Header("ワープする前隙と後隙"), SerializeField] 36 private float _freezeTime = 1.0f; 37 38 //ワープ中かどうか 39 private bool isWarp = false; 40 //ワープのインターバル 41 private bool isWarpinterval = false; 42 43 //ワープする際の前隙と後隙 44 45 46 47 //トランスフォームと、キャラクターコントローラーの変数を宣言 48 private Transform _transform; 49 private CharacterController _characterController; 50 51 //キャラクターのサイズ 52 private Vector3 originalScale; 53 //子オブジェクトのサイズ 54 private Transform GunScale; 55 //しゃがみ状態かどうか 56 private bool isCrouching = false; 57 58 private Vector2 _inputMove; 59 private float _verticalVelocity; 60 private float _turnVelocity; 61 private bool _isGroundedPrev; 62 /// <summary> 63 /// 移動アクション(PlyerInput側から呼ばれる) 64 /// </summary> 65 public void OnMove(InputAction.CallbackContext context) 66 { 67 //ワープ中は移動しない 68 if (isWarp) return; 69 // 入力値を保存しておく 70 _inputMove = context.ReadValue<Vector2>(); 71 } 72 //ジャンプアクション 73 public void OnJump(InputAction.CallbackContext context) 74 { 75 76 //ボタンが押されていない時、かつ地面に接触していない時、かつしゃがんでいるとき、またワープ中は処理を終了。 77 if (!context.performed || !_characterController.isGrounded || isCrouching || isWarp) return; 78 Debug.Log("ジャンプコマンド"); 79 //鉛直上向きに速度を与える。 80 _verticalVelocity = _jumpSpeed; 81 82 } 83 //しゃがみアクション 84 public void OnCrouching(InputAction.CallbackContext context) 85 { 86 if (isWarp) return; 87 88 if (context.performed) 89 { 90 Crouching(); 91 Debug.Log("しゃがみコマンド"); 92 } 93 } 94 95 //Awakeはゲーム再生時最も早く処理される 96 private void Awake() 97 { 98 //何度も呼び出すコンポーネントを変数にキャッシュしておく。 99 _transform = transform; 100 _characterController = GetComponent<CharacterController>(); 101 102 //メインカメラを取得 103 if (_tagetcamera == null) 104 _tagetcamera = Camera.main; 105 106 //サイズ 107 originalScale = transform.localScale; 108 GunScale = transform.Find("M4A1_PBR"); 109 } 110 111 private void Update() 112 { 113 //地面に接触した判定をするプロパティ。 114 var isGrounded = _characterController.isGrounded; 115 //isGroundedに接触判定を格納した後に、isGroundedPrevにisGroundedの値を格納しているため、 116 //isGroundedPrevには、前のフレームの接触判定が格納されている。 117 if (isGrounded && !_isGroundedPrev) 118 { 119 //地面に接触した瞬間に落下の初速を指定 120 _verticalVelocity = -_initFallSpeed; 121 // 122 Debug.Log("地面に触れている"); 123 } 124 else if (!isGrounded) 125 { 126 //空中にいる時は重力加速度を下向きに与えて落下させる 127 _verticalVelocity -= _gravity * Time.deltaTime; 128 129 //落下する速さ以上にならないように補正 130 if (_verticalVelocity < -_fallSpeed) 131 _verticalVelocity = -_fallSpeed; 132 } 133 134 _isGroundedPrev = isGrounded; 135 136 //カメラの角度を取得 137 var cameraAngleY = _tagetcamera.transform.eulerAngles.y; 138 139 140 var moveVelocity = new Vector3( 141 _inputMove.x * _speed, 142 _verticalVelocity, 143 _inputMove.y * _speed); 144 145 146 //カメラの角度分移動量を回転 147 moveVelocity = Quaternion.Euler(0, cameraAngleY, 0) * moveVelocity; 148 149 // 現在フレームの移動量を移動速度から計算 150 var moveDelta = moveVelocity * Time.deltaTime; 151 152 // CharacterControllerに移動量を指定し、オブジェクトを動かす 153 _characterController.Move(moveDelta); 154 155 156 //移動がゼロではない=移動している時に処理される 157 if (_inputMove != Vector2.zero) 158 { 159 //移動入力がある場合は振り向き動作も行う。 160 //操作入力からy軸周りの目標角度[deg]を計算 161 var targetAngleY = -Mathf.Atan2(_inputMove.y, _inputMove.x) 162 * Mathf.Rad2Deg + 90; 163 164 //カメラの角度分だけ振り向く角度を補正 165 targetAngleY += cameraAngleY; 166 167 //イージングしながら次の回転角度[deg]を計算 168 var angleY = Mathf.SmoothDampAngle( 169 _transform.eulerAngles.y, 170 targetAngleY, 171 ref _turnVelocity, 172 0.1f); 173 174 // オブジェクトの回転を更新 175 _transform.rotation = Quaternion.Euler(0, angleY, 0); 176 177 } 178 } 179 void Crouching() 180 { 181 //地面に接触していないとしゃがめない 182 if (!_characterController.isGrounded) 183 return; 184 185 if (isCrouching) 186 { 187 Debug.Log("しゃがみ"); 188 // しゃがみ状態を解除し、親オブジェクトのサイズを元に戻す 189 transform.localScale = originalScale; 190 //銃のおおきさが変わらないように 191 GunScale.localScale = new Vector3(1, 1, 1); 192 //スピードを戻す 193 _speed /= _crouchingspeed; 194 // キャラクターコントロールを元にもどす 195 _characterController.height = 1.5f; 196 _characterController.center = new Vector3(0, 0.8f, 0); 197 198 } 199 else 200 { 201 // しゃがみ状態にし、親オブジェクトのサイズを半分にする 202 transform.localScale = new Vector3( 203 originalScale.x, 204 originalScale.y * 0.5f, 205 originalScale.z 206 ); 207 //銃のおおきさが変わらないように 208 GunScale.localScale = new Vector3(1, 2, 1); 209 210 // キャラクターコントロールの調整 211 _characterController.height = 1.5f; 212 _characterController.center = new Vector3(0, 0.89f, 0); 213 214 //スピードを遅くする 215 _speed *= _crouchingspeed; 216 } 217 // フラグを切り替える 218 isCrouching = !isCrouching; 219 } 220 221 //WarpPoint1というタグがついたオブジェクトに触れたらコルーチン開始 222 private void OnControllerColliderHit(ControllerColliderHit hit) 223 { 224 //インターバル中はワープできない。 225 if (isWarpinterval) return; 226 //ワープポイント1から2へ 227 if (!isWarp && hit.collider.CompareTag("WarpPoint1")) 228 { 229 //ワープ中は移動しない 230 _inputMove = Vector2.zero; 231 Debug.Log("ワープポイント1に触った"); 232 StartCoroutine(WarpAndFreeze()); 233 } 234 235 } 236 //ワープ処理 237 private IEnumerator WarpAndFreeze() 238 { 239 isWarp = true; 240 241 // プレイヤーを動けなくする処理 242 Debug.Log("Player frozen for 1 second"); 243 yield return new WaitForSeconds(_freezeTime); 244 245 // プレイヤーをWarpPoint2に瞬間移動させる 246 GameObject warpPoint2 = GameObject.FindGameObjectWithTag("WarpPoint2"); 247 if (warpPoint2 != null) 248 { 249 transform.position = warpPoint2.transform.position; 250 transform.rotation = warpPoint2.transform.rotation; 251 252 // 移動後も1秒間動けない 253 yield return new WaitForSeconds(_freezeTime); 254 } 255 256 isWarp = false; 257 //ワープインターバル 258 isWarpinterval = true; 259 yield return new WaitForSeconds(_Warpinterval); 260 isWarpinterval = false; 261 } 262} 263
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
チャットGPTにワープ処理を書かせたのですがおかしくなっています。チャットGPTを用いて再び修正しようとしましたが、処理が重く返答してくれませんでした。
補足
特になし

回答1件
あなたの回答
tips
プレビュー