前提・実現したいこと
一人称視点のホラーゲームを作っています。
カメラに「Lerp減衰」「FoV変動」「手振れ」の機能を、スクリプトかChinemachineどちらかで制御する方法が知りたいです。
動かすキャラはStandard AssetのFPSControllerを使っています。
(できればキャラクターはFPSControllerを使い続けたいです)
発生している問題
問題1:
「Lerp減衰」「FoV変動」「手振れ」のスクリプトをアタッチして制御しようとしたのですが、「手振れ」のみ機能せず、sceneを切り替えると画面がガクガクに揺れマウス操作が効かなくなります。
問題2:
公式アセットのCinemachineを使うと手振れなどのカメラの機能は正しく働くようになりました。しかし、ゆっくりマウスを動かせば視点方向に前進するが早く振り返ったりすると前進ボタンを押しても後退してしまいます。
CinemachineとFPSControllerについているカメラとのマウス加速度の差?に違いがあるように感じているのですが解決方法が分かりません。
※両方ともエラーメッセージは一切ありません
試したこと
・新しく作ったカメラに3つの機能のスクリプトをつけると手振れが機能するようになりました。
しかし、移動とマウス操作のスクリプトを追加すると移動はできてもマウス操作が効きませんでした。
・スクリプトのUpdate()をFixedUpdate()に変更しました。
初動に画面が揺れることはなくなったが、移動して停止すると数秒間カメラが前後にガクガク揺れるようになった。
「Lerp減衰」「FoV変動」「手振れ」のスクリプト
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class CameraController3D : MonoBehaviour 6{ 7 public GameObject TargetObject; 8 public float Height = 1.5f; 9 public float Distance = 5.0f; 10 public float HeightAngle = 10.0f; 11 public float RotAngle = 0.0f; 12 public float RotAngleAttenRate = 5.0f; 13 public float AngleAttenRate = 40.0f; 14 15 public bool EnableAtten = true; 16 public float AttenRate = 3.0f; 17 18 public bool EnableNoise = true; 19 public float NoiseSpeed = 0.5f; 20 public float MoveNoiseSpeed = 1.5f; 21 public float NoiseCoeff = 1.3f; 22 public float MoveNoiseCoeff = 2.5f; 23 24 public bool EnableFieldOfViewAtten = true; 25 public float FieldOfView = 50.0f; 26 public float MoveFieldOfView = 60.0f; 27 28 public float ForwardDistance = 2.0f; 29 30 private Camera cam; 31 private Vector3 addForward; 32 private Vector3 deltaTarget; 33 private Vector3 nowPos; 34 private float nowfov; 35 36 private float nowRotAngle; 37 private float nowHeightAngle; 38 39 private Vector3 prevTargetPos; 40 41 // Use this for initialization 42 void Start() 43 { 44 cam = GetComponent<Camera>(); 45 nowfov = FieldOfView; 46 nowPos = TargetObject.transform.position; 47 } 48 49 // Update is called once per frame 50 void FixedUpdate() 51 { 52 RotAngle -= Input.GetAxis("Mouse X") * 5.0f; 53 HeightAngle += Input.GetAxis("Mouse Y") * 5.0f; 54 HeightAngle = Mathf.Clamp(HeightAngle, 0.0f, 80.0f); 55 56 var delta = TargetObject.transform.position - deltaTarget; 57 deltaTarget = TargetObject.transform.position; 58 59 // 減衰 60 if (EnableAtten) 61 { 62 var deltaPos = TargetObject.transform.position - prevTargetPos; 63 prevTargetPos = TargetObject.transform.position; 64 deltaPos *= ForwardDistance; 65 66 addForward += deltaPos * Time.deltaTime * 20.0f; 67 addForward = Vector3.Lerp(addForward, Vector3.zero, Time.deltaTime * AttenRate); 68 69 nowPos = Vector3.Lerp(nowPos, TargetObject.transform.position + Vector3.up * Height + addForward, Mathf.Clamp(Time.deltaTime * AttenRate, 0.0f, 1.0f)); 70 } 71 else nowPos = TargetObject.transform.position + Vector3.up * Height; 72 73 // 手ブレ 74 bool move = Mathf.Abs(delta.x) > 0.0f; 75 var noise = new Vector3(); 76 if (EnableNoise) 77 { 78 var ns = (move ? MoveNoiseSpeed : NoiseSpeed); 79 var nc = (move ? MoveNoiseCoeff : NoiseCoeff); 80 81 var t = Time.time * ns; 82 83 var nx = Mathf.PerlinNoise(t, t) * nc; 84 var ny = Mathf.PerlinNoise(t + 10.0f, t + 10.0f) * nc; 85 var nz = Mathf.PerlinNoise(t + 20.0f, t + 20.0f) * nc * 0.5f; 86 noise = new Vector3(nx, ny, nz); 87 } 88 89 // FoV 90 if (EnableFieldOfViewAtten) nowfov = Mathf.Lerp(nowfov, move ? MoveFieldOfView : FieldOfView, Time.deltaTime); 91 else nowfov = FieldOfView; 92 cam.fieldOfView = nowfov; 93 94 // カメラ位置 95 if (EnableAtten) nowRotAngle = Mathf.Lerp(nowRotAngle, RotAngle, Time.deltaTime * RotAngleAttenRate); 96 else nowRotAngle = RotAngle; 97 98 if (EnableAtten) nowHeightAngle = Mathf.Lerp(nowHeightAngle, HeightAngle, Time.deltaTime * RotAngleAttenRate); 99 else nowHeightAngle = HeightAngle; 100 101 var deg = Mathf.PI / 180.0f; 102 var cx = Mathf.Sin(nowRotAngle * deg) * Mathf.Cos(nowHeightAngle * deg) * Distance; 103 var cz = -Mathf.Cos(nowRotAngle * deg) * Mathf.Cos(nowHeightAngle * deg) * Distance; 104 var cy = Mathf.Sin(nowHeightAngle * deg) * Distance; 105 transform.position = nowPos + new Vector3(cx, cy, cz); 106 107 // カメラ向き 108 var rot = Quaternion.LookRotation((nowPos - transform.position).normalized) * Quaternion.Euler(noise); 109 if (EnableAtten) transform.rotation = Quaternion.Slerp(transform.rotation, rot, Time.deltaTime * AngleAttenRate); 110 else transform.rotation = rot; 111 } 112} 113
補足情報(FW/ツールのバージョンなど)
Unityバージョン:2019.4.9f1
参考にしたサイト
https://qiita.com/yoship1639/items/9bf6f8ad080b3c496b12
http://bboydaisuke.wp.xdomain.jp/2020/06/05/post-313/
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/10/05 05:28