Примеры кода

Пример 1: Основы Rigidbody

Работа с компонентом Rigidbody и его свойствами:

using UnityEngine;

public class RigidbodyExample : MonoBehaviour
{
    [Header("Настройки Rigidbody")]
    public float mass = 1f;
    public float drag = 0.5f;
    public float angularDrag = 0.05f;
    
    private Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
        
        if (rb == null)
        {
            rb = gameObject.AddComponent<Rigidbody>();
        }

        SetupRigidbody();
    }

    void SetupRigidbody()
    {
        rb.mass = mass;
        rb.drag = drag;
        rb.angularDrag = angularDrag;
        rb.useGravity = true;
        
        Debug.Log($"Rigidbody настроен: масса={mass}");
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.G))
        {
            rb.useGravity = !rb.useGravity;
            Debug.Log($"Гравитация: {rb.useGravity}");
        }

        if (Input.GetKeyDown(KeyCode.K))
        {
            rb.isKinematic = !rb.isKinematic;
            Debug.Log($"Кинематический: {rb.isKinematic}");
        }

        if (Input.GetKeyDown(KeyCode.R))
        {
            ResetRigidbody();
        }

        if (Input.GetKeyDown(KeyCode.I))
        {
            ShowInfo();
        }
    }

    void ResetRigidbody()
    {
        rb.position = Vector3.zero;
        rb.rotation = Quaternion.identity;
        rb.velocity = Vector3.zero;
        rb.angularVelocity = Vector3.zero;
        Debug.Log("Rigidbody сброшен");
    }

    void ShowInfo()
    {
        Debug.Log($"Скорость: {rb.velocity}");
        Debug.Log($"Позиция: {rb.position}");
        Debug.Log($"Спит: {rb.IsSleeping()}");
    }
}

Пример 2: Применение сил

Различные способы применения сил к Rigidbody:

using UnityEngine;

public class ForcesExample : MonoBehaviour
{
    [Header("Силы")]
    public float forceAmount = 10f;
    public float jumpForce = 300f;
    public float moveSpeed = 5f;
    
    private Rigidbody rb;
    private bool isGrounded = false;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        HandleMovement();
        HandleForces();
    }

    void HandleMovement()
    {
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");

        Vector3 moveDirection = new Vector3(horizontal, 0, vertical);
        rb.AddForce(moveDirection * moveSpeed);

        if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
        {
            rb.AddForce(Vector3.up * jumpForce);
            Debug.Log("Прыжок!");
        }
    }

    void HandleForces()
    {
        // Импульс (F)
        if (Input.GetKeyDown(KeyCode.F))
        {
            Vector3 impulse = transform.forward * forceAmount;
            rb.AddForce(impulse, ForceMode.Impulse);
            Debug.Log("Импульс!");
        }

        // Взрыв (E)
        if (Input.GetKeyDown(KeyCode.E))
        {
            Vector3 explosion = Vector3.up + Random.insideUnitSphere;
            rb.AddForce(explosion * forceAmount, ForceMode.VelocityChange);
            Debug.Log("Взрыв!");
        }

        // Вращение (T)
        if (Input.GetKeyDown(KeyCode.T))
        {
            rb.AddTorque(Vector3.up * forceAmount);
            Debug.Log("Вращение!");
        }

        // Сила в точке (P)
        if (Input.GetKeyDown(KeyCode.P))
        {
            Vector3 position = transform.position + Vector3.right;
            rb.AddForceAtPosition(Vector3.forward * forceAmount, position);
            Debug.Log("Сила в точке!");
        }
    }

    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Ground"))
        {
            isGrounded = true;
        }
    }

    void OnCollisionExit(Collision collision)
    {
        if (collision.gameObject.CompareTag("Ground"))
        {
            isGrounded = false;
        }
    }
}

Пример 3: Физические суставы

Работа с различными типами суставов:

using UnityEngine;

public class JointsExample : MonoBehaviour
{
    [Header("Суставы")]
    public GameObject connectedObject;
    public float springForce = 50f;
    public float damperForce = 5f;
    
