BITFALL/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs

245 lines
7.6 KiB
C#
Raw Normal View History

2024-03-18 18:20:23 +08:00
// Magica Cloth 2.
// Copyright (c) 2023 MagicaSoft.
// https://magicasoft.jp
using UnityEngine;
namespace MagicaCloth2
{
/// <summary>
/// カメラ回転
/// </summary>
public class CameraOrbit : MonoBehaviour
{
[SerializeField]
private Transform cameraTransform;
[Header("Camera Target")]
public Transform cameraTarget;
public Vector3 cameraTargetPos;
public Vector3 cameraTargetOffset;
[Header("Now Position")]
[SerializeField]
private float cameraDist = 1.5f;
[SerializeField]
private float cameraPitch = 21.0f;
[SerializeField]
private float cameraYaw = 180.0f;
[Header("Parameter")]
[SerializeField]
private float cameraDistHokanTime = 0.1f;
[SerializeField]
private float cameraAngleHokanTime = 0.1f;
[SerializeField]
private float cameraDistSpeed = 0.02f;
[SerializeField]
private float cameraDistMax = 8.0f;
[SerializeField]
private float cameraDistMin = 0.1f;
[SerializeField]
private float cameraYawSpeed = 0.3f;
[SerializeField]
private float cameraPitchSpeed = 0.3f;
[SerializeField]
private float cameraMaxAngleSpeed = 100.0f;
[SerializeField]
private float cameraPitchMax = 89.0f;
[SerializeField]
private float cameraPitchMin = -89.0f;
// 中ボタンドラッグによる移動
public enum MoveMode
{
None,
UpDown,
Free,
}
[SerializeField]
private MoveMode moveMode = MoveMode.Free;
[SerializeField]
private float moveSpeed = 0.002f;
// 自動回転
[Header("Auto Rotation")]
[SerializeField]
private bool useAutoRotation = false;
[SerializeField]
private float autoRotationSpeed = 90.0f;
// 移動作業用
private float setCameraDist;
private float setCameraPitch;
private float setCameraYaw;
private float cameraDistVelocity;
private float cameraPitchVelocity;
private float cameraYawVelocity;
private float offsetYaw;
void Start()
{
if (cameraTransform == null)
{
var cam = GetComponent<Camera>();
if (cam)
cameraTransform = cam.transform;
}
if (cameraTransform == null)
enabled = false;
setCameraDist = cameraDist;
setCameraPitch = cameraPitch;
setCameraYaw = cameraYaw;
}
void OnEnable()
{
// 入力イベント登録
SimpleInputManager.OnTouchMove += OnTouchMove;
SimpleInputManager.OnDoubleTouchMove += OnDoubleTouchMove;
SimpleInputManager.OnTouchPinch += OnTouchPinch;
}
void OnDisable()
{
// 入力イベント解除
SimpleInputManager.OnTouchMove -= OnTouchMove;
SimpleInputManager.OnDoubleTouchMove -= OnDoubleTouchMove;
SimpleInputManager.OnTouchPinch -= OnTouchPinch;
}
void LateUpdate()
{
// カメラ更新
updateCamera();
}
// カメラ更新
private void updateCamera()
{
if (cameraTransform == null)
return;
// カメラターゲットポジション
if (cameraTarget)
{
cameraTargetPos = cameraTarget.position;
}
// 補間
cameraDist = Mathf.SmoothDamp(cameraDist, setCameraDist, ref cameraDistVelocity, cameraDistHokanTime);
cameraPitch = Mathf.SmoothDampAngle(cameraPitch, setCameraPitch, ref cameraPitchVelocity, cameraAngleHokanTime);
cameraYaw = Mathf.SmoothDampAngle(cameraYaw, setCameraYaw, ref cameraYawVelocity, cameraAngleHokanTime);
// 自動回転
if (useAutoRotation)
{
offsetYaw += autoRotationSpeed * Time.deltaTime;
}
// 座標確定
Quaternion q = Quaternion.Euler(cameraPitch, cameraYaw + offsetYaw, 0);
q = transform.rotation * q; // コンポーネントの回転
Vector3 v = new Vector3(0, 0, -cameraDist);
Vector3 pos = q * v;
// ターゲットポジション
Vector3 tarpos = cameraTargetPos + cameraTargetOffset;
Vector3 fixpos = tarpos + pos;
cameraTransform.localPosition = fixpos;
// 回転確定
Vector3 relativePos = tarpos - cameraTransform.position;
Quaternion rot = Quaternion.LookRotation(relativePos);
cameraTransform.rotation = rot;
}
// 回転操作
private void updatePitchYaw(Vector2 speed)
{
// Yaw
setCameraYaw += speed.x * cameraYawSpeed;
// Pitch
setCameraPitch += -speed.y * cameraPitchSpeed;
setCameraPitch = Mathf.Clamp(setCameraPitch, cameraPitchMin, cameraPitchMax);
}
// 移動操作
private void updateOffset(Vector2 speed)
{
if (cameraTransform == null)
{
return;
}
if (moveMode == MoveMode.UpDown)
{
cameraTargetOffset.y -= speed.y * moveSpeed;
}
else if (moveMode == MoveMode.Free)
{
Vector3 offset = cameraTransform.up * -speed.y * moveSpeed;
offset += cameraTransform.right * -speed.x * moveSpeed;
cameraTargetOffset += offset;
}
}
// ズーム操作
private void updateZoom(float speed)
{
float value = speed * cameraDistSpeed;
float scl = Mathf.InverseLerp(cameraDistMin, cameraDistMax, setCameraDist);
scl = Mathf.Clamp(scl, 0.1f, 1.0f);
setCameraDist -= value * scl;
setCameraDist = Mathf.Clamp(setCameraDist, cameraDistMin, cameraDistMax);
}
//=============================================================================================
/// <summary>
/// 入力通知:移動
/// </summary>
/// <param name="screenPos"></param>
/// <param name="screenVelocity"></param>
private void OnTouchMove(int fid, Vector2 screenPos, Vector2 screenVelocity, Vector2 cmVelocity)
{
screenVelocity *= Time.deltaTime * 60.0f;
if (fid == 2)
{
// 中ドラッグ
updateOffset(screenVelocity);
}
else if (fid == 0)
{
// 左ドラッグ
// 最大速度
screenVelocity = Vector2.ClampMagnitude(screenVelocity, cameraMaxAngleSpeed);
updatePitchYaw(screenVelocity);
}
}
private void OnDoubleTouchMove(int fid, Vector2 screenPos, Vector2 screenVelocity, Vector2 cmVelocity)
{
if (SimpleInputManager.Instance.GetTouchCount() >= 3)
updateOffset(screenVelocity);
}
/// <summary>
/// 入力通知:ピンチイン/アウト
/// </summary>
/// <param name="speedscr"></param>
/// <param name="speedcm"></param>
private void OnTouchPinch(float speedscr, float speedcm)
{
//if (Mathf.Abs(speedcm) > 1.0f)
if (SimpleInputManager.Instance.GetTouchCount() < 3)
updateZoom(speedcm);
}
}
}