我是 Unity 的初學者,目前正在制作一個簡單的游戲。我有一個問題,按鈕應該重新出現在我正在接觸的物件上。它僅顯示在我放置腳本的第一個物件上。
我想做的是有一個可回收的按鈕,只要我接觸到大多數游戲中的“查看”按鈕等物件,它就會出現。在我的專案中不斷發生的事情是觸發了碰撞,但物件的位置在我放置腳本以將其設定為活動并設定位置的第一個物件中。我將它放在另一個物件中,因為我希望按鈕顯示在該物件中,但它一直出現在第一個物件中。
這是我使用的腳本:
using UnityEngine;
using UnityEngine.UI;
public class InteractNPC : MonoBehaviour
{
//public Button UI;
[SerializeField] GameObject uiUse, nameBtn, dialogBox;
[SerializeField] TextAsset characterData;
// [SerializeField] UnityEngine.UI.Text dialogMessage;
private Transform head;
private Vector3 offset = new Vector3(0, 1.0f, 0);
// Start is called before the first frame update
void Start()
{
//uiUse = Instantiate(UI, FindObjectOfType<Canvas>().transform).GetComponent<Button>();
uiUse.gameObject.SetActive(true);
head = this.transform.GetChild(0);
uiUse.transform.position = Camera.main.WorldToScreenPoint(head.position offset);
nameBtn.transform.position = Camera.main.WorldToScreenPoint(head.position offset);
nameBtn.GetComponent<Button>().onClick.AddListener(onNameClick);
}
// Update is called once per frame
void Update()
{
uiUse.transform.position = Camera.main.WorldToScreenPoint(head.position offset);
nameBtn.transform.position = Camera.main.WorldToScreenPoint(head.position offset);
}
private void OnTriggerEnter(Collider collisionInfo)
{
if (collisionInfo.CompareTag("Player"))
{
//Character characterJson = JsonUtility.FromJson<Character>(characterData.text);
nameBtn.gameObject.SetActive(true);
// Text lbl = nameBtn.gameObject.GetComponentInChildren(typeof(Text), true) as Text;
// lbl.text = "BOBO";
// nameBtn.GetComponent<Button>().GetComponentInChildren<Text>().text = characterJson.name;
}
}
private void OnTriggerExit(Collider collisionInfo)
{
if (collisionInfo.CompareTag("Player"))
{
nameBtn.gameObject.SetActive(false);
}
}
// DIALOGUE SYSTEM
public void onNameClick()
{
Text dialogMessage, dialogName;
if (dialogBox.gameObject.activeInHierarchy)
{
dialogName = GameObject.Find("Canvas/DialogBox/DialogueName").GetComponent<Text>();
dialogMessage = GameObject.Find("Canvas/DialogBox/Dialogue").GetComponent<Text>();
if (dialogMessage != null && dialogName != null)
{
loadCharacterData(dialogMessage, dialogName);
Debug.Log("not null dialog message");
}
else
{
Debug.Log("null dialog message");
}
}
}
public void loadCharacterData(Text dialogMessage, Text dialogName)
{
Character characterJson = JsonUtility.FromJson<Character>(characterData.text);
dialogName.text = characterJson.name;
dialogMessage.text = characterJson.dialogs[0].choices[1];
}
}
uj5u.com熱心網友回復:
那么你的問題是你的腳本的每一個實體都會一直覆寫
void Update()
{
uiUse.transform.position = Camera.main.WorldToScreenPoint(head.position offset);
nameBtn.transform.position = Camera.main.WorldToScreenPoint(head.position offset);
}
每一幀。
你想要的只是設定一次
[SerializeField] private Button nameBtn;
pivate Character character;
private void Start()
{
...
// do this only once!
character = JsonUtility.FromJson<Character>(characterData.text);
}
private void OnTriggerEnter(Collider collisionInfo)
{
if (collisionInfo.CompareTag("Player"))
{
nameBtn.gameObject.SetActive(true);
var lbl = nameBtn.gameObject.GetComponentInChildren<Text>(true);
lbl.text = characterJson.name;
var position = Camera.main.WorldToScreenPoint(head.position offset);
uiUse.transform.position = position;
nameBtn.transform.position = position;
}
}
此外,您還會遇到另一個問題:腳本的每個實體都附加一個回呼
nameBtn.GetComponent<Button>().onClick.AddListener(onNameClick);
這是不好的!現在,每當您單擊一次按鈕時,都會為腳本的每個實體觸發 allback。
您寧愿僅在實際為當前物件呼叫單擊時才執行此操作。
為此,您可以在需要時僅附加監聽器,例如
private void OnTriggerEnter(Collider collisionInfo)
{
if (collisionInfo.CompareTag("Player"))
{
...
nameBtn.onClick.RemoveListener(onNameClick);
nameBtn.onClick.AddListener(onNameClick);
}
}
private void OnTriggerExit(Collider other)
{
if (collisionInfo.CompareTag("Player"))
{
nameBtn.onClick.RemoveListener(onNameClick);
nameBtn.gameObject.SetActive(false);
}
}
好的,在您的物體移動之前我們不知道
很好,您將需要回到以前的狀態并不斷更新位置,但僅當您是當前活動物件時,例如
private static InteractNPC buttonOwner;
private Camera mainCamera;
void Update()
{
if(buttonOwner != this) return;
if(!mainCamera) mainCamera = Camera.main;
var position = mainCamera.WorldToScreenPoint(head.position offset);
uiUse.transform.position = position;
nameBtn.transform.position = position;
}
private void OnTriggerEnter(Collider collisionInfo)
{
if (collisionInfo.CompareTag("Player") && !buttonOwner)
{
...
buttonOwner = this;
}
}
private void OnTriggerExit(Collider other)
{
if (collisionInfo.CompareTag("Player") && buttonOwner == this)
{
nameBtn.onClick.RemoveListener(onNameClick);
nameBtn.gameObject.SetActive(false);
buttonOwner = null;
}
}
uj5u.com熱心網友回復:
據我所知,您永遠不會創建新按鈕,我猜 Unity 可能會認為,您希望所有 NPC 上都使用相同的按鈕。
也許嘗試在 Start 方法中為新按鈕呼叫建構式,然后查看它是否會為每個 NPC 生成一個新按鈕。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/511258.html
標籤:C#unity3d按钮
下一篇:如何指定通道來設定權限?
