Unity/3d/キャラクタ移動/前後回転 CharacterController
提供: 初心者エンジニアの簡易メモ
準備
- unity標準のCharacterControllerを使うのでAddComponentしておく。
- オブジェクト内にカメラを設置しておく。
前後回転サンプル
using System.Collections.Generic; using UnityEngine; public class CharacterControl : MonoBehaviour { [SerializeField] private float m_moveSpeed = 2; [SerializeField] private float m_turnSpeed = 200; [SerializeField] private float m_jumpForce = 4; [SerializeField] private Animator m_animator = null; [SerializeField] private Rigidbody m_rigidBody = null; private readonly float m_runScale = 3f; private Vector3 m_currentDirection = Vector3.zero; private bool m_jumpInput = false; private bool m_isGrounded; private List<Collider> m_collisions = new List<Collider>(); private void Awake() { if (!m_animator) { gameObject.GetComponent<Animator>(); } if (!m_rigidBody) { gameObject.GetComponent<Animator>(); } } private void OnCollisionEnter(Collision collision) { ContactPoint[] contactPoints = collision.contacts; for (int i = 0; i < contactPoints.Length; i++) { if (Vector3.Dot(contactPoints[i].normal, Vector3.up) > 0.5f) { if (!m_collisions.Contains(collision.collider)) { m_collisions.Add(collision.collider); } m_isGrounded = true; } } } private void OnCollisionStay(Collision collision) { ContactPoint[] contactPoints = collision.contacts; bool validSurfaceNormal = false; for (int i = 0; i < contactPoints.Length; i++) { if (Vector3.Dot(contactPoints[i].normal, Vector3.up) > 0.5f) { validSurfaceNormal = true; break; } } if (validSurfaceNormal) { m_isGrounded = true; if (!m_collisions.Contains(collision.collider)) { m_collisions.Add(collision.collider); } } else { if (m_collisions.Contains(collision.collider)) { m_collisions.Remove(collision.collider); } if (m_collisions.Count == 0) { m_isGrounded = false; } } } private void OnCollisionExit(Collision collision) { if (m_collisions.Contains(collision.collider)) { m_collisions.Remove(collision.collider); } if (m_collisions.Count == 0) { m_isGrounded = false; } } private void Update() { if (!m_jumpInput && Input.GetKey(KeyCode.Space)) { m_jumpInput = true; } } private void FixedUpdate() { if (m_animator != null) { m_animator.SetBool("Grounded", m_isGrounded); } DirectUpdate(); m_jumpInput = false; } private void DirectUpdate() { float vertical = Input.GetAxis("Vertical"); float horizontal = Input.GetAxis("Horizontal"); float currentSpeed = (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) ? m_moveSpeed * m_runScale * 2 : m_moveSpeed * 2; Vector3 forwardsMovement = transform.forward * vertical; GetComponent<CharacterController>().Move(Time.deltaTime * currentSpeed * forwardsMovement); float rotete = m_turnSpeed / 100 * horizontal; if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) { rotete = m_turnSpeed / 100 * 2 * horizontal; } GetComponent<CharacterController>().transform.Rotate(new Vector3(0f, rotete, 0f)); if (m_animator != null) { m_animator.SetFloat("MoveSpeed", 1); } } }