Как я могу создать границу, используя только код C #? - PullRequest
0 голосов
/ 28 ноября 2018

Я пытаюсь создать сценарий единства, который определяет, когда игрок покинул определенную область, используя только код C # (без границ).Мой код должен воспроизводить звук после того, как проигрыватель выйдет, но код не работает должным образом, и я не вижу ошибки в логике.

Ожидаемое поведение

Когдаигрок выходит за границу, звук будет воспроизводиться один раз.

Фактическое поведение

Звук воспроизводится постоянно, независимо от того, где находится игрок.

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

public class EX2BoundaryDetect : MonoBehaviour {

    // create a GameObject to represent the player
    public GameObject playerObject;
    public bool leaveArea = false;

    // create an Audio-clip object. This assumes we drag a sound file onto the myclip box in the Inspector.
    public AudioClip myclip;

    // Use this for initialization
    void Start () {

        // associate playerObject with the player. This assumes the First Person Controller is name "player
        playerObject = GameObject.Find ("player");

        // get the actual Sound file from the Inspector
        GetComponent<AudioSource>().clip = myclip;

    }

    // Update is called once per frame
    void Update () {

        PlayAudio1();
        if (leaveArea) {
            GetComponent<AudioSource> ().Play ();
        }
    }

    public void PlayAudio1 () {

        // play the sound if the player is outside some boundaries

        if (transform.position.x > 10) {
            leaveArea = true;
        }

        if (transform.position.x < -29) {
            leaveArea = true;
        }

        if (transform.position.z > 10) {
            leaveArea = true;
        }

        if (transform.position.z < -29) {
            leaveArea = true;
        }

    }
}

Ответы [ 3 ]

0 голосов
/ 28 ноября 2018

Теперь все работает, добавив

leaveArea = false;

к методу Update.

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

public class EX2BoundaryDetect : MonoBehaviour {

    // create a GameObject to represent the player
    public GameObject playerObject;
    public bool leaveArea = false;

    // create an Audio-clip object. This assumes we drag a sound file onto the myclip box in the Inspector.
    public AudioClip myclip;

    // Use this for initialization
    void Start () {

        // associate playerObject with the player. This assumes the First Person Controller is name "player
        playerObject = GameObject.Find ("player");

        // get the actual Sound file from the Inspector
        GetComponent<AudioSource>().clip = myclip;

    }

    // Update is called once per frame
    void Update () {

        PlayAudio1();
        if (leaveArea) {
            GetComponent<AudioSource> ().Play ();
        }

        leaveArea = false;
    }

    public void PlayAudio1 () {

        // play the sound if the player is outside some boundaries

        if (transform.position.x > 10) {
            leaveArea = true;
        }

        if (transform.position.x < -29) {
            leaveArea = true;
        }

        if (transform.position.z > 10) {
            leaveArea = true;
        }

        if (transform.position.z < -29) {
            leaveArea = true;
        }



    }
}
0 голосов
/ 28 ноября 2018

Я думаю, что приведенные выше ответы по-прежнему не решают вашу проблему «Когда игрок выходит за границы, звук будет играть один раз.»

Я поделюсь более чистым способомделать это (возможно, оптимизировать)

Использование границ

Создать наши собственные границы с помощью Bounds https://docs.unity3d.com/ScriptReference/Bounds.html

Конструктор Boundsравно Bounds(Vector3 center,vector3 size)

Таким образом, в вашем случае центр будет center = (-9.5f, 0, -9.5f) (формула средней точки) и, наконец, размер ограничивающей рамки будет size = (39.0f, 0f, 39.0f)

Давайте перейдем к части кода

public class BoundsCheck: MonoBehaviour
{
    public bool isInside = false;
    public bool isPlayedOnce = false;
    private Bounds bounds;

    void Start()
    {
        bounds = new Bounds(new Vector3(-9.5f, 0, -9.5f), new Vector3(39.0f, 0f, 39.0f));
    }


    void Update()
    {
        CheckBounds();// play the sound if the player is outside some boundaries
        if (!isInside &&!isPlayedOnce)
        {
            Debug.Log("PLAY");
            isPlayedOnce = true;
        }
    }

    private void CheckBounds()
    {


        bool isInsideBound = bounds.Contains(transform.position);
        if (isInsideBound)
        {
            isInside = true;
            if (isPlayedOnce)
            {
                isPlayedOnce = false;
            }
        }
        else
        {
            isInside = false;
        }
    }
}

Таким образом, вместо нескольких if, мы можем просто проверить, находится ли позиция преобразования внутри границы, используя bool isInsideBound = bounds.Contains(transform.position);

Примечание: - Для воспроизведения звука только один раз, я использовал еще один логический isPlayedOnce

Я не уверен, является ли это наиболее оптимизированным способом сделать это.Но, безусловно, более чистый способ (через код).

0 голосов
/ 28 ноября 2018

leaveArea устанавливается только на false в определении класса.Установив значение true, оно никогда не может быть снова установлено на false, и оно может быть непреднамеренно перезаписано в определении сцены.

Чтобы устранить эту проблему, установите значение false.в начале Update:

void Update () {

    leaveArea = false;
    PlayAudio1();
    if (leaveArea) {
        GetComponent<AudioSource> ().Play ();
    }
}

Кроме того, GetComponent является дорогостоящим действием, и лучше не называть его в Update, где это возможно.Поэтому вы можете захотеть переместить его в свойство класса и установить его один раз в Start:

private AudioSource audioSource;

void Start () {

    // associate playerObject with the player. This assumes the First Person Controller is name "player
    playerObject = GameObject.Find ("player");

    audioSource = GetComponent<AudioSource>();

    // get the actual Sound file from the Inspector
    audioSource.clip = myclip;

}

// Update is called once per frame
void Update () {

    leaveArea = false;
    PlayAudio1();
    if (leaveArea) {
        audioSource.Play ();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...