我在学习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
。使用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();
}
}
在你的皮卡课上:
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;
}
}
}
但是要小心,如果使用不正确,singleton模式可能是一记重拳。对于经理来说,你应该适度地对待他们。