Character controller en modelo importado a Unity desde Maya
Buenas. Tengo un personaje creado en Autodesk Maya y lo he importado a Unity con todas sus animaciones, modelo y texturas. Sin embargo, al asignarle el character controller, el personaje anda, corre y golpea bien, pero en el salto, la cápsula del character controller no sigue al personaje y se queda pegada al suelo, a pesar de que la animación se ve bien.
He intentado centrar la cápsula desde código, pero no funciona ya que la malla del personaje está por encima. He considerado aumentar temporalmente la altura de la cápsula, pero esto no es una solución definitiva.
El objeto playera contiene dos objetos, uno de los controladores declarado en Maya y otro con el hips y la estructura de los huesos. Si coloco el character controller en el objeto player, ocurre el problema mencionado anteriormente, pero si lo coloco en hips, la cápsula sigue al personaje en todos los movimientos, pero las animaciones no funcionan correctamente.
He intentado crear el avatar del personaje en Unity directamente, y aunque reconoce todos los huesos, ocurre el mismo problema que con el avatar genérico.
He revisado el animation root para ver si estaba marcado, pero no encontré ninguna solución.
¿Alguien tiene alguna idea de lo que podría estar pasando para que la cápsula no siga al personaje cuando coloco el character controller en el objeto player?
Agradecería cualquier consejo o ayuda para solucionar este problema.
Muchas gracias y un saludo.
Rigidbody como alternativa a character controller
El componente "Rigidbody" es una alternativa al character controller que ofrece algunas ventajas e inconvenientes.
Ventajas:
Realismo físico: El "Rigidbody" utiliza la física realista para simular los movimientos del personaje, lo que puede hacer que los movimientos sean más naturales y creíbles.
Interacción con el entorno: El "Rigidbody" permite que el personaje interactúe con el entorno de una manera más realista. Por ejemplo, el personaje puede empujar objetos, saltar más alto en una plataforma elevada, o caer al suelo de manera realista.
Colisiones: El "Rigidbody" gestiona automáticamente las colisiones con otros objetos, lo que puede simplificar el proceso de programación.
Inconvenientes:
Más complejidad: El "Rigidbody" puede ser más complejo de programar y configurar que el character controller, especialmente si se desea un comportamiento preciso.
Menor control sobre el movimiento: El "Rigidbody" utiliza la física realista para simular los movimientos, lo que significa que el programador tiene menos control sobre la velocidad y la dirección del movimiento del personaje.
Más uso de recursos: El "Rigidbody" puede ser más intensivo en recursos que el character controller, lo que puede afectar el rendimiento del juego en computadoras más antiguas o con recursos limitados.
En resumen, el uso del "Rigidbody" puede ofrecer ventajas en términos de realismo físico e interacción con el entorno, pero puede ser más complejo de programar y consumir más recursos del sistema que el character controller. La elección entre los dos dependerá de las necesidades específicas del juego y las habilidades del programador.
Código base para los movimientos del personaje
Este script tiene una variable de velocidad para controlar el movimiento del personaje, una variable de fuerza de salto para el salto y una variable de fuerza de voltereta para controlar la voltereta del personaje. También hay una variable de duración de voltereta para controlar cuánto tiempo debe durar la voltereta.
El script utiliza la función Translate para mover el personaje horizontalmente y la función AddForce para hacer que el personaje salte. También utiliza una corutina para controlar la voltereta del personaje y desactiva la gravedad y el movimiento horizontal mientras se realiza la voltereta.
El script también tiene una función OnCollisionEnter que comprueba si el personaje está en el suelo o no. Si el personaje está en el suelo, se establece la variable isGrounded en true para permitir que el personaje salte de nuevo.
Código:
using UnityEngine;
public class CustomController : MonoBehaviour
{
public float speed = 5f; // Velocidad de movimiento del personaje
public float jumpForce = 7f; // Fuerza de salto del personaje
public float rollForce = 10f; // Fuerza de voltereta del personaje
public float rollDuration = 0.5f; // Duración de la voltereta del personaje
private bool isGrounded; // Variable para comprobar si el personaje está en el suelo
private Rigidbody rb; // Componente RigidBody del personaje
private void Start()
{
rb = GetComponent<Rigidbody>(); // Obtenemos el componente RigidBody del personaje
}
private void Update()
{
// Movimiento horizontal del personaje
float horizontal = Input.GetAxis("Horizontal");
transform.Translate(Vector3.right * horizontal * speed * Time.deltaTime);
// Salto del personaje
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
isGrounded = false;
}
// Voltereta del personaje
if (Input.GetKeyDown(KeyCode.LeftShift))
{
StartCoroutine(Roll());
}
}
private void OnCollisionEnter(Collision collision)
{
// Comprobar si el personaje está en el suelo
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = true;
}
}
private IEnumerator Roll()
{
// Desactivar la gravedad y el movimiento horizontal
rb.useGravity = false;
float horizontal = Input.GetAxis("Horizontal");
transform.Translate(Vector3.right * -horizontal * rollForce * Time.deltaTime);
// Realizar la voltereta
yield return new WaitForSeconds(rollDuration);
// Reactivar la gravedad y el movimiento horizontal
rb.useGravity = true;
transform.Translate(Vector3.right * horizontal * rollForce * Time.deltaTime);
}
}
Ejemplo de un script que permite que el personaje interactúe con objetos
Te dejo un ejemplo de script que permite que el personaje interactúe con objetos en el mundo que le rodea y reconozca los mismos, es un código base, a partir de ahí puedes ampliarlo tanto como quieras.
En este ejemplo, el script utiliza un Raycast para detectar si hay un objeto interactuable dentro de una distancia específica y en una capa determinada. Si se detecta un objeto interactuable, se llama al método Interact() del componente Interactable asociado con el objeto. Puedes personalizar la distancia y la capa de detección para adaptarse a tus necesidades.
Para utilizar este script, deberás crear un nuevo script llamado Interact y adjuntarlo a tu personaje en el editor de Unity. Asegúrate de agregar también un componente de cámara a tu personaje si no lo has hecho ya, para poder usarla en el Raycast.
Luego, en cada objeto del mundo del juego que desees que sea interactuable, deberás crear un componente de tipo Interactable y personalizarlo para que haga lo que quieras que haga cuando se interactúa con él.
Espero que esto te sea útil.
Código:
using UnityEngine;
public class Interact : MonoBehaviour
{
public float interactDistance = 2f;
public LayerMask interactLayer;
private Camera playerCam;
private void Start()
{
playerCam = Camera.main;
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.E))
{
RaycastHit hit;
if (Physics.Raycast(playerCam.transform.position, playerCam.transform.forward, out hit, interactDistance, interactLayer))
{
Interactable interactable = hit.collider.GetComponent<Interactable>();
if (interactable != null)
{
interactable.Interact();
}
}
}
}
}