Problem ze skalowaniem

Programowanie w Unity.

Problem ze skalowaniem

Postprzez DoktorGold » 08 Lip 2019, 14:09

Witam wszystkich bardzo serdecznie;)
Ostatnio zaczalem swoja przygode z Unity i mam taki malutki kłopocik

Kiedy skaluje rozmiar obiektu w dół wszystko jest ok
Problem pojawia sie dopiero po powiekszeniu obiektu a konkretnie skakanie jest niemozliwe.
Winny kryje sie w skrypcie Ball (odpowiadajacym za sterowanie) a konkretnie w tym oto wierszu

private float k_GroundRayLength = 1f;

Czy jest mozliwosc odwolania sie do tej zmiennej z innego skryptu konkretnie (BigMe)?Chce aby po kolizji obiekt sie zwiekszyl i móc zmienić k_GroundRayLength = 1f; na przyklad na 4f

Ponizej dolaczam oba skrypty


Ball
Kod: Zaznacz wszystko
using System;
using UnityEngine;

namespace UnityStandardAssets.Vehicles.Ball
{
    public class Ball : MonoBehaviour
    {
        [SerializeField] private float m_MovePower = 5; // The force added to the ball to move it.
        [SerializeField] private bool m_UseTorque = true; // Whether or not to use torque to move the ball.
        [SerializeField] private float m_MaxAngularVelocity = 25; // The maximum velocity the ball can rotate at.
        [SerializeField] private float m_JumpPower = 2; // The force added to the ball when it jumps.

        private float k_GroundRayLength = 1f; // The length of the ray to check if the ball is grounded.
        private Rigidbody m_Rigidbody;


        private void Start()
        {
            m_Rigidbody = GetComponent<Rigidbody>();
            // Set the maximum angular velocity.
            GetComponent<Rigidbody>().maxAngularVelocity = m_MaxAngularVelocity;
        }


        public void Move(Vector3 moveDirection, bool jump)
        {
            // If using torque to rotate the ball...
            if (m_UseTorque)
            {
                // ... add torque around the axis defined by the move direction.
                m_Rigidbody.AddTorque(new Vector3(moveDirection.z, 0, -moveDirection.x)*m_MovePower);
            }
            else
            {
                // Otherwise add force in the move direction.
                m_Rigidbody.AddForce(moveDirection*m_MovePower);
            }

            // If on the ground and jump is pressed...
            if (Physics.Raycast(transform.position, -Vector3.up, k_GroundRayLength) && jump)
            {
                // ... add force in upwards.
                m_Rigidbody.AddForce(Vector3.up*m_JumpPower, ForceMode.Impulse);
            }
        }
    }
}

BigMe
Kod: Zaznacz wszystko
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BigMe: MonoBehaviour
{

    public float mass;
    public float massPlus;
    public Rigidbody rb;
    public float fieldOfView;
    public IEnumerator WaitForSeconds()

    {
       
      yield return new WaitForSeconds(10);
      transform.localScale -= new Vector3(4F, 4F, 4F);
      Camera.main.fieldOfView -= fieldOfView;
       mass -= massPlus;
    }



    IEnumerator OnTriggerEnter(Collider other)

    {


        if (other.gameObject.name == "BigMeBuff")/*jesli obiekt z ktorym zaszla kolizja to RollerBall to:opis funkcji ponizszej czyli zrestartuj lvl*/
        {

           
            transform.localScale += new Vector3(4F, 4F, 4F);
            mass += massPlus;
            Camera.main.fieldOfView += fieldOfView;
            yield return StartCoroutine(WaitForSeconds());
        }
        if (other.gameObject.name == "BigMeBuff(Clone)")/*jesli obiekt z ktorym zaszla kolizja to RollerBall to:opis funkcji ponizszej czyli zrestartuj lvl*/
        {
           

            transform.localScale += new Vector3(4F, 4F, 4F);
            mass += massPlus;
            Camera.main.fieldOfView += fieldOfView;
            yield return StartCoroutine(WaitForSeconds());
        }





    }
}
Ostatnio edytowany przez DoktorGold 10 Lip 2019, 00:02, edytowano w sumie 2 razy
DoktorGold
 
Posty: 7
Rejestracja: 01 Lip 2019, 03:08
Has thanked: 0 time
Been thanked: 0 time

Re: Problem ze skalowaniem

Postprzez Hostur » 09 Lip 2019, 09:11

