我正在学习Learn 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();
}
}
问题:
可以,但是我需要手动将文本(在画布下)附加到每个拾取对象,这很累,不是一件好事。
我想要实现的目标:
就像在教程中一样,大多数情况下,他们在这种工作中使用预制件(我认为),问题是我可以将文本附加到当前场景中的拾取器(对象/饼干)上,但不能将文本拖动并附加到饼干的预制件,我使文本不会附加在“文本”的空白处。
答案 0 :(得分: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;
}
}
}
但是请注意,如果使用不正确,单例模式可能是脚上的射击。对于管理人员,您应该只适当地使用它们。