Это мой первый топик на этом форуме. Мне 33 года, 6 лет назад делал игру на Юнити, затем пошёл работать в бюджетную сферу и игрострой забросил. И вот, спустя 6 лет, снова вернулся и делаю игру. Сейчас разбираюсь с самыми основами и застрял прямо в самом начале. Итак, есть скрип движения персонажа (с видом сверху/сбоку, если это важно). Персонаж поворачивает вслед за курсором.
Что необходимо, чтобы мне объяснили:
1) Почему персонаж будто скользит? Т.е. начинаешь бежать, отпускаешь кнопки бега и персонаж продолжает скользить по поверхности. Есть где-то в "моем" позаимствованном коде где-то этот параметр? Что за это отвечает? Как убрать? Как уменьшить скольжение, поменять параметр?
2) Почему в скрипте используются слои (что это? Зачем?) и рейкас для обнаружения пола под персонажем? А как же обычный isGrounded? (кстати, у меня исГраундед не работает)
3) Попытался сделать проверку на то, что персонаж в воздухе. Т.е. если в воздухе, то чтобы персонаж летел с той скоростью, которая была задана в момент прыжка. Сейчас получается, что персонаж во время прыжка может менять траекторию движения. Как сделать правильно, чтобы персонаж во время полета не мог менять траекторию и скорость полета?
4) В том числе, при прикручивании увеличения скорости при нажатии шифт (кстати, как это лучше всего сорганизовать?), как лучше всего вернуть значения при отпускании шифта? Т.е. шифт нажали - персонаж бежит быстрее, отпустили - передвигается с обычной скоростью. При этом, если персонаж в воздухе - то шифт не ускоряет движение (думаю, тут связь с предыдущим пунктом, что если сделать так, что при состоянии персонажа в воздухе вообще никак бы скорость не менялась).
5) Может прыжки лучше вообще убрать в моем случае, если я хочу сделать игру, где не будет прыжков, а будут только перепрыгивания препятствий? Кстати, как это лучше всего организовать? Допустим, есть заборчик. Персонаж подбегает к заборчику, там, я так полагаю, находится триггер на присутствие игрока и возможность прыгания. Если игрок повернут лицом к префабу заборчика - то появляется надпись типа "Чтобы перепрыгнуть нажмите пробел". Игрок перепрыгивает, проигрывается анимация перепрыгивания и игрока телепортирует за заборчик - так было бы правильно? Тогда прыжок можно вообще убрать, по-идее, т.к. слишком сложная система.
Но давайте для начала разберемся, мне для науки, как правильно 1) сделать блокировку на изменение траектории движения, скорость в полете 2) Изменить скорость движения при беге и возврат её в обычное состояние (если шифт отпущен, либо закончилась стамина) 3) не менять скорость движения в полете, если включен "бег" (если пункт 1 выполнен - тогда этот автоматом чек).
А, и ещё, у меня занки вопросиков, вместо кириллицы. Каждый раз при запуске VS Code Editor приходилось переключать UTF-8 на Windows 1252, но я задолбался. При этом при перезапуске компа - перестало помогать и это. Теперь вместо вопросиком просто тильды (~), даже в раскладке 1252. Как починить?
Синтаксис:
Используется csharp
public class PlayerControlTPS : MonoBehaviour {
[Header("��������� ��������:")]
public float speed = 1.5f; // ����. ��������
public float acceleration = 100f;
public float defaultAcceleration = 100f; // ���������
[Header("��������:")]
public Transform bodyTransform; // ������ �������� (���������)
public float smooth = 3;
public bool useSmooth;
[Header("������:")]
public KeyCode jumpButton = KeyCode.Space; // ������� ��� ������
public float jumpForce = 10; // ���� ������
public float jumpDistance = 1.2f; // ���������� �� ������ �������, �� �����������
[Header("������������ ������ ������")]
public Transform cameraParent;
private Vector3 direction;
private int layerMask;
private Rigidbody body;
void Awake()
{
body = GetComponent<Rigidbody>();
body.freezeRotation = true;
// ������� ������ ���� �������� ��������� ����, ��� ������ ������
layerMask = 1 << gameObject.layer | 1 << 2;
layerMask = ~layerMask;
}
void FixedUpdate()
{
body.AddForce(direction.normalized * defaultAcceleration * body.mass * speed);
// ����������� ��������, ����� ������ ����� ��������� ����������
if(Mathf.Abs(body.velocity.x) > speed)
{
body.velocity = new Vector3(Mathf.Sign(body.velocity.x) * speed, body.velocity.y, body.velocity.z);
}
if(Mathf.Abs(body.velocity.z) > speed)
{
body.velocity = new Vector3(body.velocity.x, body.velocity.y, Mathf.Sign(body.velocity.z) * speed);
}
Rotation();
}
void Rotation() // �������� ����, ������������ �������
{
Vector3 lookPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.y)) - body.position;
lookPos.y = 0; // ������� � ��������� �Z
if(useSmooth)
{
Quaternion playerRotation = Quaternion.LookRotation(lookPos);
bodyTransform.rotation = Quaternion.Lerp(bodyTransform.rotation, playerRotation, smooth * Time.fixedDeltaTime);
}
else
{
bodyTransform.rotation = Quaternion.LookRotation(lookPos);
}
}
bool NotGetJump() // ���������, ���� �� ��������� ��� ������
{
RaycastHit hit;
Ray ray = new Ray(transform.position, Vector3.down);
if (Physics.Raycast(ray, out hit, jumpDistance, layerMask))
{
return true;
}
return false;
}
void Update()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
// ������ ����������� ��������
direction = new Vector3(h, 0, v);
direction = cameraParent.TransformDirection(direction);
direction = new Vector3(direction.x, 0, direction.z);
Debug.DrawRay(transform.position, Vector3.down * jumpDistance, Color.red); //
<span style="font-weight: bold"> if(Input.GetKeyDown(jumpButton) && NotGetJump())
{
body.velocity = new Vector2(0, jumpForce);
}
if(Input.GetKeyDown(KeyCode.LeftShift) && NotGetJump())
{
defaultAcceleration = defaultAcceleration*2;
} </span>
// тут я хотел вернуть значение переменной defaultAcceleration, приравнивая к значению acceleration, если шифт не нажат (отпущен), но что-то пошло не так.
}
}
[Header("��������� ��������:")]
public float speed = 1.5f; // ����. ��������
public float acceleration = 100f;
public float defaultAcceleration = 100f; // ���������
[Header("��������:")]
public Transform bodyTransform; // ������ �������� (���������)
public float smooth = 3;
public bool useSmooth;
[Header("������:")]
public KeyCode jumpButton = KeyCode.Space; // ������� ��� ������
public float jumpForce = 10; // ���� ������
public float jumpDistance = 1.2f; // ���������� �� ������ �������, �� �����������
[Header("������������ ������ ������")]
public Transform cameraParent;
private Vector3 direction;
private int layerMask;
private Rigidbody body;
void Awake()
{
body = GetComponent<Rigidbody>();
body.freezeRotation = true;
// ������� ������ ���� �������� ��������� ����, ��� ������ ������
layerMask = 1 << gameObject.layer | 1 << 2;
layerMask = ~layerMask;
}
void FixedUpdate()
{
body.AddForce(direction.normalized * defaultAcceleration * body.mass * speed);
// ����������� ��������, ����� ������ ����� ��������� ����������
if(Mathf.Abs(body.velocity.x) > speed)
{
body.velocity = new Vector3(Mathf.Sign(body.velocity.x) * speed, body.velocity.y, body.velocity.z);
}
if(Mathf.Abs(body.velocity.z) > speed)
{
body.velocity = new Vector3(body.velocity.x, body.velocity.y, Mathf.Sign(body.velocity.z) * speed);
}
Rotation();
}
void Rotation() // �������� ����, ������������ �������
{
Vector3 lookPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.y)) - body.position;
lookPos.y = 0; // ������� � ��������� �Z
if(useSmooth)
{
Quaternion playerRotation = Quaternion.LookRotation(lookPos);
bodyTransform.rotation = Quaternion.Lerp(bodyTransform.rotation, playerRotation, smooth * Time.fixedDeltaTime);
}
else
{
bodyTransform.rotation = Quaternion.LookRotation(lookPos);
}
}
bool NotGetJump() // ���������, ���� �� ��������� ��� ������
{
RaycastHit hit;
Ray ray = new Ray(transform.position, Vector3.down);
if (Physics.Raycast(ray, out hit, jumpDistance, layerMask))
{
return true;
}
return false;
}
void Update()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
// ������ ����������� ��������
direction = new Vector3(h, 0, v);
direction = cameraParent.TransformDirection(direction);
direction = new Vector3(direction.x, 0, direction.z);
Debug.DrawRay(transform.position, Vector3.down * jumpDistance, Color.red); //
<span style="font-weight: bold"> if(Input.GetKeyDown(jumpButton) && NotGetJump())
{
body.velocity = new Vector2(0, jumpForce);
}
if(Input.GetKeyDown(KeyCode.LeftShift) && NotGetJump())
{
defaultAcceleration = defaultAcceleration*2;
} </span>
// тут я хотел вернуть значение переменной defaultAcceleration, приравнивая к значению acceleration, если шифт не нажат (отпущен), но что-то пошло не так.
}
}