Creare Videogiochi - Game Developer

Versione completa: problema nei movimenti del personaggio
Al momento stai visualizzando i contenuti in una versione ridotta. Visualizza la versione completa e formattata.
salve, vorrei esporvi un problema che assolutamente non riesco a risolvere
ho creato un CharacterController su Unity nella quale ho inserito pure un RigidBody e un script creato da me per muoversi

Codice:
using UnityEngine;
using System.Collections;

public class PlayerMovement : MonoBehaviour {

    public float speed = 6.0F;
    public float jumpSpeed = 8.0F;
    public float gravity = 20.0F;
    public Camera fpsCamera;
    public bool playerBlocked = false;
    
    private Vector3 moveDirection = Vector3.zero;

    void Update()
    {
        if (playerBlocked == false)
        {
            CharacterController controller = GetComponent<CharacterController> ();
            if (controller.isGrounded)
            {
                moveDirection = new Vector3 (Input.GetAxis ("Horizontal"), 0, Input.GetAxis ("Vertical"));
                moveDirection = fpsCamera.transform.TransformDirection (moveDirection);
                moveDirection *= speed;
                if (Input.GetButton ("Jump"))
                {
                    moveDirection.y = jumpSpeed;
                }
            
            }
            moveDirection.y -= gravity * Time.deltaTime;
            controller.Move (moveDirection * Time.deltaTime);
        }
    }

    public void disableMovement ()
    {
        playerBlocked = true;
    }

    public void enableMovement ()
    {
        playerBlocked = false;
    }
}

però ho due problemi:
1) quando il personaggio salta e tocca il tetto, quest'ultimo non cade subito a terra ma rimane qualche decimo di secondo ancora in aria, come se la spinta del salto non fosse ancora terminata

2) quando fisso il pavimento con la telecamera e cammino all'indietro, anziché camminare il personaggio "saltella"


qualche consiglio?
Ciao, per risolvere il secondo problema basta che semplicemente elimini la riga:
Codice:
moveDirection = fpsCamera.transform.TransformDirection (moveDirection);
Per il primo la soluzione è leggermente più complessa.
Per prima cosa crea un tag e dagli un nome(io ad esempio ho messo "top"), ora metti questo nello script che ci hai postato:
Codice:
void OnControllerColliderHit(ControllerColliderHit hit)
    {
        if(hit.collider.tag == "Top")//se hai messo un altro tag mettilo qui
        {
            moveDirection.y = -moveDirection.y;
        }
    }
Ora seleziona il game object dove il player "sbatteva la testa" e gli selezioni il tag che hai appena creato.
per il secondo problema, se elimino quella riga allora non riesco più a far muovere il personaggio secondo la direzione della MainCamera
avevo pensato a un modo per poter costringere il movimento solamente lungo il piano orizzontale ma non ci sto riuscendo
sono riuscito a risolvere parzialmente il primo problema, quello delle collisioni

Codice:
void Update()
{
if (playerBlocked == false)
{
CharacterController controller = GetComponent<CharacterController> ();
           if (controller.isGrounded)
{
moveDirection = new Vector3 (Input.GetAxis ("Horizontal"), 0, Input.GetAxis ("Vertical"));
moveDirection = fpsCamera.transform.TransformDirection (moveDirection);
moveDirection *= speed;
if (Input.GetButton ("Jump"))
{
moveDirection.y = jumpSpeed;
}

}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move (moveDirection * Time.deltaTime);
           if (controller.collisionFlags == CollisionFlags.Above)
           {
               moveDirection.y = -moveDirection.y;
           }
}
}

ho messo la funzione collisionFlags che permette di discriminare solo le collisioni da un lato
ok, ho risolto quasi totalmente il problema delle collisioni mentre si salta, ecco lo script modificato
Codice:
using UnityEngine;
using System.Collections;

public class PlayerMovement : MonoBehaviour {

    public float speed = 6.0F;
    public float jumpSpeed = 8.0F;
    public float gravity = 20.0F;
    public Camera fpsCamera;
    public bool playerBlocked = false;
   public bool canJump = true;
   public float timeDelayJump = 0.5F;
    
    private Vector3 moveDirection = Vector3.zero;
   private bool isJumping = false;
   private IEnumerator coroutine;

