Creare Videogiochi - Game Developer
Crouch script - Versione stampabile

+- Creare Videogiochi - Game Developer (https://www.making-videogames.net/giochi)
+-- Forum: Unity3D Italia (https://www.making-videogames.net/giochi/Forum-Unity3D-Italia)
+--- Forum: Richieste di Aiuto per Unity 3D (https://www.making-videogames.net/giochi/Forum-Richieste-di-Aiuto-per-Unity-3D)
+--- Discussione: Crouch script (/thread-Crouch-script)



Crouch script - 93sunderland - 07-04-2016

Ho provato a creare uno script per permettere l'abbassamento del player, cioè il crouching, e questo script l'ho allegato al mio CharacterController.

Codice:
using UnityEngine;
using System.Collections;

public class PlayerCrouching : MonoBehaviour {

    public float crouchHeight = 0.75F;
    public float crouchSlowness = 0.75F;

    private Vector3 standUpPosition;
    private Vector3 crouchPosition;
    private Vector3 crouchingVelocity;

    void Awake ()
    {
        standUpPosition = transform.localScale;
        crouchPosition = transform.localScale;
        crouchPosition.y = crouchHeight;
    }
   

    void FixedUpdate ()
    {
        Vector3 targetPosition;

        if (Input.GetButton ("Crouch"))
        {
            targetPosition = crouchPosition;
        }
        else
        {
            targetPosition = standUpPosition;
        }

        transform.localScale = Vector3.SmoothDamp (transform.localScale, targetPosition, ref crouchingVelocity, (crouchSlowness / 10.0F));
    }
}

Lo script funziona, però crea dei movimenti un po' rozzi: praticamente quando premo il tasto "Crouch" il CharacterController diminuisce la propria dimensione, tuttavia nel momento di ritornare alla dimensione di partenza, ovvero in piedi, si fa sentire l'effetto delle gravità e quindi il ridimensionamento avviene vibrando. E' un po' brutto da vedere quindi vorrei sapere se qualcuno sa come risolvere questo inconveniente.


RE: Crouch script - Blackg96 - 08-04-2016

Codice:
variabili :
private float charHeight;
private float h;
private Vector3 pos;
public CharacterController charCont;
public float speedToCrouch = 18;


funzione :
if(Input.GetKey(KeyCode.C)) h = 1;
else h = 2;

float lastHeight = charCont.height;
charCont.height = Mathf.Lerp(charCont.height, h, Time.deltaTime * speed);
pos.x = charCont.transform.position.x;
pos.z = charCont.transform.position.z;
pos.y = charCont.transform.position.y + (charCont.height - lastHeight) / 2;
charCont.transform.position = pos;
Dimmi se ti dà qualche problema Smile


RE: Crouch script - 93sunderland - 09-04-2016

Grazie mille, il tuo script mi è stato di grande aiuto... metto il mio script finale:

Codice:
using UnityEngine;
using System.Collections;

public class PlayerCrouching : MonoBehaviour {

    public float crouchHeight = 1.6F;
    public float crouchSpeed = 20.0F;
    public static float standUpHeight = 2.6F;

    public bool crouching = false;
    public bool showDisplay = false;

    public CharacterController controller;

    private Vector3 position;

    private float height;

    private bool cannotCrouch;

    void Awake ()
    {
        controller.height = standUpHeight;
    }

    void FixedUpdate ()
    {
        if (Input.GetButton ("Crouch"))
        {
            height = crouchHeight;
        }
        else if (!Input.GetButton ("Crouch") && cannotCrouch == false)
        {
            height = standUpHeight;
        }

        float lastHeight = controller.height;
        controller.height = Mathf.Lerp (controller.height, height, crouchSpeed * Time.deltaTime);

        position.x = controller.transform.position.x;
        position.z = controller.transform.position.z;
        position.y = controller.transform.position.y + (controller.height - lastHeight) / 2.0F;
        controller.transform.position = position;

        if (controller.height >= (standUpHeight - 0.05F))
        {
            crouching = false;
        }
        else
        {
            crouching = true;
        }
    }

    public void ConstrainCrouch ()
    {
        if (crouching == true)
        {
            cannotCrouch = true;
        }
        else
        {
            cannotCrouch = false;
        }
    }

    public void FreeCrouch ()
    {
        cannotCrouch = false;
    }
        
    void OnGUI()
    {
        if (showDisplay == true)
        {
            GUI.Box (new Rect (10, 80, 150, 45), "Player Height");
            GUI.Label (new Rect (20, 100, 150, 25), "Height " + controller.height);
        }
    }
}

Adesso il problema di prima è sparito, ma ce n'è un altro: quando l'altezza del personaggio diminuisce, ovviamente tutti i GameObject imparentati con lui si muoveranno. Purtroppo la MainCamera attaccata al personaggio si muoverà di meno rispetto al personaggio stesso, quindi ne risulterà che la MainCamera, mentre si è accovacciati, sarà al di sopra della testa. Quindi vorrei capire un modo per poter muovere la MainCamera in modo "uguale" rispetto al personaggio.


RE: Crouch script - Blackg96 - 09-04-2016

Dovresti spostare la MainCamera attraverso un Lerp in una posizione stabilita da te Smile


RE: Crouch script - 93sunderland - 09-04-2016

c'ho provato ma non ci riesco: ho provato a introdurre nello stesso script la MainCamera e definire due localPosition, ovvero una di partenza quando è in piedi e una di arrivo quando è accovacciato.
Non capisco perchè ma non funziona e credo che il problema sia questa stringa

Codice:
mainCamera.transform.localPosition = cameraPosition;

dove:
- mainCamera è il nome della MainCamera precedentemente chiamata da un GameOject.Find
- cameraPosition è il nome di un Vector3 precedentemente nominato al di fuori del void

il Lerp funziona, infatti il valore cameraPosition.y varia senza problema, ma la MainCamera rimane sempre nella sua posizione di partenza


RE: Crouch script - Blackg96 - 10-04-2016

Allora penso che il problema sia legato al fatto che ci sono più script/linee di codice che interagiscono sulla posizione della main camera. Tu non devi far altro che questo :

mainCamera.transform.localPosition = Vector3.Lerp(mainCamera.transform.localPosition, camCrouchPos, speed * Time.deltaTime);

Prova ad usare questo e controlla che non ci sia nient'altro che interagisca sulla posizione della maincamera.


RE: Crouch script - 93sunderland - 10-04-2016

forse ho capito il problema: la MainCamera possiede un'animazione che, dopo aver attivato un trigger, essa si muoverà in un determinato modo. Secondo alcune mie esperienze su Unity ho capito che se un GameObject possiede delle animazioni, che magari normalmente sono solo animation_idle, non riuscirà a muoversi nemmeno sotto comando via script.
Sinceramente non so perchè ma sicuramente ci sarà qualcosa che stia ignorando... per caso tu ne sai qualcosa?

EDIT: ho provato e ho avuto conferma che quello che ho scritto qua sopra è vero, quindi ho pensato di disattivare l'animator (e riattivarlo solo quando mi interessa l'animazione) ma c'è un problema, ovvero la telecamera è totalmente in un'altra posizione rispetto a prima.


RE: Crouch script - Blackg96 - 10-04-2016

Bhè allora ti conviene gestirtela ad animazioni secondo me, invece di fare un lerp, fai che la main camera con un anim si sposta nella posizione del crouch Smile


RE: Crouch script - 93sunderland - 10-04-2016

RISOLTO

ti faccio vedere lo script finale... benché sembri molto confusionario in verità sembra efficace

Codice:
using UnityEngine;
using System.Collections;

public class PlayerCrouching : MonoBehaviour {

    public float crouchHeight = 1.6F;
    public float crouchSpeed = 20.0F;
    public float crouchHead = 0.1F;

    public bool crouching = false;
    public bool showDisplay = false;

    public CharacterController controller;
    public Camera fpsCamera;

    private Vector3 position;
    private Vector3 cameraPosition;

    private float height;
    private float cameraHeight;
    private static float standUpHeight = 2.6F;
    private static float standUpHead = 0.3F;

    private bool cannotCrouch;

    void Awake ()
    {
        controller.height = standUpHeight;

        cameraPosition.y = standUpHead;
    }

    void FixedUpdate ()
    {
        if (!GetComponent<PlayerMovement> ().playerBlocked)
        {
            if (Input.GetButton ("Crouch"))
            {
                height = crouchHeight;
                cameraHeight = crouchHead;
            }
            else if (!Input.GetButton ("Crouch") && cannotCrouch == false)
            {
                height = standUpHeight;
                cameraHeight = standUpHead;
            }

            float lastHeight = controller.height;
            controller.height = Mathf.Lerp (controller.height, height, crouchSpeed * Time.deltaTime);
            cameraPosition.y = Mathf.Lerp (cameraPosition.y, cameraHeight, crouchSpeed * Time.deltaTime);

            position.x = controller.transform.position.x;
            position.z = controller.transform.position.z;
            position.y = controller.transform.position.y + (controller.height - lastHeight) / 2.0F;
            controller.transform.position = position;

            cameraPosition.x = fpsCamera.transform.localPosition.x;
            cameraPosition.z = fpsCamera.transform.localPosition.z;
            fpsCamera.transform.localPosition = cameraPosition;

            if (controller.height >= (standUpHeight - 0.05F))
            {
                crouching = false;
            }
            else
            {
                crouching = true;
            }
        }
    }

    public void ConstrainCrouch ()
    {
        if (crouching == true)
        {
            cannotCrouch = true;
        }
        else
        {
            cannotCrouch = false;
        }
    }

    public void FreeCrouch ()
    {
        cannotCrouch = false;
    }
        
    void OnGUI()
    {
        if (showDisplay == true)
        {
            GUI.Box (new Rect (10, 80, 150, 65), "Player Height");
            GUI.Label (new Rect (20, 100, 150, 25), "Height " + controller.height);
            GUI.Label (new Rect (20, 120, 150, 25), "Cam Height " + fpsCamera.transform.localPosition.y);
        }
    }
}



RE: Crouch script - Blackg96 - 11-04-2016

Benissimo, allora chiudo Smile