unity3d
Raycast
Поиск…
параметры
параметр | подробности |
---|---|
происхождения | Начальная точка луча в мировых координатах |
направление | Направление луча |
maxDistance | Максимальное расстояние, которое луч должен проверять на наличие столкновений |
слой маски | Маска слоя, которая используется для выборочного игнорирования коллайдеров при бросании луча. |
queryTriggerInteraction | Указывает, где этот запрос должен ударить триггеры. |
Физика Raycast
Эта функция передает луч из origin
в направлении direction
длины maxDistance
против всех коллайдеров в сцене.
Функция принимает в origin
direction
maxDistance
и вычислить , если есть коллайдер перед GameObject.
Physics.Raycast(origin, direction, maxDistance);
Например, эта функция будет печатать Hello World
на консоли, если к ней подключено что-то в пределах 10 единиц GameObject
:
using UnityEngine;
public class TestPhysicsRaycast: MonoBehaviour
{
void FixedUpdate()
{
Vector3 fwd = transform.TransformDirection(Vector3.forward);
if (Physics.Raycast(transform.position, fwd, 10))
print("Hello World");
}
}
Физика2D Raycast2D
Вы можете использовать raycasts, чтобы проверить, может ли ai ходить, не падая с края уровня.
using UnityEngine;
public class Physics2dRaycast: MonoBehaviour
{
public LayerMask LineOfSightMask;
void FixedUpdate()
{
RaycastHit2D hit = Physics2D.Raycast(raycastRightPart, Vector2.down, 0.6f * heightCharacter, LineOfSightMask);
if(hit.collider != null)
{
//code when the ai can walk
}
else
{
//code when the ai cannot walk
}
}
}
В этом примере направление правильное. Переменная raycastRightPart является правой частью персонажа, поэтому raycast будет происходить в правой части персонажа. Расстояние в 0.6f раз превышает высоту персонажа, поэтому raycast не даст удар, когда он ударит по земле, которая ниже, чем земля, на которой он сейчас стоит. Убедитесь, что Layermask установлен только на землю, иначе он также обнаружит другие объекты.
RaycastHit2D сам по себе является структурой, а не классом, поэтому удар не может быть нулевым; это означает, что вам нужно проверить коллайдер переменной RaycastHit2D.
Инкапсуляция вызовов Raycast
Если ваши сценарии называют Raycast
напрямую, это может привести к проблемам, если вам нужно изменить матрицы столкновений в будущем, так как вам придется отслеживать каждое поле LayerMask
для внесения изменений. В зависимости от размера вашего проекта это может стать огромным начинанием.
Инкапсуляция вызовов Raycast
может облегчить вам жизнь.
Рассматривая это по принципу SoC , игровой объект действительно не должен знать или заботиться о LayerMasks. Ему нужен только способ сканирования своего окружения. Получает ли результат raycast то или это не имеет значения для игрового объекта. Он должен действовать только на информацию, которую он получает, и не делать каких-либо предположений об окружающей среде, в которой он существует.
Одним из способов решения этой проблемы является , чтобы переместить значение LayerMask в ScriptableObject экземпляров и использовать их в качестве формы raycast услуг , которые вы инъекционная в скрипты.
// RaycastService.cs
using UnityEngine;
[CreateAssetMenu(menuName = "StackOverflow")]
public class RaycastService : ScriptableObject
{
[SerializeField]
LayerMask layerMask;
public RaycastHit2D Raycast2D(Vector2 origin, Vector2 direction, float distance)
{
return Physics2D.Raycast(origin, direction, distance, layerMask.value);
}
// Add more methods as needed
}
// MyScript.cs
using UnityEngine;
public class MyScript : MonoBehaviour
{
[SerializeField]
RaycastService raycastService;
void FixedUpdate()
{
RaycastHit2D hit = raycastService.Raycast2D(Vector2.zero, Vector2.down, 1f);
}
}
Это позволяет вам сделать несколько сервисов raycast, все с различными комбинациями LayerMask для разных ситуаций. У вас может быть тот, который ударяет только с коллайдерами на землю, а другой - с земными коллайдерами и односторонними платформами.
Если вам когда-либо понадобится внести радикальные изменения в настройки LayerMask, вам нужно только обновить эти ресурсы RaycastService.