Nie chce mi się tego czytać, używaj znaczników ['code']['/code'] bez cudzysłowów do wklejania kodu.
Nie dostawaj się z innego skryptu (oczywiście że się da) tylko uzależnij tę zmienną od skali obiektu.
Używasz teraz cudzego skryptu (tal składam), który tę zmienną miał dostosowaną do wielkości obiektu. Jeżeli więc masz defaultowo skalę 1,1,1 i długość raycasta 1 to wystarczy że zmienisz tę linijkę

Kod: Zaznacz wszystko
if (Physics.Raycast(transform.position, -Vector3.up, k_GroundRayLength) && jump)

na
Kod: Zaznacz wszystko
if (Physics.Raycast(transform.position, -Vector3.up, k_GroundRayLength * transform.localScale.x) && jump)


Jeśli chcesz to zrobić lepiej to cachuj tranforma
Kod: Zaznacz wszystko
...
private Transform _transform;
private void Start()
{
  ...
  _transform = transform;
}

...
if (Physics.Raycast(transform.position, -Vector3.up, k_GroundRayLength * _transform.localScale.x) && jump)
...


To jest zapewne wołane w pętli update więc lepiej unikać używania transform bezpośrednio ze względów wydajnościowych.


Jeśli chodzi o zmianę zmiennej na innym komponencie

Kod: Zaznacz wszystko
[SerializeField] private Ball _ball;
private void ChangeBallRaycast(float value)
{
  // Najpierw zmienić k_GroundRayLength  na public.
  _ball.k_GroundRayLength = value;
}


lub z gorszych praktyk programistycznych

Kod: Zaznacz wszystko
private void ChangeBallRaycastLength(float value)
{
  GameObject.FindObjectOfType<Ball>().k_GroundRayLength = value;
}


Jednak jeśli nie musisz wprowadzać zależności między komponentami to tego nie rób.
Jeżeli komponent może być samowystarczalny (jak poprzez skalowanie długości racyasta) to staraj się tak to rozwiązać.
Hostur
 
Posty: 720
Rejestracja: 05 Sie 2015, 07:36
Has thanked: 0 time
Been thanked: 0 time

Re: Problem ze skalowaniem

Postprzez DoktorGold » 10 Lip 2019, 01:07

A co jesli chcialbym odwrotnosc tego skryptu tj pomniejszenie obiektu,jednoczesnie bez zmniejszania tj skalowania skoku?Da sie to jakos optymalnie obejsc?
Czy dobrym pomyslem bedzie napisanie 3 skryptow i wlaczanie konkretnego w zaleznosci od skalowania a wylaczanie pozostalych?
DoktorGold
 
Posty: 7
Rejestracja: 01 Lip 2019, 03:08
Has thanked: 0 time
Been thanked: 0 time

Re: Problem ze skalowaniem

Postprzez Hostur » 10 Lip 2019, 06:07

Nie wiem dokładnie co chcesz osiągnąć ale domniemam, że zrobiłbym to w taki sposób aby logika siedziała w jednym obiekcie i w ramach możliwości żeby sam on zarządzał jej "przełączaniem" a jeśli nie byłoby to sensowne to przełączałbym ją z innego obiektu jednak wydaje mi się, że to Twój "Ball" powinien ustawiać długość swojego raycasta a jeśli potrzebujesz wywołać tę zmianę z zewnątrz to poprzez proste api

Kod: Zaznacz wszystko
public enum ScaleMode
{
  Default = 1,
  Big = 4,
  SomethingElse = ??,
  ...
}

public void ChangeScaleMode(ScaleMode mode)
{
  switch(mode)
  {
    ...
  }
}


I z zewnątrz tylko wywołujesz zmianę

Robienie trzech skryptów brzmi jak ta sama powielona logika ze zmienionymi parametrami
Hostur
 
Posty: 720
Rejestracja: 05 Sie 2015, 07:36
Has thanked: 0 time
Been thanked: 0 time

Re: Problem ze skalowaniem

Postprzez DoktorGold » 11 Lip 2019, 11:20

Hmm..Nie bardzo sie znam i nie wiem czy dobrze rozumiem.Podczas kolizji z konkretnym obiektem chce zmniejszyc obiekt gracza x10 czyli scale obiekt = 0.1 to
k_GroundRayLength tez = 0.1
Zrobilem to tak ale cos jest nie tak.

Kod: Zaznacz wszystko
using System;
using UnityEngine;

