(2D) Collectible Objects using Raycasts

Hello fellow Unity users. :slight_smile:

I’ve completed the excellent series of tutorials here (2D Platformer Controller (Unity 5) - YouTube) and I’d like to add ‘collectible’ items to my prototype game.

This tutorial series develops a 2D platformer, whereby all collisions are worked out using raycasting (as opposed to rigid bodies / colliders). It works fine, but I’m not sure how to proceed so as when my player (a simple quad, currently) collides with another quad (tagged as ‘Pickup’) the other object is destroyed.

I tried this via the usual method of adding rigid bodies / box colliders and checking onTriggerEnter2D (after setting the relevant setting of ‘Is Trigger?’ to yes. But the event doesn’t ever appear to fire.

(Code Below: Controller2D)
using UnityEngine;
using System.Collections;

[RequireComponent (typeof (BoxCollider2D))]
public class Controller2D : MonoBehaviour {

	public LayerMask collisionMask;
	
	const float skinwidth = .015f; 
	public int horizontalRayCount = 4;
	public int verticalRayCount = 4;

	float horizontalRaySpacing;
	float verticalRaySpacing;


	BoxCollider2D coll;
	RaycastOrigins raycastOrigins;

	void Start () {
		coll = GetComponent<BoxCollider2D>();
		calculateRaySpacing();
	}
	
	public void Move(Vector3 velocity){
		UpdateRaycastOrigins();
		if (velocity.x != 0){
			HorizontalCollisions(ref velocity);
		}
		if (velocity.y !=0){
			VerticalCollisions(ref velocity);
		}
		transform.Translate(velocity);
	}

	void HorizontalCollisions(ref Vector3 velocity){
		float directionX = Mathf.Sign (velocity.x);
		float rayLength = Mathf.Abs(velocity.x) + skinwidth;
		
		for (int i = 0; i < horizontalRayCount; i++) {
			Vector2 rayOrigin = (directionX == -1)?raycastOrigins.bottomLeft:raycastOrigins.bottomRight;
			rayOrigin += Vector2.up * (horizontalRaySpacing * i);
			RaycastHit2D hit = Physics2D.Raycast(rayOrigin,Vector2.right * directionX,rayLength,collisionMask);

			Debug.DrawRay(rayOrigin, Vector2.right * directionX * rayLength,Color.red);

			if (hit) {
				velocity.x = (hit.distance - skinwidth) * directionX;
				rayLength = hit.distance;
			}
		}
	}

	void VerticalCollisions(ref Vector3 velocity){
		float directionY = Mathf.Sign (velocity.y);
		float rayLength = Mathf.Abs(velocity.y) + skinwidth;

		for (int i = 0; i < verticalRayCount; i++) {
			Vector2 rayOrigin = (directionY == -1)?raycastOrigins.bottomLeft:raycastOrigins.topLeft;
			rayOrigin += Vector2.right * (verticalRaySpacing * i + velocity.x);
			RaycastHit2D hit = Physics2D.Raycast(rayOrigin,Vector2.up * directionY,rayLength,collisionMask);
			Debug.DrawRay(rayOrigin, Vector2.up * directionY * rayLength,Color.red);

			if (hit) {
				velocity.y = (hit.distance - skinwidth) * directionY;
				rayLength = hit.distance;
			}
		}
	}

	void UpdateRaycastOrigins(){
		Bounds bounds = coll.bounds;
		bounds.Expand(skinwidth * -2);

		raycastOrigins.bottomLeft = new Vector2(bounds.min.x,bounds.min.y);
		raycastOrigins.bottomRight = new Vector2(bounds.max.x,bounds.min.y);
		raycastOrigins.topLeft = new Vector2(bounds.min.x,bounds.max.y);
		raycastOrigins.topRight = new Vector2(bounds.max.x,bounds.max.y);

	}
	void calculateRaySpacing(){
		Bounds bounds = coll.bounds;
		bounds.Expand(skinwidth * -2);

		horizontalRayCount = Mathf.Clamp(horizontalRayCount,2,int.MaxValue);
		verticalRayCount = Mathf.Clamp(verticalRayCount,2,int.MaxValue);

		horizontalRaySpacing = bounds.size.y / (horizontalRayCount - 1);
		verticalRaySpacing = bounds.size.x / (verticalRayCount - 1);
	}


	struct RaycastOrigins {
		public Vector2 topLeft,topRight;
		public Vector2 bottomLeft,bottomRight;
	}

}


(Code Below: Player)
using UnityEngine;
using System.Collections;

[RequireComponent (typeof (Controller2D))]

public class Player : MonoBehaviour {

	float moveSpeed = 6;
	float gravity = -20;
	Vector3 velocity;

	Controller2D controller;	

	void Start(){
		controller = GetComponent<Controller2D>();
	}

	void Update(){

		Vector2 input = new Vector2(Input.GetAxisRaw("Horizontal"),Input.GetAxisRaw("Vertical"));


		velocity.x = input.x * moveSpeed;
		velocity.y += gravity * Time.deltaTime;
		controller.Move(velocity * Time.deltaTime);
	}
}

Could anyone kindly point me in the right direction and advise as to what I would need to consider when trying to make my player collect an item?

My first request on here, so hopefully I’ve done everything within the guidelines. :slight_smile:

Sorry, just to clarify, the code posted above is taken straight from the tutorial and does not include my failed attempts at making the pickups work via OnTriggerEntry2D etc. :slight_smile: