Jak naprawić te skrypty

Jak naprawić te skrypty
Adam Matuszek
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 9
0

Cześć otóż robię grę w unity. Planuję bardziej rozbudować tę produkcję ale nie do końca rozumiem C#. Na chwilę obecną potrzebuje pomocy w dopracowaniu systemu Double-Jumpa. Codzi o to że chcę aby po wjechaniu oraz zderzeniu się z Colliderami np jakiejś jakiejś monety uruchamiało to skrypt który doda do postaci umiejętność double-jumpa. Sam skok mam zaprogramowany ale nie wiem jak zmieniać jego wartość innym skryptem żeby właśnie z jednego skoku wartość zmieniała się na dwa skoki. Dorzucam kod do systemu poruszania się oraz do systemu tej monety.

Kopiuj
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ogcontrol : MonoBehaviour
{
    public float chodz;
    public float bieganie;
    private float aktual;
    public float mouseSens;
    public float jumpPlayer;
    private Rigidbody rb;
    private int jumpLeft = 2;

    private bool canJump;

    jddsped motor;



    void Start()
    {

        aktual = chodz;
        motor = GetComponent<jddsped>();
        rb = GetComponent<Rigidbody>();
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(KeyCode.LeftShift))
        {

            aktual = bieganie;

        }
        else if (Input.GetKeyUp(KeyCode.LeftShift))
        {
            aktual = chodz;
        }

  
        float _xMove = Input.GetAxisRaw("Horizontal");
        float _zMove = Input.GetAxisRaw("Vertical");
        Vector3 _moveHorizontal = transform.right * _xMove;
        Vector3 _moveVertical = transform.forward * _zMove;

        Vector3 _velocity = (_moveHorizontal + _moveVertical).normalized * aktual;


        motor.Move(_velocity);

        float _yRot = Input.GetAxisRaw("Mouse X");

        Vector3 _rotation = new Vector3(0, _yRot, 0) * mouseSens;



        motor.Rotate(_rotation);

        float _xRot = Input.GetAxisRaw("Mouse Y");

        Vector3 _cameraRotation = new Vector3(_xRot, 0, 0) * mouseSens;


        motor.RotateCamera(_cameraRotation);


        if (Input.GetKeyDown(KeyCode.Space) && jumpLeft > 0)
        {
            rb.AddForce(Vector3.up * jumpPlayer);
            jumpLeft--;
        }

    }

    private void OnCollisionEnter(Collision collision)
    {
 
        jumpLeft = 1;
    }

 


}
Kopiuj
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class punkt : MonoBehaviour
{

    void OnTriggerEnter(Collider collison)
    {


        Destroy(gameObject);
       

    }


}

Spine
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6968
0

Jeśli obiekt z komponentem gracza ogcontrol jest tylko jeden na scenie. To możesz z niego zrobić "Singleton" i raczej będzie to wydajniejsze, niż wywoływanie w triggerze punkt metody GetComponent, co możesz zrobić alternatywnie, żeby się dobrać do obiektu z komponentem ogcontrol.

Żeby zrobić Singleton, dodaj w ciele klasy ogcontrol:

public static ogcontrol instance;

W metodzie Start albo Awake dopisz:

instance = this;

Gotowe ;)

Teraz w klasie punkt, żeby się odnieść do tego obiektu, piszesz:

ogcontrol.instance.DoubleJumpActivate();

Oczywiście musisz zaimplementować taką publiczną metodę.

No i w OnCollisionEnter, jumpLeft zwiększasz o 2 jeślie DoubleJump jest aktywny.

Adam Matuszek
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 9
0

@Spine: Okej wygląda dobrze ale co w przypadku jeśli postać może znajdować się na kilku scenach ?

Spine
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6968
0

To musisz gdzieś zapisywać umiejętności gracza i w każdej scenie na początku musisz ładować to co gracz sobie odblokował.

Jeśli odblokowane umiejętności mają być dostępne w całej sesji gry i nie chcesz zapisywać żadnych danych na dysku, to możesz zrobić jakąś klasę ze zmiennymi statycznymi, które przechowują informacje niezależnie od obiektów załadowanych na scenie. Wtedy Twoja klasa gracza, triggery itp. wpływają na tą klasę statyczną i czytają z niej potrzebne dane w odpowiednich sytuacjach.

obscurity
  • Rejestracja: dni
  • Ostatnio: dni
0

Ogólnie unikaj statycznych klas i zmiennych - utwórz zwykłą klasę, przeciągnij jej instancję na instancję gracza jako zależność.
Używanie staticów później Cię zablokuje gdybyś chciał stworzyć grę multiplayer albo split-screen - będziesz musiał te wszystkie statiki przepisywać

