Find Position of Destroying Object ?
Hello, I want to take a text to a position of the collectible that player just take.
The collectible object is destroying after player is collecting them, so how can I achieve this effect?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Collectibles : MonoBehaviour {
public static int scoreValue;
public bool alreadyScored;
public float spawnX, spawnY;
void Start()
{
spawnX = transform.position.x;
spawnY = transform.position.y;
}
void OnTriggerEnter2D (Collider2D col) {
if (col.gameObject.layer == LayerMask.NameToLayer ("Player")) {
if (alreadyScored)
return;
alreadyScored = true;
ScoreManager.score += scoreValue;
ScoreManager.collected = true;
} else {
ScoreManager.collected = false;
}
}
}
Answer by Harinezumi · Feb 15, 2018 at 08:34 AM
Pass to ScoreManager the position of the Collectible that is being picked up, and instantiate a game object (probably a prefab) with Text component on it at that position (this function will help you position the Text correctly). Then you can Destroy() your Collectible.
2 questions though:
- what is the purpose of scoreValue being static? Put in a different way, why do all the Collectibles need to share this variable?
- what is the purpose of ScoreManager.collected? Doesn't alreadyScored provide the same functionality, but better?
Okay, I get the Idea, but how to instantiate the object? I never don't deal with that actually. Can you show some example of the code please?
1) i added static to have access from another script 2)Score$$anonymous$$anager.collected is for my another script, where is my ScoreText is scaling when I collected the Collectibles
You instantiate an object using Instantiate(objectPrototype);
, where objectPrototype has to be a Unity object (see the scripting reference for examples).
In your case, you need to add this to your Score$$anonymous$$anager:
[SerializeField] private Canvas uiCanvas = null; // assign to this the Canvas of your UI
[SerializeField] private Text scoreTextPrefab = null; // assign to this a prefab with Text on it
public void OnCollecting(Vector3 collectiblePosition) {
Text textInstance = Instantiate(scoreTextPrefab);
textInstance.transform.SetParent(uiCanvas.transform);
textInstance.transform = Camera.main.WorldToScreenPoint(collectiblePosition + Vector3.up);
// store your new text instance in Score$$anonymous$$anager and Destroy() it when you don't need it anymore. Alternatively, you can call Destroy(textInstance.gameObject, delay);
}
About the questions for using static:
- you don't need static to access from another class, you need public. For example, you could pass your whole Collectible object to Score$$anonymous$$anager using the this
keyword, and Score$$anonymous$$anager can get from the passed Collectible using collectible.scoreValue its value
- ins$$anonymous$$d of your other script, ScoreText accessing Score$$anonymous$$anager.collected for control of scaling, why not make Score$$anonymous$$anager tell ScoreText whenever something was collected? In fact, the nicest would be if ScoreText were on your prefab with Text, and Score$$anonymous$$anager just told it to be created, and ScoreText destroyed itself automatically after a few seconds. This way there is less interdependency, less chance of bugs ;)
Something like this? (I have added your script to it). I added UI and TextPrefab but nothing seems to change
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using T$$anonymous$$Pro;
public class Score$$anonymous$$anager : $$anonymous$$onoBehaviour {
Animator anim;
public static int score;
private float m_smoothScore;
private float m_smoothScoreVelocity;
private int m_displayedScore = -1;
Text$$anonymous$$eshProUGUI text;
//Text$$anonymous$$eshPro worldText;
public static bool collected;
public float $$anonymous$$;
public float max;
public float t;
[SerializeField] private Canvas uiCanvas = null;
[SerializeField] private Text$$anonymous$$eshPro scoreTextPrefab = null;
void Awake()
{
text = GetComponent<Text$$anonymous$$eshProUGUI> ();
score = 0;
}
void Start()
{
anim = GetComponent<Animator> ();
collected = false;
}
void Update () {
//smooth score animation
m_smoothScore = $$anonymous$$athf.SmoothDamp(m_smoothScore,(float)score,ref m_smoothScoreVelocity, 0.2f, $$anonymous$$athf.Infinity, Time.deltaTime * 1.2f);
//display the text
int toDisplay = (int)$$anonymous$$athf.Round(m_smoothScore);
if (toDisplay != m_displayedScore)
{
m_displayedScore = toDisplay;
text.text = toDisplay + " PTS";
}
if (score > 0)
{
anim.SetBool ("Points", true);
}
if (collected == true) {
t = Time.time;
text.fontSize = $$anonymous$$athf.Lerp ($$anonymous$$, max, t);
collected = false;
} else {
t = Time.time;
text.fontSize = $$anonymous$$athf.Lerp (max, $$anonymous$$, t);
}
}
public void OnCollecting(Vector3 collectiblePosition)
{
Text$$anonymous$$eshPro worldText = Instantiate (scoreTextPrefab);
worldText.transform.SetParent (uiCanvas.transform);
worldText.transform.position = Camera.main.WorldToScreenPoint (collectiblePosition + Vector3.up);
}
}
1 answer) I understood that, and remove static) 2) it sounds great, but I dont really understand how to achieve this :)