namespace UnityStandardAssets.Vehicles.Ball
{
    public class Ball : MonoBehaviour
    {
        [SerializeField] private float m_MovePower = 5; // The force added to the ball to move it.
        [SerializeField] private bool m_UseTorque = true; // Whether or not to use torque to move the ball.
        [SerializeField] private float m_MaxAngularVelocity = 25; // The maximum velocity the ball can rotate at.
        [SerializeField] private float m_JumpPower = 2; // The force added to the ball when it jumps.

        public float k_GroundRayLength = 1f; // The length of the ray to check if the ball is grounded.
        private Rigidbody m_Rigidbody;
        private Transform _transform;

   
        public enum ScaleMode
        {
            Default = 1,
            Big = 4,
            Small = 1/10,
           
        }
        public void ChangeScaleMode(ScaleMode k_GroundRayLength)
        {
            switch (k_GroundRayLength)
            {
                case 1/10:
                    1;
                    break;

            }
    }
    public void Start()
        {
            m_Rigidbody = GetComponent<Rigidbody>();
            // Set the maximum angular velocity.
            GetComponent<Rigidbody>().maxAngularVelocity = m_MaxAngularVelocity;
            _transform = transform;
    }


        public void Move(Vector3 moveDirection, bool jump)
        {

            // If using torque to rotate the ball...
            if (m_UseTorque)
            {
                // ... add torque around the axis defined by the move direction.
                m_Rigidbody.AddTorque(new Vector3(moveDirection.z, 0, -moveDirection.x)*m_MovePower);
            }
            else
            {
                // Otherwise add force in the move direction.
                m_Rigidbody.AddForce(moveDirection*m_MovePower);
            }

            // If on the ground and jump is pressed...
            if (Physics.Raycast(transform.position, -Vector3.up, k_GroundRayLength * transform.localScale.x) && jump)

            {
                // ... add force in upwards.
                m_Rigidbody.AddForce(Vector3.up*m_JumpPower, ForceMode.Impulse);

            }
        }
    }
}


Prosze powiedz gdzie popelniam bledy i jak to naprawic

Na ta chwile korzystam ze zlych praktyk bo dzialaja ale chce wiedziec jak robic to najbardziej optymalnie


Kod: Zaznacz wszystko
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.Vehicles.Ball;


public class SmallMe : MonoBehaviour
{

    public float fieldOfView;
    public IEnumerator WaitForSeconds()

    {

        yield return new WaitForSeconds(10);
        Camera.main.fieldOfView += fieldOfView;
        transform.localScale = new Vector3(1F, 1F, 1F);
        GameObject.FindObjectOfType<Ball>().k_GroundRayLength = 1;



    }



    IEnumerator OnTriggerEnter(Collider other)

    {


        if (other.gameObject.name == "SmallMeBuff")/*jesli obiekt z ktorym zaszla kolizja to RollerBall to:opis funkcji ponizszej czyli zrestartuj lvl*/
        {

            Camera.main.fieldOfView -= fieldOfView;
            transform.localScale = new Vector3(0.1F, 0.1F, 0.1F);
            GameObject.FindObjectOfType<Ball>().k_GroundRayLength = 10;
            yield return StartCoroutine(WaitForSeconds());
        }





    }
}
DoktorGold
 
Posty: 7
Rejestracja: 01 Lip 2019, 03:08
Has thanked: 0 time
Been thanked: 0 time

Re: Problem ze skalowaniem

Postprzez Hostur » 11 Lip 2019, 18:34

Jak chcesz floaty w enumie to zrób enum z dziesięciokrotnością a później dziel prze 10

Kod: Zaznacz wszystko
enum E
{
 a = 10,
 b = 40,
 c = 1,
}


Enum ma wartość integera i 1/10 Ci zaokrągli do 0 pewnie
Hostur
 
Posty: 720
Rejestracja: 05 Sie 2015, 07:36
Has thanked: 0 time
Been thanked: 0 time

Re: Problem ze skalowaniem

Postprzez Palanthir » 11 Lip 2019, 21:33

Jeśli nie potrzebujesz rotacji, to ustaw sobie pivot na dole i nie będziesz potrzebował żadnych wzorów.
Palanthir
 
Posty: 99
Rejestracja: 31 Sie 2017, 16:13
Has thanked: 0 time
Been thanked: 0 time


Wróć do Skrypty

Kto jest na forum

Użytkownicy przeglądający to forum: Brak zarejestrowanych użytkowników oraz 5 gości

cron