【问题标题】:Unity 3D Attaching Score Display Script to prefabUnity 3D 将乐谱显示脚本附加到预制件
【发布时间】:2018-07-16 20:47:59
【问题描述】:

我在学习 Unity 网站上关注 Unity 3d 教程,但这是我想做的事情有点不同。一开始效果很好,但最后结果证明这是一个糟糕的决定,现在我需要手动将脚本附加到每个可选取的对象上。

这是我的代码: 注意:它的作用是旋转拾取器并在拾取器与球员球碰撞时显示得分。

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

public class PickUps : MonoBehaviour {

    public Vector3 Rotate;
    private int Score;
    public Text ScoreGUI;

    private void Start()
    {
        Rotate = new Vector3(0, 25, 0);
        Score = 0;
        DisplayScore();

    }
    void Update () {
        transform.Rotate(Rotate*Time.deltaTime);
    }
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("Ball"))
        {
            Destroy(this.gameObject);
            Score = Score + 1;
            DisplayScore();
        }
    }
    void DisplayScore()
    {
        ScoreGUI.text = "SCORE " + Score.ToString();
    }
}

问题:

可以,但是我需要手动将文本(在画布下)附加到每个拾取对象上,这很累,而且不是一件好事。

我想要达到的目标:

就像在教程中一样,他们在这种工作中大多使用预制件(我认为),问题是我可以将文本附加到当前场景中的拾音器(对象/饼干),但我无法将文本拖放到我制作的饼干预制件只是不会在“文本”的空白处附加。

【问题讨论】:

  • 不能把预制件的Text组件拖到预制件的ScoreGUI字段中吗?
  • 每个 PickUp 都有自己的文本?或者他们都使用相同的文本?
  • @FredrikWiderberg 不,我不能那样做。
  • @NathaliaSoragge 否 文本是我销毁或禁用拾取应更新的文本时的分数 请参阅图像imgur.com/a/qp7Umpq
  • 您不能将场景对象分配给预制件的字段,因为当它被实例化时,该对象可能不存在。你可能会说“它当然会存在!”但事情是这样的:Unity 不知道,也无法知道。

标签: c# user-interface unity3d


【解决方案1】:

您不应直接更改分数Text。改用Controller 来制作桥接器。我会这样做:

将此脚本放在场景中的某个位置:

public class ScoreManager : Singleton<ScoreManager>
{
    private int score = 0;

    // Event that will be called everytime the score's changed
    public static Action<int> OnScoreChanged; 

    public void SetScore(int score)
    {
        this.score = score;
        InvokeOnScoreChanged();
    }

    public void AddScore(int score)
    {
        this.score += score;
        InvokeOnScoreChanged();
    }

    // Tells to the listeners that the score's changed
    private void InvokeOnScoreChanged()
    {
        if(OnScoreChanged != null)
        {
            OnScoreChanged(score);
        }
    }
}

此脚本附加在Text 游戏对象中:

[RequireComponent(typeof(Text))]
public class ScoreText : MonoBehaviour
{
    private Text scoreText;

    private void Awake()
    {
        scoreText = GetComponent<Text>();
        RegisterEvents();
    }

    private void OnDestroy()
    {
        UnregisterEvents();
    }

    private void RegisterEvents()
    {
        // Register the listener to the manager's event 
        ScoreManager.OnScoreChanged += HandleOnScoreChanged; 
    }

    private void UnregisterEvents()
    {
        // Unregister the listener
        ScoreManager.OnScoreChanged -= HandleOnScoreChanged;
    }

    private void HandleOnScoreChanged(int newScore)
    {
        scoreText.text = newScore.ToString();
    }
}

在您的 PickUps 课程中:

void DisplayScore()
{
    ScoreManager.Instance.SetScore(Score); // Maybe what you need is AddScore to not 
                                           // reset the value everytime
}

一个你可以使用的简单单例(你可以在互联网上找到更完整的):

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    static T instance;

    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = (T)FindObjectOfType(typeof(T));

                if (instance == null) Debug.LogError("Singleton of type " + typeof(T).ToString() + " not found in the scene.");
            }

            return instance;
        }
    }
}

但是要小心,如果使用不当,单例模式可能会被击中。您应该只为经理适度地使用它们。

【讨论】:

    猜你喜欢
    • 2022-12-16
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 2016-02-09
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多