[RESOLVIDO] Clicar em um botão e o personagem se mover por uma distância.
3 participantes
SchultzGames :: UNITY 3D :: Resolvidos
Página 1 de 1
[RESOLVIDO] Clicar em um botão e o personagem se mover por uma distância.
Olá, estou criando um jogo, porém estou com dificuldade de implementar uma mecânica. O jogador terá que passar de nível colocando os blocos de código que executa uma determinada ação no jogo.
O problema é que não importa a quantidade de blocos que eu colocar sempre executa apenas uma vez, eu quero que executar um bloco, depois outro e outro e assim por diante. Desde já agradeço pela ajuda e paciência.
Um vídeo do protótipo do jogo.
Código do Player
- Código:
[size=16]using [i]System[/i].[i]Collections[/i];
using [i]System[/i].[i]Collections[/i].[i]Generic[/i];
using [i]UnityEngine[/i];
public class PlayerController : [i]MonoBehaviour[/i]
{
#region Fields
private [i]float[/i] _speed = 2f;
private [i]float[/i] _jumpForce = 5f;
private [i]GameObject[/i] _slotRun;
private [i]Rigidbody2D[/i] _rigid;
private [i]Animator[/i] _animator;
// private bool _isGrounded;
// private Transform _floorPoint;
#endregion
#region Unity
private [i]void[/i] Awake()
{
_rigid = GetComponent<[i]Rigidbody2D[/i]>();
_animator = GetComponent<[i]Animator[/i]>();
_slotRun = GameObject.FindWithTag( "Slot Run" );
// _floorPoint = transform.Find( "FloorPoint" );
}
private [i]void[/i] Update()
{
// Is Grounded?
// _isGrounded = Physics2D.OverlapCircle( _floorPoint.position, 0.025f, LayerMask.GetMask("Ground") );
}
private [i]void[/i] LateUpdate()
{
_animator.SetBool( "Idle", _rigid.velocity == Vector2.zero );
// _animator.SetBool( "isGrounded", _isGrounded );
_animator.SetFloat( "VerticalVelocity", _rigid.velocity.y );
}
#endregion
#region Button Run
public [i]void[/i] ButtonRun()
{
for( [i]int[/i] i = 0; i < _slotRun.transform.childCount; i++ )
{
[i]GameObject[/i] block = _slotRun.transform.GetChild( i ).gameObject;
if( block.CompareTag("Walk") )
{
StartCoroutine( "Walk" );
}
if( block.CompareTag("Jump") )
{
Jump();
}
}
}
#endregion
#region Methods Movement
private [i]IEnumerator[/i] Walk()
{
_rigid.velocity = Vector2.right * _speed;
yield return new [i]WaitForSeconds[/i]( 0.5f );
_rigid.velocity = Vector2.zero;
}
private [i]void[/i] Jump()
{
_rigid.AddForce( Vector2.up * _jumpForce, ForceMode2D.Impulse );
}
#endregion
}
[/size]
Markimg22- Programador
- PONTOS : 1621
REPUTAÇÃO : 6
Idade : 23
Respeito as regras :
Re: [RESOLVIDO] Clicar em um botão e o personagem se mover por uma distância.
Primeiro, bem legal a proposta do joguinho, curto bastante essa mecânica estilo Scratch e Robocode.
Acredito que a Coroutine não funcione como um pilha de comandos, seu "for" ocorre rápido demais, a primeira coroutine é chamada e enquanto ela é executada você chama mais vezes...
Existem outras formas de fazer isso, mas se não quiser alterar muito o código original, você pode pegar a quantidade de blocos quando der o click, chamar a coroutine e no fim dar um Invoke pra chamar o metodo novamente, isso até que a quantidade de chamadas seja igual a quantidade de blocos.
Não recriei a cena pra testar, mas isso já deve te dar uma ideia de como fazer.
Acredito que a Coroutine não funcione como um pilha de comandos, seu "for" ocorre rápido demais, a primeira coroutine é chamada e enquanto ela é executada você chama mais vezes...
Existem outras formas de fazer isso, mas se não quiser alterar muito o código original, você pode pegar a quantidade de blocos quando der o click, chamar a coroutine e no fim dar um Invoke pra chamar o metodo novamente, isso até que a quantidade de chamadas seja igual a quantidade de blocos.
Não recriei a cena pra testar, mas isso já deve te dar uma ideia de como fazer.
- Código:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
#region Fields
private float _speed = 2f;
private float _jumpForce = 5f;
private GameObject _slotRun;
private Rigidbody2D _rigid;
private Animator _animator;
// private bool _isGrounded;
// private Transform _floorPoint;
private int numComandos = 0;
private int comandoAtual = 0;
#endregion
#region Unity
private void Awake()
{
_rigid = GetComponent<Rigidbody2D>();
_animator = GetComponent<Animator>();
_slotRun = GameObject.FindWithTag("Slot Run");
// _floorPoint = transform.Find( "FloorPoint" );
}
private void Update()
{
// Is Grounded?
// _isGrounded = Physics2D.OverlapCircle( _floorPoint.position, 0.025f, LayerMask.GetMask("Ground") );
}
private void LateUpdate()
{
_animator.SetBool("Idle", _rigid.velocity == Vector2.zero);
// _animator.SetBool( "isGrounded", _isGrounded );
_animator.SetFloat("VerticalVelocity", _rigid.velocity.y);
}
#endregion
#region Button Run
public void ButtonRun()
{
numComandos = _slotRun.transform.childCount;
comandoAtual = 0;
ExecutarComandos();
}
private void ExecutarComandos()
{
GameObject block = _slotRun.transform.GetChild(comandoAtual).gameObject;
if (block.CompareTag("Walk"))
{
StartCoroutine("Walk");
}
if (block.CompareTag("Jump"))
{
StartCoroutine("Jump");
}
}
#endregion
#region Methods Movement
private IEnumerator Walk()
{
_rigid.velocity = Vector2.right * _speed;
yield return new WaitForSeconds(0.5f);
_rigid.velocity = Vector2.zero;
comandoAtual++;
if (comandoAtual < numComandos)
{
Invoke("ExecutarComandos", 0);
}
}
private IEnumerator Jump()
{
_rigid.AddForce(Vector2.up * _jumpForce, ForceMode2D.Impulse);
yield return new WaitForSeconds(0.5f);
comandoAtual++;
if (comandoAtual < numComandos)
{
Invoke("ExecutarComandos", 0);
}
}
#endregion
}
Fagner- Moderador
- PONTOS : 4443
REPUTAÇÃO : 667
Áreas de atuação : Modelagem 3D, Programação.
Respeito as regras :
Re: [RESOLVIDO] Clicar em um botão e o personagem se mover por uma distância.
Vlwww Fagner, agora entendi oq tava dando errado kkkkk...Muito obrigado!! Ajudou muito!!!!
Markimg22- Programador
- PONTOS : 1621
REPUTAÇÃO : 6
Idade : 23
Respeito as regras :
Re: [RESOLVIDO] Clicar em um botão e o personagem se mover por uma distância.
Fagner escreveu:Primeiro, bem legal a proposta do joguinho, curto bastante essa mecânica estilo Scratch e Robocode.
Acredito que a Coroutine não funcione como um pilha de comandos, seu "for" ocorre rápido demais, a primeira coroutine é chamada e enquanto ela é executada você chama mais vezes...
Existem outras formas de fazer isso, mas se não quiser alterar muito o código original, você pode pegar a quantidade de blocos quando der o click, chamar a coroutine e no fim dar um Invoke pra chamar o metodo novamente, isso até que a quantidade de chamadas seja igual a quantidade de blocos.
Não recriei a cena pra testar, mas isso já deve te dar uma ideia de como fazer.
- Código:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
#region Fields
private float _speed = 2f;
private float _jumpForce = 5f;
private GameObject _slotRun;
private Rigidbody2D _rigid;
private Animator _animator;
// private bool _isGrounded;
// private Transform _floorPoint;
private int numComandos = 0;
private int comandoAtual = 0;
#endregion
#region Unity
private void Awake()
{
_rigid = GetComponent<Rigidbody2D>();
_animator = GetComponent<Animator>();
_slotRun = GameObject.FindWithTag("Slot Run");
// _floorPoint = transform.Find( "FloorPoint" );
}
private void Update()
{
// Is Grounded?
// _isGrounded = Physics2D.OverlapCircle( _floorPoint.position, 0.025f, LayerMask.GetMask("Ground") );
}
private void LateUpdate()
{
_animator.SetBool("Idle", _rigid.velocity == Vector2.zero);
// _animator.SetBool( "isGrounded", _isGrounded );
_animator.SetFloat("VerticalVelocity", _rigid.velocity.y);
}
#endregion
#region Button Run
public void ButtonRun()
{
numComandos = _slotRun.transform.childCount;
comandoAtual = 0;
ExecutarComandos();
}
private void ExecutarComandos()
{
GameObject block = _slotRun.transform.GetChild(comandoAtual).gameObject;
if (block.CompareTag("Walk"))
{
StartCoroutine("Walk");
}
if (block.CompareTag("Jump"))
{
StartCoroutine("Jump");
}
}
#endregion
#region Methods Movement
private IEnumerator Walk()
{
_rigid.velocity = Vector2.right * _speed;
yield return new WaitForSeconds(0.5f);
_rigid.velocity = Vector2.zero;
comandoAtual++;
if (comandoAtual < numComandos)
{
Invoke("ExecutarComandos", 0);
}
}
private IEnumerator Jump()
{
_rigid.AddForce(Vector2.up * _jumpForce, ForceMode2D.Impulse);
yield return new WaitForSeconds(0.5f);
comandoAtual++;
if (comandoAtual < numComandos)
{
Invoke("ExecutarComandos", 0);
}
}
#endregion
}
Fagner, se não for pedir muito...como seria a outra forma de fazer essa mecânica?? Não precisa passar o código inteiro não, só fala mais ou menos a lógica que eu vou atrás pra tentar fazer. Desde já vlww muitooo!!!
Markimg22- Programador
- PONTOS : 1621
REPUTAÇÃO : 6
Idade : 23
Respeito as regras :
Re: [RESOLVIDO] Clicar em um botão e o personagem se mover por uma distância.
O seu código funciona de forma similar a uma Queue, então você pode usar uma diretamente.
Aqui tem um exemplo:
https://answers.unity.com/questions/1590871/how-to-stack-coroutines-and-call-each-one-till-all.html
Aqui tem um exemplo:
https://answers.unity.com/questions/1590871/how-to-stack-coroutines-and-call-each-one-till-all.html
Fagner- Moderador
- PONTOS : 4443
REPUTAÇÃO : 667
Áreas de atuação : Modelagem 3D, Programação.
Respeito as regras :
Re: [RESOLVIDO] Clicar em um botão e o personagem se mover por uma distância.
Vlww, vou tentar fazer aki...como marcar esse tópico como resolvido??Fagner escreveu:O seu código funciona de forma similar a uma Queue, então você pode usar uma diretamente.
Aqui tem um exemplo:
https://answers.unity.com/questions/1590871/how-to-stack-coroutines-and-call-each-one-till-all.html
Markimg22- Programador
- PONTOS : 1621
REPUTAÇÃO : 6
Idade : 23
Respeito as regras :
Re: [RESOLVIDO] Clicar em um botão e o personagem se mover por uma distância.
Eu sei que o assunto já foi encerrado, mas outra prática que eu gosto muito de usar nessas situações de fila de espera em loops é o comando WaitUntil. Ele funciona dentro de Coroutines e a lógica é bem simples: ele só vai executar o próximo bloco de comandos se a condição dentro do WaitUntil for cumprida, ou seja, ele faz essa espera (sleep Task) até a condição se completar sem precisar congelar a aplicação ou usar programação assícrona.
Re: [RESOLVIDO] Clicar em um botão e o personagem se mover por uma distância.
Muito obrigado pela dica, quanto mais conhecimento melhor kakakak, vou atrás desse assunto, vlw msmMayLeone escreveu:Eu sei que o assunto já foi encerrado, mas outra prática que eu gosto muito de usar nessas situações de fila de espera em loops é o comando WaitUntil. Ele funciona dentro de Coroutines e a lógica é bem simples: ele só vai executar o próximo bloco de comandos se a condição dentro do WaitUntil for cumprida, ou seja, ele faz essa espera (sleep Task) até a condição se completar sem precisar congelar a aplicação ou usar programação assícrona.
Markimg22- Programador
- PONTOS : 1621
REPUTAÇÃO : 6
Idade : 23
Respeito as regras :
Tópicos semelhantes
» [RESOLVIDO] Como mover personagem em y pelo Rigidbody
» Animaçoes Para personagem ao clicar
» COMO MOVER UM OBJETO OU PERSONAGEM
» [TUTORIAL] mover personagem na direção da camera
» Como fazer meu personagem se mover para o lado?
» Animaçoes Para personagem ao clicar
» COMO MOVER UM OBJETO OU PERSONAGEM
» [TUTORIAL] mover personagem na direção da camera
» Como fazer meu personagem se mover para o lado?
SchultzGames :: UNITY 3D :: Resolvidos
Página 1 de 1
Permissões neste sub-fórum
Não podes responder a tópicos