Примеры кода
Пример 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);
}
}