Rigidbody と Cinemachine を使用して、3D の第三者キャラクターの動きを実装しようとしています。キャラクターは、壁だけでなく、地面と天井も歩くことができる必要があります (正の X 軸に面している場合、左右の壁のみ)。
Rigidbody に一定の力を追加/変更して、重力の方向を変更し、キャラクターを x で上下に、z で左右に回転させることで、これを実現しました。
CinemachineBrain には World Up Override が Characters トランスフォームに設定されており、CinemchineFreeLook Binding Mode は「Simple Follow with World Up」に設定されています。これにより、カメラ/シネマシーンの軌道をキャラクターの回転に合わせて回転させることができます。
今のところ、PlayerMovement スクリプトに 4 つのメソッドを実装しました。重力方向 (上、下、左、右) ごとに 1 つずつ、回転と重力を変更するだけで基本的に同じことを行います。
MoveUp() および MoveDown() メソッドは期待どおりに機能します。
しかし、MoveLeft() および MoveRight() メソッドを機能させることができません。
問題は、カメラの角度を追加するときにキャラクターが 360 度の回転 (ここでは x 軸上) を行うことができず、正または負の x に面している間は 180 度の回転しかできないことです (y に目に見えない壁があるように感じます)。軸。
私はどうにか Cinemachine / the + Camera.main.transform.eulerAngles.x; がここで問題になると予想していますが、それが正確に何であるかはわかりません。
これは、Unity / ゲーム開発全般における私の最初のプロジェクトです。必要な情報をすべて提供できれば幸いです。
回答ありがとうございます。
そして、ここに私のスクリプトがあります:
(私はこのチュートリアルに従って基本的な動きを実装し、Rigidbody で動作するように変更しました: https://youtu.be/4HpC--2iowE )
public class PlayerMovement : MonoBehaviour
{
public float walkSpeed = 5f;
public float runSpeed = 15f;
public float idleSpeed = 0f;
public string gravityDiretion = "down";
public ConstantForce gravity = new ConstantForce();
private float actualSpeed;
public float turnSmoothing = 0.1f;
float turnSmoothVelocity;
private Rigidbody character;
private void Start()
{
character = GetComponent<Rigidbody>();
gravity = gameObject.AddComponent<ConstantForce>();
}
private void FixedUpdate()
{
Move();
}
private void Move()
{
if (gravityDiretion.Equals("up"))
{
MoveUp();
}
else if (gravityDiretion.Equals("down"))
{
MoveDown();
}
else if (gravityDiretion.Equals("right"))
{
MoveRight();
}
else if (gravityDiretion.Equals("left"))
{
MoveLeft();
}
}
private void MoveUp()
{
gravity.force = new Vector3(0.0f, 9.81f, 0.0f);
if (Input.GetKey(KeyCode.LeftShift))
{
actualSpeed = runSpeed;
}
else
{
actualSpeed = walkSpeed;
}
float horizonal = Input.GetAxisRaw("Horizontal"); // 1 = left -1 righ
float vertical = Input.GetAxisRaw("Vertical"); // 1 = forward -1 bakwadrd
Debug.Log("Axis Vertical = " + vertical);
Debug.Log("Axis Horizontal = " + horizonal);
Vector3 direction = new Vector3(horizonal, 0f, -vertical).normalized; //normalize to not moving faster when pressing two keys to walk diagonal
if (direction.magnitude >= 0.1f) // If lenght of the vecctor is > 0
{
//Character Rotation
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + Camera.main.transform.eulerAngles.y; // The angle the character should turn to face forward
Debug.Log("targetAngle = " + targetAngle);
float smoothedAngle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, - turnSmoothing);
Debug.Log("smoothedAngle = " + smoothedAngle);
character.MoveRotation(Quaternion.Euler(180f, smoothedAngle, 0f));
//Character Movement
Vector3 moveDir = Quaternion.Euler(180f, targetAngle, 0f) * Vector3.forward;
Debug.Log("Movedir = " + moveDir.ToString());
character.MovePosition(transform.position + moveDir.normalized * actualSpeed * Time.fixedDeltaTime);
}
else
{
actualSpeed = 0f;
}
}
private void MoveDown()
{
//Gravity
gravity.force = new Vector3(0.0f, -9.81f, 0.0f);
if (Input.GetKey(KeyCode.LeftShift))
{
actualSpeed = runSpeed;
}
else
{
actualSpeed = walkSpeed;
}
float horizonal = Input.GetAxisRaw("Horizontal"); // 1 = left -1 righ
float vertical = Input.GetAxisRaw("Vertical"); // 1 = forward -1 bakward
Debug.Log("Axis Vertical = " + vertical);
Debug.Log("Axis Horizontal = " + horizonal);
Vector3 direction = new Vector3(horizonal, 0f, vertical).normalized;
if (direction.magnitude >= 0.1f)
{
//Character Rotation
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + Camera.main.transform.eulerAngles.y;
float smoothedAngle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothing);
character.MoveRotation(Quaternion.Euler(0f, smoothedAngle, 0f));
//Character Movement
Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
Debug.Log("Movedir = " + moveDir.ToString());
character.MovePosition(transform.position + moveDir.normalized * actualSpeed * Time.fixedDeltaTime);
}
else
{
actualSpeed = 0f;
}
}
private void MoveRight()
{
//Gravity
gravity.force = new Vector3(9.81f, 0.0f, 0.0f);
if (Input.GetKey(KeyCode.LeftShift))
{
actualSpeed = runSpeed;
}
else
{
actualSpeed = walkSpeed;
}
float horizonal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Debug.Log("Axis Vertical = " + vertical);
Debug.Log("Axis Horizontal = " + horizonal);
Vector3 direction = new Vector3( 0f, horizonal, vertical).normalized;
if (direction.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(direction.y, direction.z) * Mathf.Rad2Deg + Camera.main.transform.eulerAngles.x;
Debug.Log("targetAngle = " + targetAngle);
float smoothedAngle = Mathf.SmoothDampAngle(transform.eulerAngles.x, targetAngle, ref turnSmoothVelocity, turnSmoothing);
Debug.Log("smoothedAngle = " + smoothedAngle);
character.MoveRotation( Quaternion.Euler(targetAngle, 0f , 90f));
//Character Movement
Vector3 moveDir = Quaternion.Euler(targetAngle, 0.0f, 90f) * Vector3.forward;
Debug.Log("Movedir = " + moveDir.ToString());
character.MovePosition(transform.position + moveDir.normalized * actualSpeed * Time.fixedDeltaTime);
}
else
{
actualSpeed = 0f;
}
}
private void MoveLeft()
{
//Gravity
gravity.force = new Vector3(-9.81f, 0.0f, 0.0f);
if (Input.GetKey(KeyCode.LeftShift))
{
actualSpeed = runSpeed;
}
else
{
actualSpeed = walkSpeed;
}
float horizonal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Debug.Log("Axis Vertical = " + vertical);
Debug.Log("Axis Horizontal = " + horizonal);
Vector3 direction = new Vector3(0f, horizonal, vertical).normalized;
if (direction.magnitude >= 0.1f)
{
//Character Rotation
float targetAngle = Mathf.Atan2(direction.z, direction.y) * Mathf.Rad2Deg + Camera.main.transform.eulerAngles.x;
float smoothedAngle = Mathf.SmoothDampAngle(transform.eulerAngles.x, targetAngle, ref turnSmoothVelocity, turnSmoothing);
character.MoveRotation(Quaternion.Euler(smoothedAngle, 0f, -90f));
//Character Movement
Vector3 moveDir = Quaternion.Euler(targetAngle, 0.0f, -90f) * Vector3.right;
Debug.Log("Movedir = " + moveDir.ToString());
character.MovePosition(transform.position + moveDir.normalized * actualSpeed * Time.fixedDeltaTime);
}
else
{
actualSpeed = 0f;
}
}
public void ChangeDravityDirection(string newGravityDirection)
{
gravityDiretion = newGravityDirection;
}