Gain points when the player kill an enemy - unity3d

I want to gain 10 points when the player kill an enemy but I don't get it. I've created a method to add score on my PuntosPistas script in the Player, and just call the method inside of the CheckHealth of the Enemy but it don't sum 10 points in score. Can anybody help me? This is my code:
In the Enemy:
public class v_AIMotor : vCharacter
{
GameObject Player;
void Start ()
{
Player = GameObject.FindGameObjectWithTag("Player");
}
public void CheckHealth()
{
if (currentHealth <= 0 && !isDead)
{
isDead = true;
Player.GetComponent<PuntosPistas>().KillEnemy ();
print("10 points”);
DisableActions();
}
}
}
In the Player:
public class PuntosPistas : MonoBehaviour
{
public int Score;
public Text TextoContador;
void Start ()
{
Score = PlayerPrefs.GetInt("Score");
TextoContador.text = "" + Score;
}
public void KillEnemy()
{
Score = Score + 10;
TextoContador.text = "" + Score;
PlayerPrefs.SetInt("Score",Score);
}
}
Sorry! This is the full code where I call CheckHealth():
#region AI Health
GameObject Player;
void Start ()
{
Player = GameObject.FindGameObjectWithTag("Player");
}
public void CheckHealth()
{
if (currentHealth <= 0 && !isDead)
{
isDead = true;
Player.GetComponent<PuntosPistas> ().KillEnemy ();
DisableActions();
}
}
public void HealthRecovery()
{
if (currentHealth <= 0) return;
if (currentHealthRecoveryDelay > 0)
{
currentHealthRecoveryDelay -= Time.deltaTime;
}
else
{
if (currentHealth > maxHealth)
currentHealth = maxHealth;
if (currentHealth < maxHealth)
currentHealth = Mathf.Lerp(currentHealth, maxHealth, healthRecovery * Time.deltaTime);
}
}
protected void RemoveComponents()
{
if (_capsuleCollider != null) Destroy(_capsuleCollider);
if (_rigidbody != null) Destroy(_rigidbody);
if (animator != null) Destroy(animator);
if (agent != null) Destroy(agent);
var comps = GetComponents<MonoBehaviour>();
foreach (Component comp in comps) Destroy(comp);
}
public override void TakeDamage(Damage damage)
{
if (rolling || currentHealth <= 0) return;
if (canSeeTarget() && !damage.ignoreDefense && !actions && CheckChanceToRoll()) return;
// change to block an attack
StartCoroutine(CheckChanceToBlock(chanceToBlockAttack, 0));
// defend attack behaviour
if (canSeeTarget() && BlockAttack(damage)) return;
// instantiate hit particle
var hitRotation = Quaternion.LookRotation(new Vector3(transform.position.x, damage.hitPosition.y, transform.position.z) - damage.hitPosition);
SendMessage("TriggerHitParticle", new HittEffectInfo(new Vector3(transform.position.x, damage.hitPosition.y, transform.position.z), hitRotation, damage.attackName), SendMessageOptions.DontRequireReceiver);
// apply damage to the health
currentHealth -= damage.value;
currentHealthRecoveryDelay = healthRecoveryDelay;
// apply tag from the character that hit you and start chase
if (!sphereSensor.passiveToDamage && damage.sender != null)
{
target = damage.sender;
currentState = AIStates.Chase;
sphereSensor.SetTagToDetect(damage.sender);
if (meleeManager != null)
meleeManager.SetTagToDetect(damage.sender);
}
// trigger hit sound
if (damage.sender != null)
damage.sender.SendMessage("PlayHitSound", SendMessageOptions.DontRequireReceiver);
// update the HUD display
if (healthSlider != null)
healthSlider.Damage(damage.value);
// trigger the HitReaction when the AI take the damage
var hitReactionConditions = stepUp || climbUp || jumpOver || quickTurn || rolling;
if (animator != null && animator.enabled && !damage.activeRagdoll && !hitReactionConditions)
{
animator.SetInteger("Recoil_ID", damage.recoil_id);
animator.SetTrigger("HitReaction");
}
// turn the ragdoll on if the weapon is checked with 'activeRagdoll'
if (damage.activeRagdoll)
transform.SendMessage("ActivateRagdoll", SendMessageOptions.DontRequireReceiver);
CheckHealth();
}
#endregion
And this is the error in console:
NullReferenceException: Object reference not set to an instance of an object
Invector.v_AIMotor.CheckHealth () (at Assets/Invector-3rdPersonController/Scripts/CharacterAI/v_AIMotor.cs:504)
Invector.v_AIMotor.TakeDamage (.Damage damage) (at Assets/Invector-3rdPersonController/Scripts/CharacterAI/v_AIMotor.cs:582)
UnityEngine.Component:SendMessage(String, Object, SendMessageOptions)
vMeleeManager:OnDamageHit(HitInfo) (at Assets/Invector-3rdPersonController/Scripts/MeleeCombat/vMeleeManager.cs:295)
UnityEngine.Component:SendMessageUpwards(String, Object, SendMessageOptions)
Invector.vHitBox:CheckHitProperties(Collider) (at Assets/Invector-3rdPersonController/Scripts/MeleeCombat/vHitBox.cs:68)
Invector.vHitBox:OnTriggerEnter(Collider) (at Assets/Invector-3rdPersonController/Scripts/MeleeCombat/vHitBox.cs:48)

please investigate on the way you call CheckHealth(), it's not clear from your code.
That code should be work if you call the method properly, try in this way:
public class v_AIMotor : vCharacter{
GameObject Player;
void Start ()
{
Player = GameObject.FindGameObjectWithTag("Player");
}
public void CheckHealth()
{
if (currentHealth <= 0 && !isDead)
{
isDead = true;
Player.GetComponent<PuntosPistas>().KillEnemy ();
print("10 points”);
DisableActions();
}
}
void Update()
{
CheckHealth();
}
}
void update is not the best way for sure, but should be do the job.

Related

I have a problem programming with unity to paste the image of footsteps on the ground when the player moves

public class FootPaint : MonoBehaviour
{
#region --- helpers --
public enum enumFoot
{
Left,
Right,
}
#endregion
public GameObject LeftPrefab;
public GameObject RightPrefab;
public float FootprintSpacer = 1.0f;
private Vector3 LastFootprint;
private enumFoot WhichFoot;
public GameObject[] intdexPos;
private void Start()
{
LastFootprint = this.transform.position;
}
private void Update()
{
FootPaints();
}
public void FootPaints()
{
if (CheckPaintItem.instance.isPaint == true && gameObject.name == "PlayerSeek")
{
float DistanceSinceLastFootprint = Vector3.Distance(transform.position, LastFootprint);
if (DistanceSinceLastFootprint >= FootprintSpacer)
{
LastFootprint = this.transform.position;
if (WhichFoot == enumFoot.Left)
{
SpawnFootDecal(LeftPrefab);
WhichFoot = enumFoot.Right;
}
else if (WhichFoot == enumFoot.Right)
{
SpawnFootDecal(RightPrefab);
WhichFoot = enumFoot.Left;
}
LastFootprint = new Vector3(this.transform.position.x, this.transform.position.y + 1f, this.transform.position.z);
}
}
}
public void SpawnFootDecal(GameObject prefab)
{
int index = Random.Range(0, intdexPos.Length);
//where the ray hits the ground we will place a footprint
GameObject decal = Instantiate(prefab);
decal.transform.position = intdexPos[index].transform.position;
decal.transform.Rotate(Vector3.forward, intdexPos[index].transform.eulerAngles.y);
//turn the footprint to match the direction the player is facing
}
}
public class CheckPaintItem : MonoBehaviour
{
public static CheckPaintItem instance;
#region boolPaint
[HideInInspector]
public bool isPaint = false;
[HideInInspector]
public bool isPaintYellow = false;
[HideInInspector]
public bool isPaintRed = false;
[HideInInspector]
public bool isPaintBlue = false;
[HideInInspector]
public bool isPaintGreen = false;
#endregion
private float currentMoveSpeed;
private void Awake()
{
instance = this;
}
private void Start()
{
currentMoveSpeed = 2.5f;
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "PaintsYellow")
{
Debug.Log("Yellow");
isPaint = true;
isPaintYellow = true;
StartCoroutine(timePaint());
}
else if (other.gameObject.tag == "PaintsRed")
{
isPaint = true;
isPaintRed = true;
StartCoroutine(timePaint());
}
else if (other.gameObject.tag == "PaintsBlue")
{
isPaint = true;
isPaintBlue = true;
StartCoroutine(timePaint());
}
else if (other.gameObject.tag == "PaintsGreen")
{
isPaint = true;
isPaintGreen = true;
StartCoroutine(timePaint());
}
else
{
isPaint = false;
isPaintYellow = false;
isPaintRed = false;
isPaintBlue = false;
isPaintGreen = false;
}
if (other.gameObject.tag == "PaintsGlue")
{
StartCoroutine(changeMoveSpeedSlow());
}
if (other.gameObject.tag == "Speed")
{
StartCoroutine(changeMoveSpeedFast());
Destroy(other.gameObject);
}
}
IEnumerator changeMoveSpeedSlow()
{
PlayerController.instance._moveSpeed = PlayerController.instance._moveSpeed / 2 + 0.2f;
yield return new WaitForSeconds(5f);
PlayerController.instance._moveSpeed = currentMoveSpeed;
}
IEnumerator changeMoveSpeedFast()
{
PlayerController.instance._moveSpeed = PlayerController.instance._moveSpeed + 1f;
yield return new WaitForSeconds(5f);
PlayerController.instance._moveSpeed = currentMoveSpeed;
}
IEnumerator timePaint()
{
yield return new WaitForSeconds(15f);
isPaint = false;
}
}
I want to code the game "hide and seek", but I had a problem when the character stepped into a puddle of paint.
My game has 1 character finding and 5 moving AIs, I want whether the AI or the player steps into the puddle, it will leave footprints. But I have problem with above scripts tag, I add script tag with all characters.
So one character walks in, all the other characters show their footsteps. I don't know if my direction is correct. If anyone wants to understand more about the game I'm coding, you can go to youtube and type hide and seek and it will come out.
Thank you.
It seems to me, that the problem lies within CheckPaintItem.instance.isPaint. I don't know what that script is exactly, but it's probably a singleton pattern as there is an instance call. If that's the case, then you're checking if any CheckPaintItem is true globally as it's fields are pretty much static. So make changes to CheckPaintItem or show us what it does exactly.

How to keep variables with DontDestroyOnLoad unity

I'm quite new to unity and programming in general and I'm using "DontDestroyOnLoad (gameObject);" in a script that manages the all sounds played in the game, I run in to a problem that things like pause and unpause stop working when I load into another scene even though DondtDestroyOnLoad is on, it gives me a NullReferenceException error so i think that when loading a new scene it empty's the variables. does anyone now a way to prevent that from happening?
using UnityEngine.Audio;
using System;
using UnityEngine;
using Random=UnityEngine.Random;
public class AudioManager : MonoBehaviour
{
public Sound[] sounds;
public static AudioManager instance;
void Awake() {
if (instance == null) {
instance = this;
}
else {
Destroy(gameObject);
return;
}
DontDestroyOnLoad (gameObject);
foreach (Sound s in sounds) {
s.source = gameObject.AddComponent<AudioSource>();
s.source.clip = s.clip;
s.source.volume = s.volume;
if (s.randompitch == false) {
s.source.pitch = s.pitch;
}
s.source.loop = s.loop;
if (s.playonstart == true) {
Play(s.name);
}
}
}
public void Play (string name) {
Sound s = Array.Find(sounds, sound => sound.name == name);
if (s == null){
Debug.LogWarning("there is no" + name);
return;
}
if (s.randompitch == true ) {
s.source.pitch = Random.Range(s.randompitchmin, s.randompitchmax);
}
s.source.Play();
}
public void SoundPause (string name) {
Sound s = Array.Find(sounds, sound => sound.name == name);
if (s == null){
Debug.LogWarning("there is no" + name);
return;
}
s.source.Pause();
}
public void SoundUnPause (string name) {
Sound s = Array.Find(sounds, sound => sound.name == name);
if (s == null){
Debug.LogWarning("there is no" + name);
return;
}
s.source.UnPause();
}
}
You can add DontDestroyOnLoad to its array
like this
for(int i = 0; i < sounds.Length;)
{
DontDestroyOnLoad(sounds[i]);
i++;
}
Or you can search for sounds in Scane
by using :
GameObject.Find
GameObject.FindGameObjectsWithTag
Object.FindObjectOfType
EDIT
for(int i = 0; i < sounds.Length;)
{
DontDestroyOnLoad(sounds[i].GetComponent<GameObject>());
i++;
}

Sync Text objects in Unity

I have a prefab that has a text object on it and that text represents a counter for the prefab lifespan that increases every second. The script works fine on the human vs computer mode, but when I try to make a host client the numbers are always different on the clients side. How can I let the numbers displayed on them sync together?
public class Timer : MonoBehaviour
{
public Planet pl;
private bool hasDone = false;
public int timeleft =6;
public Text countdownText;
// Use this for initialization
void Start()
{
timeleft = Random.Range (0, 31);
}
// Update is called once per frame
void Update()
{
countdownText.text = ("" + timeleft);
if (pl.get_owner () != null && hasDone == false) {
StartCoroutine("LoseTime");
hasDone = true;
}
if (pl.get_owner () == "Human") {
countdownText.color = new Color (0f, 0.5f, 1f, 1f);
}
if (pl.get_owner () == "Computer") {
countdownText.color = new Color (1f, 0.5f, 0f, 1f);
}
if (pl.get_collision () > 0) {
timeleft -= 1;
pl.decrease_collision ();
}
}
IEnumerator LoseTime()
{
if (pl.get_owner () != null) {
while (true)
{
yield return new WaitForSeconds(1);
timeleft++;
}
}
}
}
I think you are looking for the syncvar attribute: https://docs.unity3d.com/ScriptReference/Networking.SyncVarAttribute.html
[SyncVar]
public int timeleft =6;
Additionally only the server should change the value. Add the following code to all locations where you would alter timeleft.
if (!isServer)
return;

Unity 5 Inventory system not working

Hello programmers all around the world. I have made myself an inventory system for my game. Only problem is that when I click on item and then drag it to and empty slot it doesn't move and I kinda don't see the error which I am having and I have tried to debug it but without success any help? Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class Inventory : MonoBehaviour {
private RectTransform inventoryRect;
private float inventoryWidth;
private float inventoryHeight;
public int slots;
public int rows;
public float slotPaddingLeft;
public float slotPaddingTop;
public float slotSize;
public GameObject slotPrefab;
private static Slot from;
private static Slot to;
private List<GameObject> allslots;
public GameObject iconPrefab;
private static GameObject hoverObject;
private static int emptySlots;
public Canvas canvas;
private float hoverYOffset;
private bool isPressed;
public EventSystem eventSystem;
public static int EmptySlots{
get{ return emptySlots;}
set{ emptySlots = value;}
}
// Use this for initialization
void Start () {
CreateLayout ();
canvas.enabled = false;
isPressed = false;
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown (KeyCode.I)) {
if (Input.GetKeyDown (KeyCode.I)) {
canvas.enabled = false;
}
canvas.enabled = true;
}
if (Input.GetMouseButtonUp (0)) {
if (!eventSystem.IsPointerOverGameObject (-1) && from != null) {
from.GetComponent<Image> ().color = Color.white;
from.ClearSlot ();
Destroy (GameObject.Find ("Hover"));
to = null;
from = null;
hoverObject = null;
}
}
if (hoverObject != null) {
Vector2 position;
RectTransformUtility.ScreenPointToLocalPointInRectangle (canvas.transform as RectTransform, Input.mousePosition, canvas.worldCamera, out position);
position.Set (position.x, position.y - hoverYOffset);
hoverObject.transform.position = canvas.transform.TransformPoint (position);
}
}
private void CreateLayout(){
allslots = new List<GameObject> ();
hoverYOffset = slotSize * 0.01f;
emptySlots = slots;
inventoryWidth = (slots / rows) * (slotSize + slotPaddingLeft) + slotPaddingLeft;
inventoryHeight = rows * (slotSize + slotPaddingTop) + slotPaddingTop;
inventoryRect = GetComponent<RectTransform> ();
inventoryRect.SetSizeWithCurrentAnchors (RectTransform.Axis.Horizontal, inventoryWidth);
inventoryRect.SetSizeWithCurrentAnchors (RectTransform.Axis.Vertical, inventoryHeight);
int colums = slots / rows;
for (int y = 0; y < rows; y++) {
for (int x = 0; x < colums; x++) {
GameObject newSlot = (GameObject)Instantiate (slotPrefab);
RectTransform slotRect = newSlot.GetComponent<RectTransform> ();
newSlot.name = "Slot";
newSlot.transform.SetParent (this.transform.parent);
slotRect.localPosition = inventoryRect.localPosition + new Vector3 (slotPaddingLeft * (x + 1) + (slotSize * x), -slotPaddingTop * (y + 1) - (slotSize * y));
slotRect.SetSizeWithCurrentAnchors (RectTransform.Axis.Horizontal, slotSize);
slotRect.SetSizeWithCurrentAnchors (RectTransform.Axis.Vertical, slotSize);
allslots.Add (newSlot);
}
}
}
public bool AddItem(Item item){
if (item.maxSize == 1) {
PlaceEmpty (item);
return true;
}
else {
foreach (GameObject slot in allslots) {
Slot temporary = slot.GetComponent<Slot> ();
if (!temporary.IsEmpty) {
if (temporary.CurrentItem.type == item.type && temporary.IsAvailable) {
temporary.AddItem (item);
return true;
}
}
}
if (emptySlots > 0) {
PlaceEmpty (item);
}
}
return false;
}
private bool PlaceEmpty(Item item){
if (emptySlots > 0) {
foreach (GameObject slot in allslots) {
Slot temporary = slot.GetComponent<Slot> ();
if (temporary.IsEmpty) {
temporary.AddItem (item);
emptySlots--;
return true;
}
}
}
return false;
}
public void MoveItem(GameObject clicked){
if (from == null) {
if (!clicked.GetComponent<Slot> ().IsEmpty) {
from = clicked.GetComponent<Slot> ();
from.GetComponent<Image> ().color = Color.gray;
hoverObject = (GameObject)Instantiate (iconPrefab);
hoverObject.GetComponent<Image> ().sprite = clicked.GetComponent<Image> ().sprite;
hoverObject.name = "Hover";
RectTransform hoverTransform = hoverObject.GetComponent<RectTransform> ();
RectTransform clickedTransform = clicked.GetComponent<RectTransform> ();
hoverTransform.SetSizeWithCurrentAnchors (RectTransform.Axis.Horizontal, clickedTransform.sizeDelta.x);
hoverTransform.SetSizeWithCurrentAnchors (RectTransform.Axis.Vertical, clickedTransform.sizeDelta.y);
hoverObject.transform.SetParent (GameObject.Find ("Canvas").transform, true);
hoverObject.transform.localScale = from.gameObject.transform.localScale;
}
}
else if (to = null) {
to = clicked.GetComponent<Slot> ();
Destroy (GameObject.Find ("Hover"));
}
if (to != null && from != null) {
Stack<Item> tmpTo = new Stack<Item> (to.Items);
to.AddItems (from.Items);
if (tmpTo.Count == 0) {
from.ClearSlot ();
}
else {
from.AddItems (tmpTo);
}
from.GetComponent<Image> ().color = Color.white;
to = null;
from = null;
hoverObject = null;
}
}
}
The method which is causing the problem is the MoveItem() sadly it is not a nullreference or nullpointer and I simply am out of ideas been strugling with it for a couple of days... Any advice on how to fix this would be helpfull and much welcomed indeed. Thanks in advance!
I haven't taken a long look at your code but right away I saw this issue:
else if (to = null) {
to = clicked.GetComponent<Slot> ();
Destroy (GameObject.Find ("Hover"));
}
This is causing the end location to be set to null. To fix this, change to double equals like so:
else if (to == null) {
to = clicked.GetComponent<Slot> ();
Destroy (GameObject.Find ("Hover"));
}
If this does not solve your problem, let me know and I'll look at your code harder.

