Contrôleur de personnage 2D dans l'unité (essayant de récupérer les plateformes de la vieille école)

11

Aujourd'hui, j'essaie de créer un contrôleur de caractères 2D avec unité (en utilisant la phisique). Je suis assez nouveau dans les moteurs physiques et il est vraiment difficile d'obtenir la sensation de contrôle que je recherche. Je serais vraiment heureux si quelqu'un pouvait suggérer une solution à un problème que je trouve:

Ceci est mon FixedUpdate en ce moment:

public void FixedUpdate()
{
    Vector3 v=new Vector3(0,-10000*Time.fixedDeltaTime,0);
    _body.AddForce(v);

    v.y=0;
    if(state(MovementState.Left))
    {
        v.x=-_walkSpeed*Time.fixedDeltaTime+v.x;
        if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=-_maxWalkSpeed;
    }
    else if(state(MovementState.Right))
    {
        v.x= _walkSpeed*Time.fixedDeltaTime+v.x;
        if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=_maxWalkSpeed;
    }

    _body.velocity=v;

    Debug.Log("Velocity: "+_body.velocity);
}

J'essaie ici de déplacer simplement le corps rigide en appliquant une gravité et une force linéaire pour la gauche et la droite. J'ai mis en place un matériau physique qui ne fait aucun rebond et 0 frottement lors du déplacement et 1 frottement avec l'arrêt. Le problème principal est que j'ai des collisionneurs avec des pentes et que la vitesse change de monter (plus lentement), de descendre la pente (plus vite) et de marcher sur un collisionneur droit (normal). Comment cela pourrait-il être corrigé? Comme vous le voyez, j'applique toujours la même vitesse pour l'axe des x.

Pour le joueur, je l'ai configuré avec une sphère à la position des pieds qui est le corps rigide auquel j'applique des forces.

Toute autre astuce qui pourrait me faciliter la vie avec cela est la bienvenue :).

PD En rentrant chez moi, j'ai remarqué que je pouvais résoudre ce problème en appliquant une force constante parallèle à la surface sur laquelle le joueur marche, mais je ne sais pas si c'est la meilleure méthode.

Pas mal
la source
4
Les plateformes de la vieille école utilisaient la «physique des dessins animés» réglée à la main pour la mécanique des sauts et le contrôle direct de la vitesse (c.-à-d. Pas de physique du tout) pour les mouvements de marche. Si vous pouvez réécrire le contrôleur de personnage, faites-le, car il sera difficile de pousser et de produire une simulation physique squishy dans les mouvements nets des jeux de la vieille école.
Patrick Hughes
Le problème de l'écriture d'un fichier personnalisé est que la détection de collision est perdue. Et il n'est pas facile de le reconstruire sans utiliser raycast (selon l'environnement, etc ... cela pourrait être un tas d'entre eux). Comment gérez-vous ces situations?
Notbad
Vous pouvez avoir des collisionneurs sur des choses qui sont toujours animées sur mesure lorsque vous utilisez des corps rigides cinématiques. Je garantis que dans la plupart des situations, vous ne voulez pas vraiment de physique / forces du monde réel, etc. pour ce type d'application. Si vous recherchez un angle plus technique, recherchez peut-être Human IK
Runonthespot
1
Définissez la physique des fossés dans cette situation.
Ray_Garner

Réponses:

7

Si vous cherchez à imiter les plateformes de la vieille école, la première étape consiste à abandonner la physique. Vous finirez par combattre le système physique pour obtenir le mouvement décidément non réaliste d'un jeu de plateforme old school. Jetez un œil à ce remplacement de CharacterController qui abandonne complètement la physique pour avoir une bonne idée d'une façon de l'implémenter.

prime31
la source
3

Vous seriez probablement plus heureux de suivre ce que mheona a recommandé. Mais si vous allez utiliser la physique d'Unity, vous voudrez probablement l'utiliser ForceMode.VelocityChange.

Exemple:

public void FixedUpdate()
{
    var v = Vector3.zero;
    if(state(MovementState.Left))
    {
        v.x=-_walkSpeed*Time.fixedDeltaTime+v.x;
        if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=-_maxWalkSpeed;
    }
    else if(state(MovementState.Right))
    {
        v.x= _walkSpeed*Time.fixedDeltaTime+v.x;
        if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=_maxWalkSpeed;
    }

    _body.AddForce(v, ForceMode.VelocityChange);

    Debug.Log("Velocity: "+_body.velocity);
}

Vous devez également appliquer la gravité globale dans les paramètres de physique de votre projet, et pour les objets que vous souhaitez chuter plus rapidement, ajoutez un composant Force constante .

