๐Ÿ“”Utils - Orbit Camera

BamgasiJMยท2026๋…„ 3์›” 16์ผ

Unity GenArt

๋ชฉ๋ก ๋ณด๊ธฐ
6/41
post-thumbnail

Camera Controlling & Orbiting Target

[์„ธํŒ… ๋ฐฉ๋ฒ•]

  • Main Camera์— ์ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ปดํฌ๋„ŒํŠธ๋กœ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • Inspector์˜ Target์— ์กฐํ˜•๋ฌผ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์„ ํƒํ•ด์„œ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.
Hierarchy
 โ”œโ”€โ”€ SculptureObject          โ† GenArtSculpture.cs ๋ถ€์ฐฉ
 โ””โ”€โ”€ Main Camera              โ† OrbitCamera.cs ๋ถ€์ฐฉ
                                    โ”” target โ†’ SculptureObject ๋“œ๋ž˜๊ทธ ํ• ๋‹น

[์ฝ”๋“œ์˜ ๊ธฐ๋Šฅ]

[์ธํ„ฐ๋ž™์…˜]

  • ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋“œ๋ž˜๊ทธ: ์กฐํ˜•๋ฌผ ์ฃผ์œ„๋ฅผ ๊ณต์ „
  • ๋งˆ์šฐ์Šค ํœ : ์คŒ ์ธ/์•„์›ƒ
  • F ํ‚ค: ์นด๋ฉ”๋ผ๋ฅผ ์ดˆ๊ธฐ ์œ„์น˜๋กœ ๋ฆฌ์…‹

๐Ÿ“„Orbit_Camera.cs

using UnityEngine;
using UnityEngine.InputSystem; // New Input System ๋„ค์ž„์ŠคํŽ˜์ด์Šค

public class OrbitCamera : MonoBehaviour
{
    [Header("ํƒ€๊ฒŸ")]
    public Transform target;

    [Header("์ดˆ๊ธฐ ์œ„์น˜")]
    public float initialDistance = 12f;
    public float initialPitch    = 20f;
    public float initialYaw      = 30f;

    [Header("๊ณต์ „ ์„ค์ •")]
    public float orbitSensitivity = 0.15f;
    public float orbitSmoothing   = 8.0f;

    [Header("์คŒ ์„ค์ •")]
    public float zoomSensitivity = 20.0f;
    public float zoomMin         = 3.0f;
    public float zoomMax         = 200.0f;
    public float zoomSmoothing   = 8.0f;

    [Header("์ž๋™ ๊ณต์ „")]
    public bool  autoOrbit      = true;
    public float autoOrbitSpeed = 5.0f;

    // ============================================================
    // ๋‚ด๋ถ€ ์ƒํƒœ
    // ============================================================

    float _yaw;
    float _pitch;
    float _distance;

    float _targetYaw;
    float _targetPitch;
    float _targetDistance;

    bool _isDragging = false; // ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ ๋“œ๋ž˜๊ทธ ์ค‘ ์—ฌ๋ถ€

    // New Input System์—์„œ ๋งˆ์šฐ์Šค ์ฐธ์กฐ๋ฅผ ์บ์‹ฑํ•ฉ๋‹ˆ๋‹ค
    Mouse    _mouse;
    Keyboard _keyboard;

    // ============================================================
    // Unity ์ด๋ฒคํŠธ
    // ============================================================

    void Start()
    {
        // ํ˜„์žฌ ์—ฐ๊ฒฐ๋œ ๋งˆ์šฐ์Šค์™€ ํ‚ค๋ณด๋“œ ์žฅ์น˜๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค
        // ์žฅ์น˜๊ฐ€ ์—†์œผ๋ฉด null์ด ๋ฐ˜ํ™˜๋˜๋ฏ€๋กœ ์ดํ›„ null ์ฒดํฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค
        _mouse    = Mouse.current;
        _keyboard = Keyboard.current;

        _yaw      = _targetYaw      = initialYaw;
        _pitch    = _targetPitch    = initialPitch;
        _distance = _targetDistance = initialDistance;

        ApplyTransform(true);
    }

    void LateUpdate()
    {
        if (target == null) return;

        // ์žฅ์น˜ ์—ฐ๊ฒฐ์ด ๋Š๊ฒผ๋‹ค๊ฐ€ ๋‹ค์‹œ ์—ฐ๊ฒฐ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋งค ํ”„๋ ˆ์ž„ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค
        _mouse    = Mouse.current;
        _keyboard = Keyboard.current;

        HandleOrbitInput();
        HandleZoomInput();
        HandleResetInput();
        HandleAutoOrbit();

        // ์Šค๋ฌด๋”ฉ: ํ˜„์žฌ ๊ฐ’์„ ๋ชฉํ‘œ ๊ฐ’ ๋ฐฉํ–ฅ์œผ๋กœ ๋ณด๊ฐ„ํ•ฉ๋‹ˆ๋‹ค
        _yaw      = Mathf.LerpAngle(_yaw,      _targetYaw,      Time.deltaTime * orbitSmoothing);
        _pitch    = Mathf.Lerp     (_pitch,    _targetPitch,    Time.deltaTime * orbitSmoothing);
        _distance = Mathf.Lerp     (_distance, _targetDistance, Time.deltaTime * zoomSmoothing);

        ApplyTransform(false);
    }