Spine
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6968
1

@obscurity: I tak po zmianie sceny i ponownym załadowaniu obiektów, ten obiekt przeciągnięty na instancję gracza wraca do stanu pierwotnego...

Można zrobić zwykłą klasę na przyszłość, którą opisujesz i trzymać ją jako pole statyczne w innej klasie, żeby wszędzie był do tych danych dostęp...

Adam Matuszek
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 9
0

@Spine: Odnosząc się do pierwszej odpowiedzi
"Teraz w klasie punkt, żeby się odnieść do tego obiektu, piszesz:

ogcontrol.instance.DoubleJumpActivate();

Oczywiście musisz zaimplementować taką publiczną metodę.

No i w OnCollisionEnter, jumpLeft zwiększasz o 2 jeślie DoubleJump jest aktywny."

Nie do końca rozumiem jak mam to zrobić

Spine
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6968
0

@Adam Matuszek

  1. W ogcontrol piszesz nową metodę public DoubleJumpActivate() { ... }.
  2. W ogcontrol dodajesz nowe pole bool doubleJump = false;.
  3. W ciele metody DoubleJumpActivate piszesz doubleJump = true;
  4. Twój trigger:
Kopiuj
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class punkt : MonoBehaviour
{

    void OnTriggerEnter(Collider collison)
    {
        ogcontrol.instance.DoubleJumpActivate();
        Destroy(gameObject);
    }

}
  1. Twój OnCollisionEnter w ogcontrol
Kopiuj
    private void OnCollisionEnter(Collision collision)
    {
        if (doubleJump)
        {
                jumpLeft = 2;
        }
        else
        {
                jumpLeft = 1;
        }
    }

Domyślam, się, że TwójjumpLeft się resetuje w OnCollisionEnter dlatego, że wtedy gracz dotyka podłoża.


Jak zrobisz doubleJump globalnie/statycznie, to po prostu wszystkie odniesienia do niego pozmieniasz.

Adam Matuszek
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 9
0

@Spine: Zrobiłem to tak ale nie do końca wszystko działa ponieważ dostałem informacje o wielu błędach pewnie jest to moja wina ale nie wiem co tu poprawić, wiem moje zdolności programistyczne nie są wzorowe.

Kopiuj
public class ogcontrol : MonoBehaviour
{
    public float chodz;
    public float bieganie;
    private float aktual;
    public float mouseSens;
    public float jumpPlayer;
    private Rigidbody rb;
    private int jumpLeft = 2;
    public float ilosc;

    bool doubleJump = false;
   
    public DoubleJumpActivate()
    {
        doubleJump = true;
    }
}
Kopiuj
  private void OnCollisionEnter(Collision collision)
    {
        if (doubleJump)
        {
            jumpLeft = 2;
        }
        else
        {
            jumpLeft = 1;
        }
    }

Kopiuj
public class punkt : MonoBehaviour
{

    void OnTriggerEnter(Collider collison)
    {
        ogcontrol.instance.DoubleJumpActivate();
        Destroy(gameObject);
    }

}
Spine
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6968
0

A zrobiłeś to co Ci wcześniej napisałem?

Spine napisał(a):

Żeby zrobić Singleton, dodaj w ciele klasy ogcontrol:

public static ogcontrol instance;

W metodzie Start albo Awake dopisz:

instance = this;

Gotowe ;)

Adam Matuszek
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 9
0

@Spine: Tak zrobiłem to

Kopiuj
    public static ogcontrol instance;
Kopiuj
   void Start()
    {

        aktual = chodz;
        motor = GetComponent<jddsped>();
        rb = GetComponent<Rigidbody>();
        instance = this;
        
    }

błędy jakie mi się do tego wyświetlają to:
'ogcontrol' does not contain a definition for 'DoubleJumpActivate' and no accessible extension method 'DoubleJumpActivate' accepting a first argument of type 'ogcontrol' could be found (are you missing a using directive or an assembly reference?) i chodzi tu o skrypt "punkt"

Method must have a return type i chodzi tu o tą linijkie:

Kopiuj
 public DoubleJumpActivate()
    {
        doubleJump = true;
    }
Spine
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6968
1

No tak... mój błąd, ma być

public void DoubleJumpActivate()

zamiast

public DoubleJumpActivate()

Wybacz...

Adam Matuszek
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 9
1

@Spine: Faktycznie to było problemem, Dziękuje ci bardzo za pomoc już wszystko działa jak należy :D

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.