Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
47
Help us understand the problem. What is going on with this article?
@sakano

[Unity3D]プレイヤー中心に回転・拡縮・追従するカメラ

More than 1 year has passed since last update.

仕様

  • 指定したキャラを中心に回転できる(マウス左ボタンを押しながらドラッグで操作)
  • 指定したキャラを中心に拡大・縮小できる(マウスホイールで操作)
  • 指定したキャラが移動しても追従する

aa4b4552a91194a0b09f35344ad6d2bd.gif
(C)Unity Technologies Japan/UCL

ソースコード

// These codes are licensed under CC0.
// http://creativecommons.org/publicdomain/zero/1.0/deed.ja

using UnityEngine;

/// <summary>
/// The camera added this script will follow the specified object.
/// The camera can be moved by left mouse drag and mouse wheel.
/// </summary>
[ExecuteInEditMode, DisallowMultipleComponent]
public class FollowingCamera : MonoBehaviour
{
    public GameObject target; // an object to follow
    public Vector3 offset; // offset form the target object

    [SerializeField] private float distance = 4.0f; // distance from following object
    [SerializeField] private float polarAngle = 45.0f; // angle with y-axis
    [SerializeField] private float azimuthalAngle = 45.0f; // angle with x-axis

    [SerializeField] private float minDistance = 1.0f;
    [SerializeField] private float maxDistance = 7.0f;
    [SerializeField] private float minPolarAngle = 5.0f;
    [SerializeField] private float maxPolarAngle = 75.0f;
    [SerializeField] private float mouseXSensitivity = 5.0f;
    [SerializeField] private float mouseYSensitivity = 5.0f;
    [SerializeField] private float scrollSensitivity = 5.0f;

    void LateUpdate()
    {
        if (Input.GetMouseButton(0)) {
            updateAngle(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
        }
        updateDistance(Input.GetAxis("Mouse ScrollWheel"));

        var lookAtPos = target.transform.position + offset;
        updatePosition(lookAtPos);
        transform.LookAt(lookAtPos);
    }

    void updateAngle(float x, float y)
    {
        x = azimuthalAngle - x * mouseXSensitivity;
        azimuthalAngle = Mathf.Repeat(x, 360);

        y = polarAngle + y * mouseYSensitivity;
        polarAngle = Mathf.Clamp(y, minPolarAngle, maxPolarAngle);
    }

    void updateDistance(float scroll)
    {
        scroll = distance - scroll * scrollSensitivity;
        distance = Mathf.Clamp(scroll, minDistance, maxDistance);
    }

    void updatePosition(Vector3 lookAtPos)
    {
        var da = azimuthalAngle * Mathf.Deg2Rad;
        var dp = polarAngle * Mathf.Deg2Rad;
        transform.position = new Vector3(
            lookAtPos.x + distance * Mathf.Sin(dp) * Mathf.Cos(da),
            lookAtPos.y + distance * Mathf.Cos(dp),
            lookAtPos.z + distance * Mathf.Sin(dp) * Mathf.Sin(da));
    }
}

解説

動かしたいカメラにコンポーネントとして追加してtargetにキャラを指定すると動く。そのままだとキャラの足下を見てしまうのでoffsetで適当にずらすと良い。

アルゴリズムは球面座標で検索すべし。数式をUnityで実装する際は軸の対応に注意(Unityではy軸が上方向)

47
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
synamon
VR空間での最適なユーザ体験を創るためのベースシステムである「NEUTRANS BIZ」を開発しています。VR市場の成長、進化をより加速させるべく、本サービスのコア機能やベースとなる部分を、ゼロベースで一緒に設計・開発設計、デザインする仲間を絶賛募集しております。https://synamon.hatenablog.com/

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
47
Help us understand the problem. What is going on with this article?