    private Joint currentJoint;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            CreateFixedJoint();
        }

        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            CreateHingeJoint();
        }

        if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            CreateSpringJoint();
        }

        if (Input.GetKeyDown(KeyCode.X))
        {
            RemoveJoint();
        }
    }

    void CreateFixedJoint()
    {
        RemoveJoint();
        
        FixedJoint joint = gameObject.AddComponent<FixedJoint>();
        if (connectedObject != null)
        {
            joint.connectedBody = connectedObject.GetComponent<Rigidbody>();
        }
        joint.breakForce = 1000f;
        
        currentJoint = joint;
        Debug.Log("Fixed Joint создан");
    }

    void CreateHingeJoint()
    {
        RemoveJoint();
        
        HingeJoint joint = gameObject.AddComponent<HingeJoint>();
        if (connectedObject != null)
        {
            joint.connectedBody = connectedObject.GetComponent<Rigidbody>();
        }
        
        joint.axis = Vector3.right;
        joint.useLimits = true;
        
        JointLimits limits = joint.limits;
        limits.min = -90f;
        limits.max = 90f;
        joint.limits = limits;
        
        currentJoint = joint;
        Debug.Log("Hinge Joint создан");
    }

    void CreateSpringJoint()
    {
        RemoveJoint();
        
        SpringJoint joint = gameObject.AddComponent<SpringJoint>();
        if (connectedObject != null)
        {
            joint.connectedBody = connectedObject.GetComponent<Rigidbody>();
        }
        
        joint.spring = springForce;
        joint.damper = damperForce;
        joint.minDistance = 1f;
        joint.maxDistance = 5f;
        
        currentJoint = joint;
        Debug.Log("Spring Joint создан");
    }

    void RemoveJoint()
    {
        if (currentJoint != null)
        {
            DestroyImmediate(currentJoint);
            currentJoint = null;
            Debug.Log("Сустав удален");
        }
    }

    void OnJointBreak(float breakForce)
    {
        Debug.Log($"Сустав сломался! Сила: {breakForce}");
        currentJoint = null;
    }
}

Пример 4: Продвинутые коллизии

Работа с коллизиями и физическими материалами:

using UnityEngine;

public class CollisionsExample : MonoBehaviour
{
    [Header("Коллизии")]
    public PhysicMaterial bouncyMaterial;
    public float damageThreshold = 5f;
    
    private Rigidbody rb;
    private Collider col;
    private int collisionCount = 0;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
        col = GetComponent<Collider>();
        
        CreateBouncyMaterial();
    }

    void CreateBouncyMaterial()
    {
        if (bouncyMaterial == null)
        {
            bouncyMaterial = new PhysicMaterial("Bouncy");
            bouncyMaterial.bounciness = 0.9f;
            bouncyMaterial.dynamicFriction = 0.1f;
            bouncyMaterial.staticFriction = 0.1f;
        }
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.B))
        {
            col.material = bouncyMaterial;
            Debug.Log("Отскакивающий материал");
        }

        if (Input.GetKeyDown(KeyCode.R))
        {
            PerformRaycast();
        }
    }

    void PerformRaycast()
    {
        Vector3 direction = transform.forward;
        float distance = 10f;

        RaycastHit hit;
        if (Physics.Raycast(transform.position, direction, out hit, distance))
        {
            Debug.Log($"Raycast попал в: {hit.collider.name}");
            Debug.Log($"Расстояние: {hit.distance}");
            
            // Применение силы
            Rigidbody hitRb = hit.collider.GetComponent<Rigidbody>();
            if (hitRb != null)
            {
                hitRb.AddForce(direction * 10f, ForceMode.Impulse);
            }
        }
        
        Debug.DrawRay(transform.position, direction * distance, Color.blue, 2f);
    }

    void OnCollisionEnter(Collision collision)
    {
        collisionCount++;
        Debug.Log($"Коллизия #{collisionCount} с: {collision.gameObject.name}");
        
        float impactForce = collision.relativeVelocity.magnitude;
        Debug.Log($"Сила удара: {impactForce}");

        if (impactForce > damageThreshold)
        {
            Debug.Log("Получен урон от сильного удара!");
        }

        // Анализ точек контакта
        foreach (ContactPoint contact in collision.contacts)
        {
            Debug.Log($"Точка контакта: {contact.point}");
            Debug.Log($"Нормаль: {contact.normal}");
        }
    }

    void OnTriggerEnter(Collider other)
    {
        Debug.Log($"Вошел в триггер: {other.name}");
    }

    void OnTriggerExit(Collider other)
    {
        Debug.Log($"Вышел из триггера: {other.name}");
    }
}