   void Update()
    {
        if (playerBlocked == false)
        {
            CharacterController controller = GetComponent<CharacterController> ();
           if (controller.isGrounded)
            {
                moveDirection = new Vector3 (Input.GetAxis ("Horizontal"), 0, Input.GetAxis ("Vertical"));
                moveDirection = fpsCamera.transform.TransformDirection (moveDirection);
                moveDirection *= speed;
               if (Input.GetButton("Jump") && canJump == true)
               {
                    moveDirection.y = jumpSpeed;
                    isJumping = true;
               }
            }
            moveDirection.y -= gravity * Time.deltaTime;
            controller.Move (moveDirection * Time.deltaTime);
           if (controller.collisionFlags == CollisionFlags.Above)
           {
               moveDirection.y = 0;
               moveDirection.x = 0;
               moveDirection.z = 0;
           }
           if (isJumping == true)
           {
               if (controller.collisionFlags == CollisionFlags.Below)
               {
                   coroutine = delayFromJumping(timeDelayJump);
                   StartCoroutine(coroutine);
               }
           }
       }
    }
     
   public IEnumerator delayFromJumping(float timeDelayJump)
   {
       speed = speed / 2;
       canJump = false;
       isJumping = false;
       yield return new WaitForSeconds(timeDelayJump);
       speed = speed * 2;
       canJump = true;
       StopCoroutine(coroutine);
   }

   public void disableMovement ()
    {
        playerBlocked = true;
    }

    public void enableMovement ()
    {
        playerBlocked = false;
    }
}

scusate per il post multiplo ma non vorrei che il problema del movimento del personaggio venga dimenticato: quello non sono riuscito ancora a risolverlo
Ho risolto il problema del personaggio quando "saltellava" se guardavi il pavimento e camminavi all'indietro.
Crea un empty GameObject come child della camera e mettigli questo script(lo script si chiama "Lock.cs"):
Codice:
using UnityEngine;
using System.Collections;

public class Lock : MonoBehaviour {

    // Use this for initialization
    void Start () {
    
    }
    
    // Update is called once per frame
    void Update () {
        transform.eulerAngles=new Vector3(0,transform.eulerAngles.y,0);
    }
}
Ora invece dovrai modificare lo script del movimento del player(lo script "PlayerMovement.cs", che è quello che mi hai dato tu).
Per prima cosa crea questa variabile(ovviamente puoi assegnarli il nome che vuoi):
Codice:
public GameObject dir;

ora sostituisci questo:
Codice:
moveDirection = fpsCamera.transform.TransformDirection (moveDirection);
con questo:
Codice:
moveDirection = dir.transform.TransformDirection(moveDirection);
funzionaaaa
grazie mille zettamax
malgrado tutte queste soluzioni ho notato un altro problema
ritornando al discorso delle collisioni del personaggio, sono riuscito a sistemare parzialmente il problema con lo script che ho riportato in un post qua sopra, però solo oggi mi sono accorto di un altro problema: se io salto in messo alla stanza allora sarà tutto nella norma, me se io salto contro una parete, lasciando premuto il tasto per camminarci incontro, il personaggio non riuscirà totalmente a toccare terra, anzi, a volte mi capita che penetra nel muro per qualche secondo
qualche consiglio?
Secondo me non è un problema di script, ma di come sono stati disposti i gameObject.
Se devi fare un sistema di movimento semplice ecco un mio vecchio tutorial :
1- https://www.youtube.com/watch?v=Ymws95i2FxM
2- https://www.youtube.com/watch?v=zLIumWhrwIg (Non tutto il tutorial è dedicato al movimento, ma solo una parte)

(Spero non sia spam anche perchè non sto più nell'OnGame e quel canale è chiuso da un bel pezzo)

Vedi un pò se può esserti utile.
mi dispiace ma i video non mi danno informazioni utili, però se vuoi ti passo il file della mia Scene e puoi controllare se c'è qualcosa che non va
Va bene, passamelo e vediamo che posso fare
Allora, io non ho trovato nessuno dei problemi da te elencati Big Grin

Ho azzerato il near della camera, per quel bug che delle volte trapassa per un secondo il muro, poi i bug delle collisioni io non li noto boh, fammi sapere =)
prova a premere W e andare incontro una parete, e poi tieni premuto pure SPACE
per poter osservare meglio, tieni aperto le funzione del personaggio e vedrai che tra i parametri dello script PlayerMovement ce n'è uno che ti avvisa che puoi saltare (è un parametro che ho creato per essere sicuro che il personaggio tocchi terra per saltare) e si vede che resta attivato sempre