// Fixed update is called in sync with physicsprivatevoid FixedUpdate()
{
// read inputsfloat h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
bool crouch = Input.GetButton("Fire3");
// calculate move direction to pass to characterif (m_Cam != null)
{
// calculate camera relative direction to move:
m_CamForward = Vector3.Scale(m_Cam.forward, new Vector3(1, 0, 1)).normalized;
m_Move = v*m_CamForward + h*m_Cam.right;
}
else
{
// we use world-relative directions in the case of no main camera
m_Move = v*Vector3.forward + h*Vector3.right;
}
#if !MOBILE_INPUT// walk speed multiplierif (Input.GetKey(KeyCode.LeftShift)) m_Move *= 0.5f;
#endif// pass all parameters to the character control script
m_Character.Move(m_Move, crouch, m_Jump);
m_Jump = false;
}
publicvoid Move(Vector3 move, bool crouch, bool jump)
{
// convert the world relative moveInput vector into a local-relative// turn amount and forward amount required to head in the desired// direction.if (move.magnitude > 1f) move.Normalize();
move = transform.InverseTransformDirection(move);
CheckGroundStatus();
move = Vector3.ProjectOnPlane(move, m_GroundNormal);
m_TurnAmount = Mathf.Atan2(move.x, move.z);
m_ForwardAmount = move.z;
ApplyExtraTurnRotation();
// control and velocity handling is different when grounded and airborne:if (m_IsGrounded)
{
HandleGroundedMovement(crouch, jump);
}
else
{
HandleAirborneMovement();
}
ScaleCapsuleForCrouching(crouch);
PreventStandingInLowHeadroom();
// send input and other state parameters to the animator
UpdateAnimator(move);
}
void UpdateAnimator(Vector3 move)
{
// update the animator parameters
m_Animator.SetFloat("Forward", m_ForwardAmount, 0.1f, Time.deltaTime);
m_Animator.SetFloat("Turn", m_TurnAmount, 0.1f, Time.deltaTime);
m_Animator.SetBool("Crouch", m_Crouching);
m_Animator.SetBool("OnGround", m_IsGrounded);
if (!m_IsGrounded)
{
m_Animator.SetFloat("Jump", m_Rigidbody.velocity.y);
}
// calculate which leg is behind, so as to leave that leg trailing in the jump animation// (This code is reliant on the specific run cycle offset in our animations,// and assumes one leg passes the other at the normalized clip times of 0.0 and 0.5)float runCycle =
Mathf.Repeat(
m_Animator.GetCurrentAnimatorStateInfo(0).normalizedTime + m_RunCycleLegOffset, 1);
float jumpLeg = (runCycle < k_Half ? 1 : -1) * m_ForwardAmount;
if (m_IsGrounded)
{
m_Animator.SetFloat("JumpLeg", jumpLeg);
}
// the anim speed multiplier allows the overall speed of walking/running to be tweaked in the inspector,// which affects the movement speed because of the root motion.if (m_IsGrounded && move.magnitude > 0)
{
m_Animator.speed = m_AnimSpeedMultiplier;
}
else
{
// don't use that while airborne
m_Animator.speed = 1;
}
}
using System;
using UnityEngine;
namespace SimpleStar
{
publicclass FreeLookCam : MonoBehaviour
{
// This script is designed to be placed on the root object of a camera rig,// comprising 3 gameobjects, each parented to the next:// Camera Rig// Pivot// Camera
[SerializeField] private Transform m_Target; // The target object to follow
[SerializeField] privatefloat m_MoveSpeed = 1f; // How fast the rig will move to keep up with the target's position.
[Range(0f, 10f)] [SerializeField] privatefloat m_TurnSpeed = 1.5f; // How fast the rig will rotate from user input.
[SerializeField] privatefloat m_TurnSmoothing = 0.0f; // How much smoothing to apply to the turn input, to reduce mouse-turn jerkiness
[SerializeField] privatefloat m_TiltMax = 75f; // The maximum value of the x axis rotation of the pivot.
[SerializeField] privatefloat m_TiltMin = 45f; // The minimum value of the x axis rotation of the pivot.
[SerializeField] privatebool m_LockCursor = false; // Whether the cursor should be hidden and locked.
[SerializeField] privatebool m_VerticalAutoReturn = false; // set wether or not the vertical axis should auto return
[SerializeField] privatefloat TiltRate = 0.52f;
private Transform m_Cam; // the transform of the cameraprivate Transform m_Pivot; // the point at which the camera pivots aroundprivatefloat m_LookAngle; // The rig's y axis rotation.privatefloat m_TiltAngle; // The pivot's x axis rotation.private Vector3 m_PivotEulers;
private Quaternion m_PivotTargetRot;
private Quaternion m_TransformTargetRot;
private Vector3 m_CameraTargetPosition;
privatefloat m_CameraDefaultDistance;
void Awake()
{
m_Cam = GetComponentInChildren<Camera>().transform;
m_Pivot = m_Cam.parent;
// Lock or unlock the cursor.
Cursor.lockState = m_LockCursor ? CursorLockMode.Locked : CursorLockMode.None;
Cursor.visible = !m_LockCursor;
m_PivotEulers = m_Pivot.rotation.eulerAngles;
m_PivotTargetRot = m_Pivot.transform.localRotation;
m_TransformTargetRot = transform.localRotation;
m_CameraDefaultDistance = m_Cam.transform.localPosition.z;
}
protectedvoid Update()
{
FollowTarget(Time.deltaTime);
HandleRotationMovement();
if (m_LockCursor && Input.GetMouseButtonUp(0))
{
Cursor.lockState = m_LockCursor ? CursorLockMode.Locked : CursorLockMode.None;
Cursor.visible = !m_LockCursor;
}
}
privatevoid OnDisable()
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
void FollowTarget(float deltaTime)
{
if (m_Target == null) return;
// Move the rig towards target position.
transform.position = Vector3.Lerp(transform.position, m_Target.position, deltaTime*m_MoveSpeed);
}
privatevoid HandleRotationMovement()
{
if(Time.timeScale < float.Epsilon)
return;
// Read the user input
var x = Input.GetAxis("HorizontalTurn");
var y = Input.GetAxis("VerticalTurn");
// Adjust the look angle by an amount proportional to the turn speed and horizontal input.
m_LookAngle += x*m_TurnSpeed;
// Rotate the rig (the root object) around Y axis only:
m_TransformTargetRot = Quaternion.Euler(0f, m_LookAngle, 0f);
if (m_VerticalAutoReturn)
{
// For tilt input, we need to behave differently depending on whether we're using mouse or touch input:// on mobile, vertical input is directly mapped to tilt value, so it springs back automatically when the look input is released// we have to test whether above or below zero because we want to auto-return to zero even if min and max are not symmetrical.
m_TiltAngle = y > 0 ? Mathf.Lerp(0, -m_TiltMin, y) : Mathf.Lerp(0, m_TiltMax, -y);
}
else
{
// on platforms with a mouse, we adjust the current angle based on Y mouse input and turn speed
m_TiltAngle -= y*m_TurnSpeed;
// and make sure the new value is within the tilt range
m_TiltAngle = Mathf.Clamp(m_TiltAngle, -m_TiltMin, m_TiltMax);
}
// Tilt input around X is applied to the pivot (the child of this object)
m_PivotTargetRot = Quaternion.Euler(m_TiltAngle, m_PivotEulers.y , m_PivotEulers.z);
float cameraDistanceRate = (1.0f - (m_TiltAngle > 0 ? (TiltRate * m_TiltAngle / m_TiltMax) : TiltRate * (m_TiltAngle / -m_TiltMin)));
float cameraTargetDistance = cameraDistanceRate * m_CameraDefaultDistance;
if (m_TurnSmoothing > 0)
{
Vector3 cameraLocalPos = m_Cam.transform.localPosition;
cameraLocalPos.z = Mathf.Lerp(cameraLocalPos.z, cameraTargetDistance, m_TurnSmoothing);
m_Cam.transform.localPosition = cameraLocalPos;
m_Pivot.localRotation = Quaternion.Slerp(m_Pivot.localRotation, m_PivotTargetRot, m_TurnSmoothing * Time.deltaTime);
transform.localRotation = Quaternion.Slerp(transform.localRotation, m_TransformTargetRot, m_TurnSmoothing * Time.deltaTime);
}
else
{
Vector3 cameraLocalPos = m_Cam.transform.localPosition;
cameraLocalPos.z = cameraTargetDistance;
m_Cam.transform.localPosition = cameraLocalPos;
m_Pivot.localRotation = m_PivotTargetRot;
transform.localRotation = m_TransformTargetRot;
}
}
}
}
標準アセットのサンプル-シーンと同じく
Rig オブジェクトにこのスクリプトを割り当てますが、構成として、子供に Pivot、孫に Camera が来る構成にしなくてはなりません。
こちらのスクリプトを使う際はお気を付けください。