Opa Eduardo, tudo bem?
Eu consegui resolver esse problema alterando o MovePosition para o velocity. Meu script ficou assim:
CharactersMovements.cs:
public class CharactersMovements : MonoBehaviour
{
private Rigidbody rb;
void Awake()
{
rb = GetComponent<Rigidbody>();
}
public void MoveCharacter(Vector3 direction, float speed)
{
rb.velocity = direction.normalized * speed;
}
public void RotateCharacter(Vector3 direction)
{
// lógica
}
public void Death()
{
// lógica
}
}
PlayerControl.cs:
public class PlayerControl : MonoBehaviour, IDeadly, IHealLife
{
public CharacterStatus PlayerStatus;
public InterfaceControl ScriptIC;
public AudioClip DamageSound;
private CharacterAnimations playerAnimation;
private PlayerMovements movePlayer;
private Vector3 direction;
void Start()
{
PlayerStatus = GetComponent<CharacterStatus>();
playerAnimation = GetComponent<CharacterAnimations>();
movePlayer = GetComponent<PlayerMovements>();
}
void Update()
{
float axleX = Input.GetAxisRaw("Horizontal");
float axleZ = Input.GetAxisRaw("Vertical");
direction = new Vector3(axleX, 0, axleZ);
playerAnimation.MoveAnimation(direction.magnitude);
}
void FixedUpdate()
{
movePlayer.MoveCharacter(direction, PlayerStatus.Speed); // Movimento o jogador
movePlayer.RotatePlayer(); // Rotaciona o jogador de acordo com a mira
}
public void TakeDamage(int damage)
{
// lógica
}
public void Dead()
{
ScriptIC.GameOver();
}
public void HealLife(int healingValue)
{
// lógica
}
}
Talvez seus zumbis fiquem meio doidos, girando no modo vagar(meu método vagar se chama Wander), para isso eu resolvi assim:
ZombieControl.cs:
public class ZombieControl : MonoBehaviour, IDeadly
{
. . .
void FixedUpdate()
{
if (Player != null)
{
distanceDiff = Vector3.Distance(transform.position, Player.transform.position);
}
int distanceWander = 15;
int distanceAttack = 3;
zombieMovements.RotateCharacter(direction);
zombieAnimations.MoveAnimation(direction.magnitude);
if (distanceDiff > distanceWander)
{
Wander();
}
else if (distanceDiff > distancePursue || distanceDiff > distanceAttack)
{
Pursue();
zombieAnimations.AttackAnimation(false);
}
else
{
if (Player != null)
{
direction = Player.transform.position - transform.position;
zombieAnimations.AttackAnimation(true);
}
}
}
void Pursue()
{
direction = Player.transform.position - transform.position; // Determina qual direção o objeto deve seguir
zombieMovements.MoveCharacter(direction, ZombieStatus.Speed);
}
void Wander()
{
timer -= Time.deltaTime;
if (timer <= 0)
{
randomPos = RandomizePosition();
direction = randomPos - transform.position;
timer += wanderingTime + Random.Range(-1f, 1f);
}
bool closeEnough = Vector3.Distance(transform.position, randomPos) <= 0.05;
if (closeEnough == false)
{
zombieMovements.MoveCharacter(direction, ZombieStatus.Speed);
}
else
{
direction = Vector3.zero;
}
}
. . .
}
Eu removi bastante conteúdo dos scripts pra evitar ficar muito grande, mas a lógica está ai.
Existe algo que preciso comentar. A minha solução para os zumbis pararem de girar no modo vagar tem um erro de lógica, eles deveriam parar de tentar andar caso a posição aleatória gerada fosse impossível de alcançar, por exemplo, quando a posição aleatória gerada fica dentro de uma casa. Eu não tentei solucionar isso, pois gostei do resultado, zumbis são meio burros né kkkkkk
Também criei um Physic Material, zerei o Dynamic Friction e Static Friction, e alterei o Friction Combine para Minimum. Adicionei ele ao colisor do player, zumbis e boss para que diminuisse a fricção entre os colisores(quando tenta andar perto das paredes ficava agarrando).
Se quiser ver o resultado, da um conferida no game pronto, a senha é zombie.
https://murilocseidenstucker.itch.io/zombie-game-v004