ForceMode.Impulseest similaire mais est affecté par la masse du corps rigide. Rend plus difficile à régler.

michael.bartnett
la source
2

Même si vous n'aimez pas le composant de contrôleur de personnage intégré (comme moi), jetez un œil à l'exemple de code Unity pour le didacticiel de jeu 2D .

Le code implémente un gameplay 2D complet avec des plates-formes mobiles, des ennemis et des boîtes avec collision, en utilisant le contrôleur de personnage.

Mais si vous ne voulez même pas y jeter un œil, je vous suggère de minimiser l'utilisation de la physique et d'essayer de copier son comportement avec votre propre code. Selon le type de jeu 2D que vous prévoyez, il peut fonctionner assez bien. Par exemple, au lieu d'appliquer une force pour Rigidbody.velocitydéplacer votre personnage, vous pourriez jouer directement avec Transform.Translate(), ce qui déplace l'objet en Transform.positionfonction de son axe. Vous pouvez déterminer le forwardet backlié à l'objet lui-même ou peut-être à la plate-forme ou au sol Transform.up, donc vous saurez si c'est une rampe et en quelque sorte connaître son angle.

De plus, si vous créez une sorte d'attribut de contrôle de la vitesse (par exemple, combien de temps la touche est enfoncée), vous pouvez l'appliquer avec votre direction pendant la traduction pour empêcher votre personnage de marcher quelque chose de trop incliné sans une certaine vitesse, tout comme ils l'ont fait sur Sonic the Hedgehog pour Genesis / Mega Drive.

Si vous choisissez de continuer à utiliser la physique, je ne peux pas vous aider du tout parce que je ne suis pas si bon dans ce domaine, mais sachez que c'est un comportement normal de monter une pente plus lentement car le corps a besoin de plus de force pour suivre , comme la vraie vie.

mheona
la source
La première chose que j'ai lue quand je suis entrée dans l'unité a été ce tutoriel. Le problème est que la sensation de contrôle est assez mauvaise. C'est pourquoi j'ai voulu trouver ma propre solution. D'un autre côté, lorsque vous commencez à utiliser Transform.Translate (), ce n'est pas si facile de faire des pentes et d'autres choses. Vous devez lancer le lancer plusieurs fois (2 ou 3 pour le sol, plus pour la direction dans laquelle vous vous déplacez en fonction de la taille du héros). Pour les appareils mobiles, le raycast n'est pas bon, et moins si vous devez faire 5..n par itération de détection de collision. Je pourrais peut-être me tromper, mais je ne pense pas.
Notbad
1

Ce que vous voulez, c'est le contrôleur de caractères intégré . En définissant la step offsetpropriété sur ce composant, vous pouvez demander à un joueur de monter et descendre des pentes avec facilité.

NoobsArePeople2
la source
Désolé de ne pas avoir commenté j'ai su qu'il y a un contrôleur de personnage dans l'unité et que je l'ai utilisé plusieurs fois, mais je n'aime pas comment il se comporte. Il convient mieux à FPS et non à un jeu de plateforme où la mécanique du mouvement est l'une des choses les plus importantes.
Notbad
Je pense qu'une fois que vous avez manipulé les paramètres du contrôleur de caractères, cela fonctionne bien. Qu'avez-vous trouvé manquant?
NoobsArePeople2
La première chose que je n'aime pas, c'est qu'il est lent par rapport aux corps rigides habituels avec un lancer de rayons. Sachant comment y parvenir, je pense que je pourrais faire un contrôleur plus léger. Un autre problème est que le comportement étrange de la capsule / sphère sur les bords de la plate-forme (il peut être résolu avec quelques lancers de rayons supplémentaires). C'est pourquoi je veux rouler le mien.
Notbad
0

entrez la description de l'image iciJe suppose que c'est parce que la force n'est pas parallèle à la plate-forme et le résultat finit par être plus faible en montée et plus en descente.

Si vous appliquez une force relative au système de coordonnées

AddRelativeForce

Vous voulez garder une vitesse maximale en "x" et la comparer à un scalaire, rappelez-vous que la vitesse est un vecteur et composez vx et vy, en terrain plat, vy est nul, mais nécessairement sur les pentes est supérieur à zéro.

La vitesse change selon la direction du corps, et sa vx relative change par rapport à sa vx globale

Cela peut modifier votre V d'une manière que vous ne voulez pas trop:

if (Mathf.Abs (v.x)> _ maxWalkSpeed) v.x = _maxWalkSpeed;

le maintien du même Vx global peut sembler étrange à l'œil nu. (Accélérations indésirables)

NorbyAriel
la source