While trying to create a game in Unity about you building a small city I stumbled upon a problem. I'm using NavMesh to have the player lead around tiny people (called mixxes here). The NavMesh is working, just I'm trying to make the mixxes produce different materials based on the location you lead them to.
Here is my code so far:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class MixxScript : MonoBehaviour
{
public float speed = 5f;
public Transform target = null;
public Transform oldTarget = null;
public Transform lastPossibleSuccess;
public float range = 8.4f;
public NavMeshAgent agent;
private float countdown = 3;
void Update()
{
if (target == null)
{
return;
}
agent.SetDestination(target.position);
float distance = Vector3.Distance(transform.position, target.position);
Debug.Log(distance);
if (distance <= 2)
{
countdown -= Time.deltaTime;
if (countdown <= 0)
{
if (target.transform.name == "Factory")
{
MainScript.metal += 1;
}
if (target.transform.name == "Farm")
{
MainScript.food += 1;
}
countdown = 3;
}
}
else
{
countdown = 3;
}
}
void OnMouseDown()
{
MainScript.selectedMixx = gameObject;
}
}
And here is MainScript:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MainScript: MonoBehaviour
{
public static GameObject selectedMixx = null;
public static GameObject selectedPlatform = null;
public static float metal = 0;
public static float wood = 0;
public static float money = 0;
public static float mixxes = 1;
public static float food = 50;
public Text scoreText;
void Update()
{
scoreText.text = "Money: $" + money.ToString() + "\nFood: " + food.ToString() + "\nMetal: " + metal.ToString() + "\nWood: " + wood.ToString() + "\nMixxes: " + mixxes.ToString();
}
}
The problem is that 1) The text as shown in MainScript is not updating. 2) The Debug.Log() statement is not working so I cannot see what is wrong here.
What I've tried:
Multiple ways to measure distance
Different distance restraints (such as the one on line 28 of the first script)
Using FixedUpdate() instead of Update() (which failed completely)
Is there a solution to this?
Related
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RotateCamera : MonoBehaviour
{
public GameObject objectToSpin;
public float spinX;
public float spinY;
public float spinZ;
public bool randomSpin = false;
private void Start()
{
var rb = GetComponent<Rigidbody>();
rb.angularVelocity = Random.insideUnitSphere;
}
private void Update()
{
if (randomSpin == true)
{
objectToSpin.transform.Rotate(Random.Range(spinX, 360), Random.Range(spinY, 360), Random.Range(spinZ, 360));
}
else
{
objectToSpin.transform.Rotate(spinX, spinY, spinZ);
}
}
}
Now when changing the randomSpin flag to true it will spin random nonstop changing random angle on x y z each frame.
But I want it to spin random for 5 seconds after 5 seconds to change to random values the x y z and continue from last point and then after 5 seconds random angles and so on.
If you want a constant speed and just a random direction, You can randomly select an Axis to rotate around using Random.onUnitSphere and then rotate around it at a speed.
Here's a solution that uses a Coroutine. If you want to stop the Coroutine, you can use StopCoroutine("Spin") to stop the coroutine and start it up later with StartCoroutine("Spin"):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RotateCamera : MonoBehaviour
{
public GameObject objectToSpin;
public Vector3 spinAxis;
public float timeToSpin = 5f;
public float spinSpeed = 20f;
public bool randomSpin = false;
private void Start()
{
var rb = GetComponent<Rigidbody>();
rb.angularVelocity = Random.insideUnitSphere;
StartCoroutine("Spin");
}
private void Update()
{
}
}
IEnumerator Spin()
{
float spinTimer;
while (true)
{
if (randomSpin == true)
{
spinAxis = Random.onUnitSphere;
}
spinTimer = timeToSpin;
while (spinTimer > 0f)
{
objectToSpin.transform.Rotate(spinAxis, Time.deltaTime * spinSpeed);
spinTimer -= Time.deltaTime;
yield return null;
}
}
}
For example have a simple timer using Time.deltaTime like e.g.
private float timer = 5;
private void Update()
{
if (randomSpin == true)
{
timer -= Time.deltaTime;
if(timer <= 0)
{
objectToSpin.transform.Rotate(Random.Range(spinX, 360), Random.Range(spinY, 360), Random.Range(spinZ, 360));
timer = 5;
}
}
else
{
objectToSpin.transform.Rotate(spinX, spinY, spinZ);
}
}
I'm making 2D Game like Pac-Man. Nevertheless, I have some issues to create a scoring system.
I want to update score whenever my Pacman eat coin(a.k.a pacdot)
I made C# script called 'ScoreManager'
Here is code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScoreManager : MonoBehaviour {
static int score = 0;
public static void setScore(int value)
{
score += value;
}
public static int getScore()
{
return score;
}
void OnGUI ()
{
GUILayout.Label("Score: " + score.ToString());
}
}
This code is working well when I play my game in Unity engine
But, I don't know how to set up ScoreValue in Pacdot scripts.
Here is Pacdot Code
using UnityEngine;
using System.Collections;
public class Pacdot : MonoBehaviour {
public int score = 10;
void OnTriggerEnter2D(Collider2D co) {
if (co.name == "pacman")
{
Destroy(gameObject);
}
}
}
Also, I added C# Script ( Pacmanbehaviour )
using UnityEngine;
using System.Collections;
public class PacmanMove : MonoBehaviour {
public float speed = 0.4f;
Vector2 dest = Vector2.zero;
void Start() {
dest = transform.position;
}
void FixedUpdate() {
// Move closer to Destination
Vector2 p = Vector2.MoveTowards(transform.position, dest, speed);
GetComponent<Rigidbody2D>().MovePosition(p);
// Check for Input if not moving
if ((Vector2)transform.position == dest) {
if (Input.GetKey(KeyCode.UpArrow) && valid(Vector2.up))
dest = (Vector2)transform.position + Vector2.up;
if (Input.GetKey(KeyCode.RightArrow) && valid(Vector2.right))
dest = (Vector2)transform.position + Vector2.right;
if (Input.GetKey(KeyCode.DownArrow) && valid(-Vector2.up))
dest = (Vector2)transform.position - Vector2.up;
if (Input.GetKey(KeyCode.LeftArrow) && valid(-Vector2.right))
dest = (Vector2)transform.position - Vector2.right;
}
// Animation Parameters
Vector2 dir = dest - (Vector2)transform.position;
GetComponent<Animator>().SetFloat("DirX", dir.x);
GetComponent<Animator>().SetFloat("DirY", dir.y);
}
bool valid(Vector2 dir) {
// Cast Line from 'next to Pac-Man' to 'Pac-Man'
Vector2 pos = transform.position;
RaycastHit2D hit = Physics2D.Linecast(pos + dir, pos);
return (hit.collider == GetComponent<Collider2D>());
}
}
ScoreManager script needs to live as a game object, or as a component in a game object. Then you can add it as a field in your Pacdot class.
It'll be something like this below, but finding the specific game object the script is attached to will depend on how you have it designed (the "find by tag" approach won't work unless you have a game object with ScoreManager attached, with that tag).
using UnityEngine;
using System.Collections;
public class Pacdot : MonoBehaviour {
public int score = 10;
private ScoreManager _score = GameObject.findGameObjectWithTag("scoreKeeper").GetComponent<ScoreManager>();
void OnTriggerEnter2D(Collider2D co) {
if (co.name == "pacman")
{
_score.SetScore(score);
Destroy(gameObject);
}
}
}
I would also look at the answer #derHugo linked to--a lot of ways to accomplish this, depending on your needs/design.
I am making a game like 2 cars. And I have written code to create a instantiater. It is a car game and there are 4 lanes. Let me show you a picture of my game and yeah this is solely for practise.
Player should avoid square objects and eat circle objects but sometimes 2 square objects get spawned in a same lane making impossible for player to win. I have written this script to control that but I failed. Please help me. At least have a check to my DetectSameLaneFunction(). And tell me what I am doing wrong.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spawner : MonoBehaviour {
public GameObject[] objects;
public float delaytime = 2f; // this is separate for each prefab with which script is attaches
public float spawnrate = 1f; // this is separate for each prefab with which script is attaches
public static int lastgameobjectindex;
public static GameObject lastgameobject;
public static GameObject SecondLastGameObject;
private float loadingtime;
private GameObject go; // just a temporary variable
public static List<GameObject> spawnobjects = new List<GameObject>();
// Use this for initialization
void Start () {
loadingtime = delaytime;
}
// Update is called once per frame
void Update () {
if (Time.time > loadingtime)
{
float randomness = spawnrate * Time.deltaTime;
if ( randomness < Random.value)
{
Spawners();
}
NextLoadTime();
}
}
private void Spawners()
{
int spawnnumber = Random.Range(0, 2);
GameObject go = Instantiate(objects[spawnnumber]) as GameObject;
go.transform.position = this.transform.position;
spawnobjects.Add(go);
Debug.Log(spawnobjects[spawnobjects.Count-1]);
DetectSameLaneObjects();
/* if (spawnobjects.Count > 4)
{
spawnobjects.RemoveAt(0);
}*/
}
private void DetectSameLaneObjects()
{
if (spawnobjects.Count > 3)
{
lastgameobject = spawnobjects[spawnobjects.Count - 1];
SecondLastGameObject = spawnobjects[spawnobjects.Count - 2];
lastgameobjectindex = spawnobjects.Count - 1;
if (SecondLastGameObject.transform.position.x != lastgameobject.transform.position.x
)
{
if (Mathf.Abs(lastgameobject.transform.position.x- SecondLastGameObject.transform.position.x) < 2.3f)
{
Debug.Log("Destroy function getting called");
Destroy(spawnobjects[lastgameobjectindex]);
spawnobjects.RemoveAt(lastgameobjectindex);
}
}
}
}
void OnDrawGizmos()
{
Gizmos.DrawWireSphere(this.transform.position, 0.6f);
}
void NextLoadTime()
{
loadingtime = Time.time + delaytime;
}
}
I'm managing my HighScore in my scene "Standard Game" by using playerprefs
I need to access my variable HighScore in my other script "SaveTest" which is in a different scene called "Main Menu" So i can destroy objects tagged DestroyUI when a highscore is reached.
Ive been googling for a bit but im not sure what im doing wrong.
Save Test
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SaveTest : MonoBehaviour
{
public ButtonReposition buttonrepositionscript;
void Start()
{
DontDestroyOnLoad(gameObject);
GameObject obj = GameObject.Find("ButtonReposition");
}
// Update is called once per frame
void Update()
{
if (GetComponent<ButtonReposition.highscore <= 100)
Destroy(GameObject.FindWithTag("DestroyUI"));
}
}
HighScore script
public class ButtonReposition : MonoBehaviour
{
public Button prefab;
public GameObject loseObject;
public int count;
public int highscore;
public Text countText;
public Text Highscoretext;
public Image lineimagestandard;
// Use this for initialization
void Start()
{
PlayerPrefs.GetInt("scorePref");
highscore = PlayerPrefs.GetInt("scorePref");
SetHighscoretext();
SetCountText();
float x = Random.Range(325f, -600f);
float y = Random.Range(250f, -450f);
Debug.Log(x + "," + y);
prefab.GetComponent<RectTransform>().anchoredPosition = new Vector2(x, y);
}
void Update()
{
if (Highscoretext.name == "highscoretext")
{
Highscoretext.text = "highscore" + highscore;
}
PlayerPrefs.SetInt("scorePref", highscore);
}
put this on your Save Test script highscore = PlayerPrefs.GetInt("scorePref");
and that's it.
Im doing an Healthbar script in unity. It works. But the mana bar script doesnt. I also have one script with static variables for health and mana system.
I have 2 images that i want to fill when health/mana incrases.Health bar works. But mana bar doesnt. There arent any compile errors. Just the script doesnt work.
Here is the health system script:
using UnityEngine;
using System.Collections;
public class HealthMana : MonoBehaviour {
public static float CurrentHealth;
public float MaximumHealth;
public float RegenSpeed;
public bool CanRegen;
public static float CurrentMana;
public float MaximumMana;
public float RegenManaSpeed;
public bool CanRegenMana;
public void Awake () {
CurrentHealth = 100.0f;
MaximumHealth = 100.0f;
RegenSpeed = 1.0f;
CanRegen = true;
CurrentMana = 10.0f;
MaximumMana = 100.0f;
RegenManaSpeed = 1.0f;
CanRegenMana = true;
}
void Start () {
}
void Update () {
if (CanRegen == true && CurrentHealth <= MaximumHealth){
CurrentHealth = CurrentHealth + RegenSpeed * Time.deltaTime;
}
if (CanRegenMana == true && CurrentMana <= MaximumMana) {
CurrentMana = CurrentMana + RegenManaSpeed * Time.deltaTime;
}
}
}
And the code for ManaUI (Image 2)
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class ManaUI : MonoBehaviour {
void Update () {
Image image = GetComponent<Image>("Image1");
float fillamount = HealthMana.CurrentMana / 100;
image.fillAmount = fillamount;
}
}
The healthUI code is the same, but it says CurrentHealth instead of CurrentMana