'Score updating automatically without any prior collisions
I am a newbie to C# and am currently trying to create a scoring system for Ruby's Tutorial. So I am trying to have the score update each time Ruby fixes a robot but currently the score is updating every few seconds without Ruby throwing her projectile. I have been working on this for days with no result and this is the closest I have come to having this scoring function work. Any assistance would be appreciated.
Also, I am calling the score between these two scripts as instructed for completing this score function.
Ruby's Controller Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : MonoBehaviour
{
public float speed;
public bool vertical;
public float changeTime = 3.0f;
private RubyController rubyController;
public ParticleSystem smokeEffect;
Rigidbody2D rigidbody2D;
float timer;
int direction = 1;
bool broken = true;
Animator animator;
// Start is called before the first frame update
void Start()
{
rigidbody2D = GetComponent<Rigidbody2D>();
timer = changeTime;
animator = GetComponent<Animator>();
GameObject rubyControllerObject = GameObject.FindWithTag("RubyController");
if (rubyControllerObject != null)
{
rubyController = rubyControllerObject.GetComponent<RubyController>();
print ("Found the RubyConroller Script!");
}
if (rubyController == null)
{
print ("Cannot find GameController Script!");
}
}
void Update()
{
//remember ! inverse the test, so if broken is true !broken will be false and return won’t be executed.
if(!broken)
{
return;
}
timer -= Time.deltaTime;
if (timer < 0)
{
direction = -direction;
timer = changeTime;
}
}
void FixedUpdate()
{
//remember ! inverse the test, so if broken is true !broken will be false and return won’t be executed.
if(!broken)
{
return;
}
Vector2 position = rigidbody2D.position;
if (vertical)
{
position.y = position.y + Time.deltaTime * speed * direction;
animator.SetFloat("Move X", 0);
animator.SetFloat("Move Y", direction);
}
else
{
position.x = position.x + Time.deltaTime * speed * direction;
animator.SetFloat("Move X", direction);
animator.SetFloat("Move Y", 0);
}
rigidbody2D.MovePosition(position);
}
void OnCollisionEnter2D(Collision2D other)
{
RubyController player = other.gameObject.GetComponent<RubyController>();
if (player != null)
{
player.ChangeHealth(-1);
}
GameObject rubyControllerObject = GameObject.FindWithTag("RubyController");
if (rubyController != null)
{
{
rubyController.ChangeScore(+1);
}
}
}
//Public because we want to call it from elsewhere like the projectile script
public void Fix()
{
broken = false;
rigidbody2D.simulated = false;
//optional if you added the fixed animation
animator.SetTrigger("Fixed");
smokeEffect.Stop();
}
}
Enemy Controller Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class RubyController : MonoBehaviour
{
public float speed = 3.0f;
public int maxHealth = 5;
public GameObject projectilePrefab;
public int Score;
public TextMeshProUGUI scoreText;
public AudioClip throwSound;
public AudioClip hitSound;
public int health { get { return currentHealth; }}
int currentHealth;
public float timeInvincible = 2.0f;
bool isInvincible;
float invincibleTimer;
Rigidbody2D rigidbody2d;
float horizontal;
float vertical;
public ParticleSystem HealthIncrease;
public ParticleSystem HealthDecrease;
Animator animator;
Vector2 lookDirection = new Vector2(1,0);
AudioSource audioSource;
// Start is called before the first frame update
void Start()
{
rigidbody2d = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
currentHealth = maxHealth;
audioSource = GetComponent<AudioSource>();
Score = 0;
HealthIncrease.Stop();
HealthDecrease.Stop();
}
public void ChangeScore(int scoreAmount)
{
{
Score++;
scoreText.text = "Fixed Robots: " + Score.ToString();
}
}
// Update is called once per frame
void Update()
{
horizontal = Input.GetAxis("Horizontal");
vertical = Input.GetAxis("Vertical");
Vector2 move = new Vector2(horizontal, vertical);
if(!Mathf.Approximately(move.x, 0.0f) || !Mathf.Approximately(move.y, 0.0f))
{
lookDirection.Set(move.x, move.y);
lookDirection.Normalize();
}
animator.SetFloat("Look X", lookDirection.x);
animator.SetFloat("Look Y", lookDirection.y);
animator.SetFloat("Speed", move.magnitude);
if (isInvincible)
{
invincibleTimer -= Time.deltaTime;
if (invincibleTimer < 0)
isInvincible = false;
}
if(Input.GetKeyDown(KeyCode.C))
{
Launch();
}
if (Input.GetKeyDown(KeyCode.X))
{
RaycastHit2D hit = Physics2D.Raycast(rigidbody2d.position + Vector2.up * 0.2f, lookDirection, 1.5f, LayerMask.GetMask("NPC"));
if (hit.collider != null)
{
NonPlayerCharacter character = hit.collider.GetComponent<NonPlayerCharacter>();
if (character != null)
{
character.DisplayDialog();
}
}
}
if (Input.GetKeyDown(KeyCode.Escape))
{
Application.Quit();
}
}
void FixedUpdate()
{
Vector2 position = rigidbody2d.position;
position.x = position.x + speed * horizontal * Time.deltaTime;
position.y = position.y + speed * vertical * Time.deltaTime;
rigidbody2d.MovePosition(position);
}
public void ChangeHealth(int amount)
{
if (amount < 0)
{
if (isInvincible)
return;
isInvincible = true;
invincibleTimer = timeInvincible;
GameObject projectileObject = Instantiate(HealthDecrease.gameObject, rigidbody2d.position + Vector2.up * 0.5f, Quaternion.identity);
Projectile projectile = projectileObject.GetComponent<Projectile>();
PlaySound(hitSound);
}
if (amount < 5)
{
GameObject projectileObject = Instantiate(HealthIncrease.gameObject, rigidbody2d.position + Vector2.up * 0.5f, Quaternion.identity);
}
currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
UIHealthBar.instance.SetValue(currentHealth / (float)maxHealth);
}
void Launch()
{
GameObject projectileObject = Instantiate(projectilePrefab, rigidbody2d.position + Vector2.up * 0.5f, Quaternion.identity);
Projectile projectile = projectileObject.GetComponent<Projectile>();
projectile.Launch(lookDirection, 300);
animator.SetTrigger("Launch");
PlaySound(throwSound);
}
public void PlaySound(AudioClip clip)
{
audioSource.PlayOneShot(clip);
}
}
Solution 1:[1]
Moving the section:
GameObject rubyControllerObject = GameObject.FindWithTag("RubyController");
if (rubyController != null)
{
{
rubyController.ChangeScore(+1);
}
}
Into public void Fix() will ensure it’s only executed when a robot is fixed.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Sven Viking |