Пример 5: Настройки физики

Работа с глобальными настройками физики:

using UnityEngine;

public class PhysicsSettings : MonoBehaviour
{
    [Header("Настройки физики")]
    public Vector3 customGravity = new Vector3(0, -9.81f, 0);
    public float timeScale = 1f;
    
    private Vector3 originalGravity;

    void Start()
    {
        originalGravity = Physics.gravity;
        ShowPhysicsInfo();
    }

    void Update()
    {
        HandlePhysicsControls();
    }

    void HandlePhysicsControls()
    {
        // Изменение гравитации (G)
        if (Input.GetKeyDown(KeyCode.G))
        {
            ToggleGravity();
        }

        // Пользовательская гравитация (C)
        if (Input.GetKeyDown(KeyCode.C))
        {
            SetCustomGravity();
        }

        // Сброс гравитации (N)
        if (Input.GetKeyDown(KeyCode.N))
        {
            ResetGravity();
        }

        // Замедление времени (T)
        if (Input.GetKeyDown(KeyCode.T))
        {
            ToggleSlowMotion();
        }

        // Информация о физике (I)
        if (Input.GetKeyDown(KeyCode.I))
        {
            ShowPhysicsInfo();
        }
    }

    void ToggleGravity()
    {
        if (Physics.gravity.magnitude > 0)
        {
            Physics.gravity = Vector3.zero;
            Debug.Log("Гравитация отключена");
        }
        else
        {
            Physics.gravity = originalGravity;
            Debug.Log("Гравитация включена");
        }
    }

    void SetCustomGravity()
    {
        Physics.gravity = customGravity;
        Debug.Log($"Установлена гравитация: {customGravity}");
    }

    void ResetGravity()
    {
        Physics.gravity = originalGravity;
        Debug.Log("Гравитация сброшена");
    }

    void ToggleSlowMotion()
    {
        if (Time.timeScale == 1f)
        {
            Time.timeScale = 0.3f;
            Debug.Log("Замедленное время");
        }
        else
        {
            Time.timeScale = 1f;
            Debug.Log("Нормальное время");
        }
    }

    void ShowPhysicsInfo()
    {
        Debug.Log("=== Настройки физики ===");
        Debug.Log($"Гравитация: {Physics.gravity}");
        Debug.Log($"Масштаб времени: {Time.timeScale}");
        Debug.Log($"Фиксированный временной шаг: {Time.fixedDeltaTime}");
        Debug.Log($"Максимальные итерации: {Physics.defaultMaxAngularSpeed}");
    }

    // Пример создания физического объекта
    void CreatePhysicsObject()
    {
        GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        obj.transform.position = transform.position + Vector3.up * 3f;
        
        Rigidbody rb = obj.AddComponent<Rigidbody>();
        rb.mass = Random.Range(0.5f, 2f);
        
        // Случайный материал
        Collider col = obj.GetComponent<Collider>();
        PhysicMaterial mat = new PhysicMaterial();
        mat.bounciness = Random.Range(0f, 1f);
        mat.dynamicFriction = Random.Range(0f, 1f);
        col.material = mat;
        
        Debug.Log($"Создан объект с массой: {rb.mass}");
    }

    void OnDrawGizmos()
    {
        // Визуализация направления гравитации
        Gizmos.color = Color.red;
        Gizmos.DrawRay(transform.position, Physics.gravity.normalized * 3f);
    }
}