    // ============================================================
    // ์ž…๋ ฅ ์ฒ˜๋ฆฌ
    // ============================================================

    void HandleOrbitInput()
    {
        if (_mouse == null) return;

        // New Input System: wasPressedThisFrame / wasReleasedThisFrame
        // ์˜ค๋ฅธ์ชฝ ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ ์ƒํƒœ๋ฅผ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค
        if (_mouse.rightButton.wasPressedThisFrame)
            _isDragging = true;

        if (_mouse.rightButton.wasReleasedThisFrame)
            _isDragging = false;

        if (!_isDragging) return;

        // New Input System: delta.value๋กœ ์ด๋ฒˆ ํ”„๋ ˆ์ž„์˜ ๋งˆ์šฐ์Šค ์ด๋™๋Ÿ‰์„ ์ฝ์Šต๋‹ˆ๋‹ค
        // ๊ตฌ Input System์˜ GetAxis("Mouse X/Y")์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค
        Vector2 delta = _mouse.delta.ReadValue();

        // ์ด๋™๋Ÿ‰์— Time.deltaTime์„ ๊ณฑํ•ด์„œ ํ”„๋ ˆ์ž„๋ ˆ์ดํŠธ ๋…๋ฆฝ์ ์œผ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค
        _targetYaw   += delta.x * orbitSensitivity;
        _targetPitch -= delta.y * orbitSensitivity;
        _targetPitch  = Mathf.Clamp(_targetPitch, -80f, 80f);
    }

    void HandleZoomInput()
    {
        if (_mouse == null) return;

        // New Input System์˜ scroll ๊ฐ’์€ ํ”ฝ์…€ ๋‹จ์œ„๋กœ ๋“ค์–ด์˜ต๋‹ˆ๋‹ค.
        // ์ผ๋ฐ˜์ ์ธ ํœ  ํ•œ ์นธ = ์•ฝ 120. ์ด๊ฑธ ๊ทธ๋Œ€๋กœ ์“ฐ๋ฉด ๋„ˆ๋ฌด ํฌ๋ฏ€๋กœ
        // 120์œผ๋กœ ๋‚˜๋ˆ ์„œ "ํ•œ ์นธ = 1.0" ๋‹จ์œ„๋กœ ์ •๊ทœํ™”ํ•ฉ๋‹ˆ๋‹ค.
        float scroll = _mouse.scroll.ReadValue().y / 120f;

        if (Mathf.Abs(scroll) < 0.001f) return;

        // ํ˜„์žฌ ๊ฑฐ๋ฆฌ์— ๋น„๋ก€ํ•ด์„œ ์คŒ ์†๋„๋ฅผ ์กฐ์ ˆํ•ฉ๋‹ˆ๋‹ค.
        // ๋ฉ€๋ฆฌ ์žˆ์„์ˆ˜๋ก ํ•œ ๋ฒˆ์— ๋” ๋งŽ์ด ์ด๋™ํ•ด์„œ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋А๊ปด์ง‘๋‹ˆ๋‹ค.
        _targetDistance -= scroll * zoomSensitivity * (_targetDistance * 0.2f);
        _targetDistance  = Mathf.Clamp(_targetDistance, zoomMin, zoomMax);
    }

    void HandleResetInput()
    {
        if (_keyboard == null) return;

        // New Input System: wasPressedThisFrame์œผ๋กœ ์ด๋ฒˆ ํ”„๋ ˆ์ž„ ํ‚ค ์ž…๋ ฅ ๊ฐ์ง€
        // ๊ตฌ Input System์˜ GetKeyDown()์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค
        if (!_keyboard.fKey.wasPressedThisFrame) return;

        _targetYaw      = initialYaw;
        _targetPitch    = initialPitch;
        _targetDistance = initialDistance;
    }

    void HandleAutoOrbit()
    {
        if (!autoOrbit || _isDragging) return;

        _targetYaw += autoOrbitSpeed * Time.deltaTime;
    }

    // ============================================================
    // ์นด๋ฉ”๋ผ Transform ์ ์šฉ
    // ============================================================

    void ApplyTransform(bool instant)
    {
        Quaternion rotation = Quaternion.Euler(
            instant ? initialPitch : _pitch,
            instant ? initialYaw   : _yaw,
            0f
        );

        float    dist   = instant ? initialDistance : _distance;
        Vector3  offset = rotation * new Vector3(0f, 0f, -dist);

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

    // ============================================================
    // ๊ธฐ์ฆˆ๋ชจ
    // ============================================================
#if UNITY_EDITOR
    void OnDrawGizmosSelected()
    {
        if (target == null) return;

        Gizmos.color = new Color(0.3f, 0.8f, 1f, 0.2f);
        Gizmos.DrawWireSphere(target.position, _distance > 0 ? _distance : initialDistance);

        Gizmos.color = new Color(1f, 1f, 0f, 0.5f);
        Gizmos.DrawLine(target.position, transform.position);
    }
#endif
}

profile
Coding Art with Blender / oF / Processing / p5.js / nannou

0๊ฐœ์˜ ๋Œ“๊ธ€