#c# #unity3d
Вопрос:
У меня в игре есть своего рода шипы, где сфера является «Игроком», если игрок наступит на шипы, его следует вышвырнуть из коллайдера шипов. Сейчас я использую случайный диапазон, иногда это хорошо работает, но в некоторых ситуациях это снова приводит к всплескам. Я хочу, чтобы, если мяч столкнулся с шипами, он должен был отскочить в случайную позицию, но не смог снова прыгнуть в положение шипов, как при двойном столкновении.
public float ballBounceStrenght;
private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.CompareTag("Player"))
{
Debug.Log("collision");
var position = new Vector3(Random.Range(-70, 70.0f), Random.Range(90f, 90.0f), Random.Range(-70.0f, 70.0f));
ball.AddForce(position * ballBounceStrenght);
}
}
Это код, который я использую для запуска в случайном диапазоне. Понятия не имею, должен ли я делать это так, может быть, просто исправить цифры или есть какой-то другой способ сделать это.
Ответ №1:
Я бы использовал функцию для вычисления этой позиции, чтобы избежать вертикальных шипов. Для этого вы можете использовать полярные координаты в плоскости XZ и вернуть свой новый pos обратно в декартовых координатах.
Не отлаженный код, просто для вашего вдохновения:
//return new pos from vertical pos aviding a vertical cilinder.
private Vector3 NewPos(
(float x, float z) VerticalPos,
float radiusToAvoid, float radiusMax) {
float fi = Random.Range(0f, 360f);
float radiusApart = Random.Range(radiusToAvoid, radiusMax);
float radomHeight = Random.Range(70,90); //according to your code y range
return new Vector3(VerticalPos.x radiusApart * Math.Cos(fi), VerticalPos.z radiusApart * Math.Sin(fi));
}
Затем вам нужно будет передать x и z в функцию:
общественный поплавковый трамплин;
private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.CompareTag("Player"))
{
Debug.Log("collision");
var position = NewPos((transform.position.x, transform.position.z), 50f, 20f);
ball.AddForce(position * ballBounceStrenght);
}
}
Все Vector3
pos могут быть переданы вместо только x и z, так что вы также можете обрабатывать относительный y в NewPos
функции. Однако я предоставил вам пример кода таким образом, чтобы очистить «псевдо вертикальный цилиндр» от шипов вдоль всей оси y (вертикальной оси), чтобы получить новое положение.
Комментарии:
1. Хорошо, имеет смысл, попытаюсь сделать это сейчас, но один быстрый вопрос: что означает «R»?
2. Я обновил псевдокод в ответе, R обозначает радиус друг от друга. Это смещение радиуса от радиуса, которого следует избегать. Радиус, которого следует избегать, — это один из псевдо вертикальных цилиндров шипов, которого следует избегать в новом pos. В обновлении , которое я назвал
radiusApart
, обратите внимание, что это минимумradiusToAvoid
. Надеюсь, в этом есть смысл3. Ладно, понял, написал, но происходит то же самое, в большинстве случаев все работает так, как должно, иногда он просто игнорирует все и возвращается к коллайдеру
4. Я жестко закодировал то
50
и то20
здесь:var position = NewPos((transform.position.x, transform.position.z), 50f, 20f);
. Вам нужно определить радиус ваших шипов (тот, которого следует избегать) и максимальный радиус для вашего нового pos. Как уже было сказано, предоставленный код не отлаживается и просто копируется для вставки, это для вас, чтобы понять идею и двигаться дальше к решению