You could simply check the distance of the coin to the player, however, you would need to store a record of each coin and iterate through each instance during each Update()
method, in order to check.
We will assume you have a static number of coins, and have pre-loaded them into an array. This is the most cost effective, in comparison to using a List
. If you dynamically add coins to the level, you will have to use a List<MoveCounTowardsPlayer>
, and add the coins to the list as they are created.
class MoveCoinTowardsPlayer : MonoBehaviour
{
public Transform target;
public float speed;
public bool isMoving = false;
void Update()
{
if(isMoving)
{
transform.position = Vector3
.MoveTowards(transform.position, target.position, speed * Time.deltaTime;
}
}
public void MoveToPlayer(Transform player)
{
target = player;
isMoving = true;
}
}
class Player : MonoBehaviour
{
///<summary>The array of coins available in the level.</summary>
public MoveCoinTowardsPlayer[] coin;
///<summary>The range within which the player will pick up coins.</summary>
public float pickupRange;
void Update()
{
for(int i = 0; i < coin.Length; i++)
{
if(coin[i] != null && Vector3
.Distance(transform.position, coin[i].transform.position) <= pickupRange)
{
// If the coin still references a valid object, and its distance to
// the player transform is within pickup range,
// start moving it towards the player.
coin[i].MoveToPlayer(transform);
}
}
}
}
All in all, the above solution seems like a waste of resources, given that it iterates through all coins during a single update. I would personally add a kinematic sphere collider (circle, if your working in 2D). You can make this collider the size of your pickup radius, and use collision to determine collection.
You would also need a collider on the coins, as well as a tag to identify them as coins.
class Player : MonoBehaviour
{
public string coinTag;
void OnTriggerEnter(Collider other)
{
if(other.tag == coinTag)
{
other.gameObject.GetComponent<MoveCoinTowardsPlayer>()
.MoveToPlayer(transform);
}
}
}