In unity tag is not found in first drag

I am making a simple drag and drop unity game. When I drag the object for the first time it does not give score but when I drag it once again it gives score even if I am dropping at the wrong place. I am using tag to match desired objects
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System;
public class sh_score : MonoBehaviour {
static int score = 0;
public Text scoreText;
public GameObject ans_circle;
public GameObject tag_circle;
public GameObject tag_rectangle;
public GameObject ans_rectangle;
public GameObject ans_triangle;
public GameObject tag_triangle;
public GameObject ans_square;
public GameObject tag_square;
public GameObject ans_star;
public GameObject tag_star;
void Start()
{
score = score;
if( (ans_circle == null || tag_circle == null) || (ans_rectangle == null || tag_rectangle == null)|| (ans_square == null || tag_square == null) || (ans_triangle == null || tag_triangle == null)|| (ans_star == null || tag_star == null))
{
ans_circle = GameObject.FindGameObjectWithTag("ans_circle");
if (ans_circle != null)
{ Debug.Log("ans Find"); }
tag_circle = GameObject.FindGameObjectWithTag("circle");
if (tag_circle != null)
{
Debug.Log("circle");
}
checkTagPlace();
ans_rectangle = GameObject.FindGameObjectWithTag("ans_rectangle");
if (ans_rectangle != null)
{ Debug.Log("ans Find"); }
tag_rectangle = GameObject.FindGameObjectWithTag("rectangle");
if (tag_circle != null)
{
Debug.Log("rectangle");
}
ans_triangle = GameObject.FindGameObjectWithTag("ans_triangle");
if (ans_triangle != null)
{ Debug.Log("ans Find"); }
tag_triangle = GameObject.FindGameObjectWithTag("triangle");
if (tag_triangle != null)
{
Debug.Log("triangle");
}
ans_star = GameObject.FindGameObjectWithTag("ans_star");
if (ans_star != null)
{ Debug.Log("ans Find"); }
tag_star = GameObject.FindGameObjectWithTag("star");
if (tag_star != null)
{
Debug.Log("star");
}
ans_square = GameObject.FindGameObjectWithTag("ans_square");
if (ans_square != null)
{ Debug.Log("ans Find"); }
tag_square = GameObject.FindGameObjectWithTag("square");
if (tag_square != null)
{
Debug.Log("square");
}
}
}
void update()
{
scoreText.text = score.ToString();
}
public void IncrementScore()
{
score = score + 9;
score++;
scoreText.text = "Score: " + score;
}
public void checkTagPlace()
{
Debug.Log("check function run");
float circle_postion = tag_circle.transform.position.x;
float circle_Tag_positon = ans_circle.transform.position.x;
float triangle_position = tag_triangle.transform.position.x;
float triangle_Tag_positon = ans_triangle.transform.position.x;
float square_postion = tag_square.transform.position.x;
float square_Tag_positon = ans_square.transform.position.x;
float star_postion = tag_star.transform.position.x;
float star_Tag_positon = ans_star.transform.position.x;
float rectangle_position = tag_rectangle.transform.position.x;
float rectangle_Tag_positon = ans_rectangle.transform.position.x;
if ((ans_circle.transform.position.x == tag_circle.transform.position.x))
{
Debug.Log("found position");
IncrementScore();
}
else if ((ans_rectangle.transform.position.x == tag_rectangle.transform.position.x))
{
IncrementScore();
}
else if ((ans_square.transform.position.x == tag_square.transform.position.x))
{
IncrementScore();
}
else if (ans_triangle.transform.position.x == tag_triangle.transform.position.x)
{
IncrementScore();
}
else if (ans_star.transform.position.x == tag_star.transform.position.x)
{
IncrementScore();
}
}
}
I cannot post comments yet but
You are calling checkTagPlace before having set all of your attributes it may be the cause of the bug.
Searching gameObjects with tags this way may be a problem in the future if you have several objects with the same tag
Usually to do what you want to do you want to use Colliders on your GameObject and the OnCollisionEnter/OnCollisionStay/OnTriggerEnter/OnTriggerStay functions (do not forget the upper case). Then you will be able to check if the "collisioned" GameObject have the correct tag.
I believe your problem might be here:
if(ans_rectangle.transform.position.x == tag_rectangle.transform.position.x)
When you check to see if these positions (and the other if statements like this one) are equal, you are checking if they're exactly equal. Unless you have some controller which is discretizing the movements of your shapes, thats almost never going to happen.
I believe what you want is really something like this:
float epsilon=.001;
if(Math.abs(ans_rectangle.transform.position.x - tag_rectangle.transform.position.x)<epsilon)
Alternatively, you can give colliders to all of your shapes and actually check for collisions between the two shape types, perhaps using layer masks to keep from comparing shapes of dissimilar types.
I understand that this doesn't explain all the behavior you're seeing, but it might explain why it doesn't increment your score the first time.
Since you don't include the code which is enabling the dragging, we can't know if that is the problem or not.