Сделайте систему бега по стене, персонаж входит в состояние бега по стене, но не выходит из него.
Вот видео:
PlayerMovement
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
[Header("Speed Display")]
public float speed; //переменная для проверки скорости
[Header("Movement")]
public float moveSpeed;
public float groundDrag;
public float jumpForce;
public float jumpCooldown;
public float airMultiplayer;
public float wallRunSpeed;
bool readyToJump = false;
[Header("Keybinds")]
public KeyCode jumpKey = KeyCode.Space;
[Header("Ground Check")]
public float playerHeight;
public LayerMask whatIsGround;
bool grounded;
[Header("References")]
public Transform orientation;
private Rigidbody rb;
public MovementState state;
public enum MovementState
{
wallrunning
}
public bool wallrunning;
[Header("Input")]
float horizontalInput;
float verticalInput;
Vector3 moveDirection;
private void Start()
{
//gameObject.GetComponent
().enabled = false;
StartCoroutine(CalcSpeed());
rb = GetComponent();
rb.freezeRotation = true; //если не будет фриза, то игрок упадет (?)
readyToJump = true;
}
private void Update()
{
//ground check
grounded = Physics.Raycast(transform.position, Vector3.down, playerHeight * 0.5f + 0.2f, whatIsGround);
MyInput();
//hangle drag
if (grounded)
rb.drag = groundDrag;
else
rb.drag = 0;
}
private void FixedUpdate()
{
MovePlayer();
SpeedControl();
}
private void MyInput()
{
if (Input.GetKey(jumpKey) && readyToJump && grounded)
{
readyToJump = false;
Jump();
Invoke(nameof(ResetJump), jumpCooldown);
}
horizontalInput = Input.GetAxisRaw("Horizontal");
verticalInput = Input.GetAxisRaw("Vertical");
}
private void MovePlayer()
{
//calculate movement direction
moveDirection = orientation.forward * verticalInput + orientation.right * horizontalInput;
if (grounded)
rb.AddForce(moveDirection * moveSpeed * 10f, ForceMode.Force);
else if (!grounded)
rb.AddForce(moveDirection * moveSpeed * 10f * airMultiplayer, ForceMode.Force);
}
private void SpeedControl()
{
Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
if (flatVel.magnitude > moveSpeed)
{
Vector3 limitedVel = flatVel.normalized * moveSpeed;
rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z);
}
}
// дисплей скорости
IEnumerator CalcSpeed()
{
bool isPlaying = true;
while (isPlaying)
{
Vector3 prevPos = transform.position;
yield return new WaitForFixedUpdate();
speed = Mathf.RoundToInt(Vector3.Distance(transform.position, prevPos) / Time.fixedDeltaTime);
}
}
private void Jump()
{
rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
rb.AddForce(transform.up * jumpForce, ForceMode.Impulse);
}
private void ResetJump()
{
readyToJump = true;
}
private void StateHandler()
{
//Mode - wallrunning
if (wallrunning)
{
state = MovementState.wallrunning;
moveSpeed = wallRunSpeed;
}
}
}
Wallrun
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WallRun : MonoBehaviour
{
[Header("Wallrun")]
public LayerMask whatIsWall;
public LayerMask whatIsGround;
public float wallRunForce;
public float maxWallRunTime;
private float wallRunTimer;
[Header("Detection")]
public float wallCheckDistance;
public float minJumpHeight;
private RaycastHit leftWallHit;
private RaycastHit rightWallHit;
private bool wallLeft;
private bool wallRight;
[Header("Input")]
float horizontalInput;
float verticalInput;
[Header("References")]
public Transform orientation;
private Rigidbody rb;
private PlayerMovement pm;
// Start is called before the first frame update
void Start()
{
rb = GetComponent();
pm = GetComponent
();
}
void Update()
{
CheckForWall();
StateMachine();
}
private void FixedUpdate()
{
if (pm.wallrunning)
WallRunningMovement();
}
private void CheckForWall()
{
wallRight = Physics.Raycast(transform.position, /*Vector3.left*/orientation.right, out rightWallHit, wallCheckDistance, whatIsWall);
wallLeft = Physics.Raycast(transform.position, /*Vector3.left*/-orientation.right, out leftWallHit, wallCheckDistance, whatIsWall);
}
private bool AboveGround()
{
return !Physics.Raycast(transform.position, Vector3.down, minJumpHeight, whatIsGround);
}
private void StateMachine()
{
horizontalInput = Input.GetAxisRaw("Horizontal");
verticalInput = Input.GetAxisRaw("Vertical");
if((wallLeft || wallRight) && verticalInput > 0 && AboveGround())
{
if (!pm.wallrunning)
{
StartWallRun();
}
else
{
if(pm.wallrunning)
StopWallRun();
}
}
}
private void StartWallRun()
{
pm.wallrunning = true;
}
private void WallRunningMovement()
{
rb.useGravity = false;
rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
Vector3 wallNormal = wallRight ? rightWallHit.normal : leftWallHit.normal;
Vector3 wallForward = Vector3.Cross(wallNormal, transform.up);
rb.AddForce(wallForward * wallRunForce, ForceMode.Force);
}
private void StopWallRun()
{
pm.wallrunning = false;
}
}
Потратил много времени, но так и не смог решить этот вопрос. Думал, что раз у меня только одна гос проблема, сделал гос гулять но проблема была не в этом. Пытался сделать активацию гравитации после выхода из состояния бега по стене, тоже не получилось.
Редактировать:
Скорректировал мой скрипт, игрок выходит из состояния бега по стене по wallRunTimer, но все равно плавает в воздухе. Измененный метод StateMachine():
private void StateMachine()
{
horizontalInput = Input.GetAxisRaw("Horizontal");
verticalInput = Input.GetAxisRaw("Vertical");
if((wallLeft || wallRight) && verticalInput > 0 && AboveGround())
{
if (!pm.wallrunning)
{
StartWallRun();
}
else if ((!wallLeft && !wallRight && pm.wallrunning) || verticalInput < 0 || !AboveGround())
{
StopWallRun();
}
}
}
добавлен wallRunTImer в WallRunningMovement(), также изменен StopWallRun():
private void StopWallRun()
{
pm.wallrunning = false;
rb.useGravity = true;
wallRunTimer = 0;
}
Подробнее здесь: https://stackoverflow.com/questions/791 ... -out-of-it
Делаем систему Wallrun, но персонаж из нее не выходит ⇐ C#
Место общения программистов C#
-
Anonymous
1730451510
Anonymous
Сделайте систему бега по стене, персонаж входит в состояние бега по стене, но не выходит из него.
Вот видео:
[youtube]y4POPMRsjg4[/youtube]
PlayerMovement
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
[Header("Speed Display")]
public float speed; //переменная для проверки скорости
[Header("Movement")]
public float moveSpeed;
public float groundDrag;
public float jumpForce;
public float jumpCooldown;
public float airMultiplayer;
public float wallRunSpeed;
bool readyToJump = false;
[Header("Keybinds")]
public KeyCode jumpKey = KeyCode.Space;
[Header("Ground Check")]
public float playerHeight;
public LayerMask whatIsGround;
bool grounded;
[Header("References")]
public Transform orientation;
private Rigidbody rb;
public MovementState state;
public enum MovementState
{
wallrunning
}
public bool wallrunning;
[Header("Input")]
float horizontalInput;
float verticalInput;
Vector3 moveDirection;
private void Start()
{
//gameObject.GetComponent
().enabled = false;
StartCoroutine(CalcSpeed());
rb = GetComponent();
rb.freezeRotation = true; //если не будет фриза, то игрок упадет (?)
readyToJump = true;
}
private void Update()
{
//ground check
grounded = Physics.Raycast(transform.position, Vector3.down, playerHeight * 0.5f + 0.2f, whatIsGround);
MyInput();
//hangle drag
if (grounded)
rb.drag = groundDrag;
else
rb.drag = 0;
}
private void FixedUpdate()
{
MovePlayer();
SpeedControl();
}
private void MyInput()
{
if (Input.GetKey(jumpKey) && readyToJump && grounded)
{
readyToJump = false;
Jump();
Invoke(nameof(ResetJump), jumpCooldown);
}
horizontalInput = Input.GetAxisRaw("Horizontal");
verticalInput = Input.GetAxisRaw("Vertical");
}
private void MovePlayer()
{
//calculate movement direction
moveDirection = orientation.forward * verticalInput + orientation.right * horizontalInput;
if (grounded)
rb.AddForce(moveDirection * moveSpeed * 10f, ForceMode.Force);
else if (!grounded)
rb.AddForce(moveDirection * moveSpeed * 10f * airMultiplayer, ForceMode.Force);
}
private void SpeedControl()
{
Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
if (flatVel.magnitude > moveSpeed)
{
Vector3 limitedVel = flatVel.normalized * moveSpeed;
rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z);
}
}
// дисплей скорости
IEnumerator CalcSpeed()
{
bool isPlaying = true;
while (isPlaying)
{
Vector3 prevPos = transform.position;
yield return new WaitForFixedUpdate();
speed = Mathf.RoundToInt(Vector3.Distance(transform.position, prevPos) / Time.fixedDeltaTime);
}
}
private void Jump()
{
rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
rb.AddForce(transform.up * jumpForce, ForceMode.Impulse);
}
private void ResetJump()
{
readyToJump = true;
}
private void StateHandler()
{
//Mode - wallrunning
if (wallrunning)
{
state = MovementState.wallrunning;
moveSpeed = wallRunSpeed;
}
}
}
Wallrun
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WallRun : MonoBehaviour
{
[Header("Wallrun")]
public LayerMask whatIsWall;
public LayerMask whatIsGround;
public float wallRunForce;
public float maxWallRunTime;
private float wallRunTimer;
[Header("Detection")]
public float wallCheckDistance;
public float minJumpHeight;
private RaycastHit leftWallHit;
private RaycastHit rightWallHit;
private bool wallLeft;
private bool wallRight;
[Header("Input")]
float horizontalInput;
float verticalInput;
[Header("References")]
public Transform orientation;
private Rigidbody rb;
private PlayerMovement pm;
// Start is called before the first frame update
void Start()
{
rb = GetComponent();
pm = GetComponent
();
}
void Update()
{
CheckForWall();
StateMachine();
}
private void FixedUpdate()
{
if (pm.wallrunning)
WallRunningMovement();
}
private void CheckForWall()
{
wallRight = Physics.Raycast(transform.position, /*Vector3.left*/orientation.right, out rightWallHit, wallCheckDistance, whatIsWall);
wallLeft = Physics.Raycast(transform.position, /*Vector3.left*/-orientation.right, out leftWallHit, wallCheckDistance, whatIsWall);
}
private bool AboveGround()
{
return !Physics.Raycast(transform.position, Vector3.down, minJumpHeight, whatIsGround);
}
private void StateMachine()
{
horizontalInput = Input.GetAxisRaw("Horizontal");
verticalInput = Input.GetAxisRaw("Vertical");
if((wallLeft || wallRight) && verticalInput > 0 && AboveGround())
{
if (!pm.wallrunning)
{
StartWallRun();
}
else
{
if(pm.wallrunning)
StopWallRun();
}
}
}
private void StartWallRun()
{
pm.wallrunning = true;
}
private void WallRunningMovement()
{
rb.useGravity = false;
rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
Vector3 wallNormal = wallRight ? rightWallHit.normal : leftWallHit.normal;
Vector3 wallForward = Vector3.Cross(wallNormal, transform.up);
rb.AddForce(wallForward * wallRunForce, ForceMode.Force);
}
private void StopWallRun()
{
pm.wallrunning = false;
}
}
Потратил много времени, но так и не смог решить этот вопрос. Думал, что раз у меня только одна гос проблема, сделал гос гулять но проблема была не в этом. Пытался сделать активацию гравитации после выхода из состояния бега по стене, тоже не получилось.
Редактировать:
Скорректировал мой скрипт, игрок выходит из состояния бега по стене по wallRunTimer, но все равно плавает в воздухе. Измененный метод StateMachine():
private void StateMachine()
{
horizontalInput = Input.GetAxisRaw("Horizontal");
verticalInput = Input.GetAxisRaw("Vertical");
if((wallLeft || wallRight) && verticalInput > 0 && AboveGround())
{
if (!pm.wallrunning)
{
StartWallRun();
}
else if ((!wallLeft && !wallRight && pm.wallrunning) || verticalInput < 0 || !AboveGround())
{
StopWallRun();
}
}
}
добавлен wallRunTImer в WallRunningMovement(), также изменен StopWallRun():
private void StopWallRun()
{
pm.wallrunning = false;
rb.useGravity = true;
wallRunTimer = 0;
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79141458/making-wallrun-system-but-character-does-not-come-out-of-it[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия